@paris-ias/list 1.0.185 → 1.0.187
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/dist/module.json +1 -1
- package/dist/runtime/components/events/DenseItem.vue +27 -16
- package/dist/runtime/components/events/RowsItem.vue +16 -5
- package/dist/runtime/components/events/SlidingItem.vue +1 -1
- package/dist/runtime/components/fellowships/DenseItem.vue +15 -7
- package/dist/runtime/components/fellowships/RowsItem.vue +18 -4
- package/dist/runtime/components/fellowships/View.vue +4 -2
- package/dist/runtime/components/list/molecules/GlobalSearchInput.vue +33 -8
- package/dist/runtime/components/list/molecules/ResultsContainer.vue +2 -3
- package/dist/runtime/components/list/organisms/Results.vue +373 -26
- package/dist/runtime/components/misc/atoms/ImageContainer.vue +4 -1
- package/dist/runtime/components/news/DenseItem.vue +19 -8
- package/dist/runtime/components/news/RowsItem.vue +21 -6
- package/dist/runtime/components/people/Badges.vue +1 -1
- package/dist/runtime/components/people/DenseItem.vue +34 -11
- package/dist/runtime/components/people/RowsItem.vue +19 -6
- package/dist/runtime/components/projects/DenseItem.vue +20 -8
- package/dist/runtime/components/projects/RowsItem.vue +32 -6
- package/dist/runtime/components/projects/View.vue +1 -1
- package/dist/runtime/components/publications/DenseItem.vue +18 -11
- package/dist/runtime/components/publications/RowsItem.vue +18 -4
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -6,19 +6,24 @@
|
|
|
6
6
|
:loading
|
|
7
7
|
:date-start="item.start"
|
|
8
8
|
:date-stop="item.stop"
|
|
9
|
-
class="pr-4
|
|
9
|
+
class="pr-4"
|
|
10
10
|
/>
|
|
11
11
|
</v-col>
|
|
12
|
-
<v-col v-if="mdAndUp" cols="
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
<v-col v-if="mdAndUp" cols="auto">
|
|
13
|
+
<div style="width: 80px; height: 80px; flex-shrink: 0">
|
|
14
|
+
<MiscAtomsImageContainer
|
|
15
|
+
cover
|
|
16
|
+
:loading
|
|
17
|
+
:src="
|
|
18
|
+
item && item.image && item.image.url
|
|
19
|
+
? item.image.url
|
|
20
|
+
: '/default.png'
|
|
21
|
+
"
|
|
22
|
+
:ratio="1 / 1"
|
|
23
|
+
:width="80"
|
|
24
|
+
style="width: 80px; height: 80px"
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
22
27
|
</v-col>
|
|
23
28
|
|
|
24
29
|
<v-col align-self="start" class="px-2">
|
|
@@ -61,8 +66,8 @@
|
|
|
61
66
|
v-else
|
|
62
67
|
class="text-h5 dense paragraph mt-2"
|
|
63
68
|
v-html="
|
|
64
|
-
|
|
65
|
-
? highlightAndTruncate(300, item.name,
|
|
69
|
+
searchQuery.length
|
|
70
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
66
71
|
: item.name
|
|
67
72
|
"
|
|
68
73
|
/>
|
|
@@ -73,7 +78,7 @@
|
|
|
73
78
|
:value="`${highlightAndTruncate(
|
|
74
79
|
85,
|
|
75
80
|
item.summary,
|
|
76
|
-
|
|
81
|
+
searchQuery.split(' '),
|
|
77
82
|
)}`"
|
|
78
83
|
/>
|
|
79
84
|
</v-col>
|
|
@@ -88,15 +93,21 @@
|
|
|
88
93
|
</template>
|
|
89
94
|
|
|
90
95
|
<script setup>
|
|
91
|
-
import { useI18n, useNuxtApp, computed } from "#imports"
|
|
96
|
+
import { useI18n, useNuxtApp, useRoute, computed } from "#imports"
|
|
92
97
|
import { useDisplay } from "vuetify"
|
|
93
98
|
import { useRootStore } from "../../stores/root"
|
|
94
99
|
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
95
|
-
const { $rootStore } = useNuxtApp()
|
|
100
|
+
const { $rootStore, $stores } = useNuxtApp()
|
|
96
101
|
const { smAndDown, mdAndUp } = useDisplay()
|
|
97
102
|
|
|
98
103
|
const { locale } = useI18n()
|
|
99
104
|
const rootStore = useRootStore()
|
|
105
|
+
const { name: routeName } = useRoute()
|
|
106
|
+
const searchQuery = computed(() =>
|
|
107
|
+
routeName.startsWith("search")
|
|
108
|
+
? $rootStore.search
|
|
109
|
+
: $stores["events"].search || "",
|
|
110
|
+
)
|
|
100
111
|
const props = defineProps({
|
|
101
112
|
item: {
|
|
102
113
|
type: Object,
|
|
@@ -29,9 +29,15 @@
|
|
|
29
29
|
/>
|
|
30
30
|
|
|
31
31
|
<div v-else>
|
|
32
|
-
<div
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
<div
|
|
33
|
+
v-if="item.name"
|
|
34
|
+
class="text-h4 text-black text-wrap mt-4"
|
|
35
|
+
v-html="
|
|
36
|
+
searchQuery.length
|
|
37
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
38
|
+
: item.name
|
|
39
|
+
"
|
|
40
|
+
/>
|
|
35
41
|
<div class="mt-2 text-h6 text-overline font-weight-black">
|
|
36
42
|
{{ $t("list.filters.events.category." + item.category) }}
|
|
37
43
|
</div>
|
|
@@ -45,7 +51,7 @@
|
|
|
45
51
|
]
|
|
46
52
|
"
|
|
47
53
|
>
|
|
48
|
-
<MDC v-if="item.summary" :value="item.summary" />
|
|
54
|
+
<MDC v-if="item.summary" :value="searchQuery.length ? highlightAndTruncate(500, item.summary, searchQuery.split(' ')) : item.summary" />
|
|
49
55
|
</p>
|
|
50
56
|
|
|
51
57
|
<div v-if="lgAndUp" class="d-flex flex-row align-center flex-wrap">
|
|
@@ -85,12 +91,17 @@
|
|
|
85
91
|
<script setup>
|
|
86
92
|
import { useDisplay } from "vuetify"
|
|
87
93
|
import { useRootStore } from "../../stores/root"
|
|
88
|
-
import { useNuxtApp, computed } from "#imports"
|
|
94
|
+
import { useNuxtApp, useRoute, computed } from "#imports"
|
|
95
|
+
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
89
96
|
|
|
90
97
|
const { name, mdAndDown, lgAndUp } = useDisplay()
|
|
91
98
|
|
|
92
99
|
const rootStore = useRootStore()
|
|
93
100
|
const { $stores } = useNuxtApp()
|
|
101
|
+
const { name: routeName } = useRoute()
|
|
102
|
+
const searchQuery = computed(() =>
|
|
103
|
+
routeName.startsWith('search') ? rootStore.search : ($stores['events'].search || '')
|
|
104
|
+
)
|
|
94
105
|
const props = defineProps({
|
|
95
106
|
item: {
|
|
96
107
|
type: Object,
|
|
@@ -4,7 +4,12 @@
|
|
|
4
4
|
no-gutters
|
|
5
5
|
class="cursor-pointer highlight-on-hover pt-2 pl-2"
|
|
6
6
|
>
|
|
7
|
-
<v-col
|
|
7
|
+
<v-col
|
|
8
|
+
align-self="center"
|
|
9
|
+
cols="8"
|
|
10
|
+
class="text-h5 dense"
|
|
11
|
+
:offset="name.startsWith('search') ? 1 : 0"
|
|
12
|
+
>
|
|
8
13
|
<v-skeleton-loader
|
|
9
14
|
v-if="loading"
|
|
10
15
|
type="heading"
|
|
@@ -14,14 +19,14 @@
|
|
|
14
19
|
<div
|
|
15
20
|
v-else
|
|
16
21
|
v-html="
|
|
17
|
-
|
|
18
|
-
? highlightAndTruncate(300, item.name,
|
|
22
|
+
searchQuery.length
|
|
23
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
19
24
|
: item.name
|
|
20
25
|
"
|
|
21
26
|
/>
|
|
22
27
|
<FellowshipsBadges :item="item" :loading="loading" />
|
|
23
28
|
</v-col>
|
|
24
|
-
<v-col align-self="center" cols="
|
|
29
|
+
<v-col align-self="center" cols="auto">
|
|
25
30
|
<v-skeleton-loader v-if="loading" type="chip" width="260" class="mt-2" />
|
|
26
31
|
<MiscMoleculesChipContainer
|
|
27
32
|
v-else
|
|
@@ -38,10 +43,13 @@
|
|
|
38
43
|
</template>
|
|
39
44
|
|
|
40
45
|
<script setup>
|
|
41
|
-
import { useNuxtApp } from "#imports"
|
|
46
|
+
import { useNuxtApp, useRoute, computed } from "#imports"
|
|
42
47
|
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
43
|
-
const { $rootStore } = useNuxtApp()
|
|
44
|
-
|
|
48
|
+
const { $rootStore, $stores } = useNuxtApp()
|
|
49
|
+
const { name } = useRoute()
|
|
50
|
+
const searchQuery = computed(() =>
|
|
51
|
+
name.startsWith('search') ? $rootStore.search : ($stores['fellowships'].search || '')
|
|
52
|
+
)
|
|
45
53
|
const props = defineProps({
|
|
46
54
|
item: {
|
|
47
55
|
type: Object,
|
|
@@ -13,9 +13,14 @@
|
|
|
13
13
|
<template v-else>
|
|
14
14
|
<FellowshipsBadges :item :loading="loading" />
|
|
15
15
|
|
|
16
|
-
<div
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
<div
|
|
17
|
+
class="text-h4 text-black text-wrap mt-4 pb-4"
|
|
18
|
+
v-html="
|
|
19
|
+
searchQuery.length
|
|
20
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
21
|
+
: item.name
|
|
22
|
+
"
|
|
23
|
+
/>
|
|
19
24
|
|
|
20
25
|
<div
|
|
21
26
|
v-if="item.summary"
|
|
@@ -27,7 +32,7 @@
|
|
|
27
32
|
]
|
|
28
33
|
"
|
|
29
34
|
>
|
|
30
|
-
<MDC :value="item.summary" />
|
|
35
|
+
<MDC :value="searchQuery.length ? highlightAndTruncate(500, item.summary, searchQuery.split(' ')) : item.summary" />
|
|
31
36
|
</div>
|
|
32
37
|
|
|
33
38
|
<MiscMoleculesChipContainer
|
|
@@ -50,8 +55,17 @@
|
|
|
50
55
|
|
|
51
56
|
<script setup>
|
|
52
57
|
import { useDisplay } from "vuetify"
|
|
58
|
+
import { computed, useRoute, useNuxtApp } from "#imports"
|
|
59
|
+
import { useRootStore } from "../../stores/root"
|
|
60
|
+
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
53
61
|
|
|
54
62
|
const { name } = useDisplay()
|
|
63
|
+
const rootStore = useRootStore()
|
|
64
|
+
const { $stores } = useNuxtApp()
|
|
65
|
+
const { name: routeName } = useRoute()
|
|
66
|
+
const searchQuery = computed(() =>
|
|
67
|
+
routeName.startsWith('search') ? rootStore.search : ($stores['fellowships'].search || '')
|
|
68
|
+
)
|
|
55
69
|
|
|
56
70
|
const props = defineProps({
|
|
57
71
|
item: {
|
|
@@ -33,7 +33,9 @@
|
|
|
33
33
|
/>
|
|
34
34
|
|
|
35
35
|
<div v-else class="d-flex align-center flex-column mt-12">
|
|
36
|
-
<div
|
|
36
|
+
<div
|
|
37
|
+
class="d-flex text-center text-wrap text-h4 text-md-h3 text-black"
|
|
38
|
+
>
|
|
37
39
|
{{ item.name }}
|
|
38
40
|
</div>
|
|
39
41
|
<v-divider width="154px" class="mb-1 mt-6" />
|
|
@@ -57,7 +59,7 @@
|
|
|
57
59
|
<FellowshipsBadges :item="item" :view="view" :loading="loading" />
|
|
58
60
|
</div>
|
|
59
61
|
</div>
|
|
60
|
-
<div
|
|
62
|
+
<div>
|
|
61
63
|
<!-- DIVIDERS -->
|
|
62
64
|
<v-responsive class="mx-auto my-9" width="120">
|
|
63
65
|
<v-divider class="mb-1" />
|
|
@@ -49,9 +49,13 @@
|
|
|
49
49
|
:id="`global-search-input-${type}`"
|
|
50
50
|
v-model.trim="search"
|
|
51
51
|
:placeholder="
|
|
52
|
-
|
|
53
|
-
?
|
|
54
|
-
|
|
52
|
+
routeName.startsWith('search')
|
|
53
|
+
? mdAndUp
|
|
54
|
+
? $t('type-a-search-term-to-find-results-across-all-categories')
|
|
55
|
+
: $t('search')
|
|
56
|
+
: type === 'all'
|
|
57
|
+
? $t('search')
|
|
58
|
+
: $t('list.search-type', [$t('items.' + type, 2)])
|
|
55
59
|
"
|
|
56
60
|
single-line
|
|
57
61
|
class="transition-swing flex-grow-1"
|
|
@@ -66,11 +70,18 @@
|
|
|
66
70
|
>
|
|
67
71
|
<template v-if="!search" #label>
|
|
68
72
|
<div class="searchLabel">
|
|
69
|
-
{{
|
|
73
|
+
{{
|
|
74
|
+
routeName.startsWith("search")
|
|
75
|
+
? mdAndUp
|
|
76
|
+
? $t("type-a-search-term-to-find-results-across-all-categories")
|
|
77
|
+
: $t("search")
|
|
78
|
+
: type === "all"
|
|
79
|
+
? $t("search")
|
|
80
|
+
: $t("list.search-type", [$t("items." + type, 2)])
|
|
81
|
+
}}
|
|
70
82
|
</div>
|
|
71
83
|
</template>
|
|
72
84
|
</v-text-field>
|
|
73
|
-
|
|
74
85
|
<v-btn
|
|
75
86
|
:rounded="0"
|
|
76
87
|
variant="outlined"
|
|
@@ -90,11 +101,21 @@
|
|
|
90
101
|
<script setup>
|
|
91
102
|
import { useDebounceFn } from "@vueuse/core"
|
|
92
103
|
import { useRootStore } from "../../../stores/root"
|
|
93
|
-
import {
|
|
104
|
+
import { useDisplay } from "vuetify"
|
|
105
|
+
import {
|
|
106
|
+
computed,
|
|
107
|
+
useI18n,
|
|
108
|
+
ref,
|
|
109
|
+
useLocalePath,
|
|
110
|
+
useRoute,
|
|
111
|
+
useRouter,
|
|
112
|
+
navigateTo,
|
|
113
|
+
} from "#imports"
|
|
114
|
+
const { mdAndUp } = useDisplay()
|
|
94
115
|
const localePath = useLocalePath()
|
|
95
116
|
const { locale, t } = useI18n()
|
|
96
117
|
const rootStore = useRootStore()
|
|
97
|
-
|
|
118
|
+
const { name: routeName } = useRoute()
|
|
98
119
|
// Utility function to capitalize first letter
|
|
99
120
|
const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1)
|
|
100
121
|
const emit = defineEmits(["filter-change"])
|
|
@@ -151,7 +172,11 @@ const toggleFilter = (option) => {
|
|
|
151
172
|
const textFieldRef = ref(null)
|
|
152
173
|
|
|
153
174
|
const navigateToSearch = () => {
|
|
154
|
-
const term = (
|
|
175
|
+
const term = (
|
|
176
|
+
textFieldRef.value?.$el?.querySelector("input")?.value ??
|
|
177
|
+
rootStore.search ??
|
|
178
|
+
""
|
|
179
|
+
).trim()
|
|
155
180
|
rootStore.search = term
|
|
156
181
|
navigateTo({
|
|
157
182
|
path: localePath("/search"),
|
|
@@ -15,8 +15,7 @@
|
|
|
15
15
|
class="d-flex flex-column cursor-pointer"
|
|
16
16
|
@click="$emit('toggle', type)"
|
|
17
17
|
>
|
|
18
|
-
<
|
|
19
|
-
class="text-h5 font-weight-medium"
|
|
18
|
+
<h3
|
|
20
19
|
:class="
|
|
21
20
|
$rootStore.results[type] && $rootStore.results[type].total > 0
|
|
22
21
|
? 'black'
|
|
@@ -24,7 +23,7 @@
|
|
|
24
23
|
"
|
|
25
24
|
>
|
|
26
25
|
{{ capitalize($t("items." + props.type, 2)) }}
|
|
27
|
-
</
|
|
26
|
+
</h3>
|
|
28
27
|
<div class="text-overline">
|
|
29
28
|
{{
|
|
30
29
|
feminine
|
|
@@ -11,10 +11,17 @@
|
|
|
11
11
|
<ListAtomsLogoPlaceholder idle />
|
|
12
12
|
</div>
|
|
13
13
|
<template v-else>
|
|
14
|
-
<div v-if="
|
|
15
|
-
<
|
|
14
|
+
<div v-if="pending" class="search-pending">
|
|
15
|
+
<div class="search-pending__inner">
|
|
16
|
+
<ListAtomsLogoPlaceholder class="loader-logo loader-logo--active" />
|
|
17
|
+
<div class="search-pending__dots">
|
|
18
|
+
<span class="search-pending__dot" />
|
|
19
|
+
<span class="search-pending__dot" />
|
|
20
|
+
<span class="search-pending__dot" />
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
16
23
|
</div>
|
|
17
|
-
<template v-else
|
|
24
|
+
<template v-else>
|
|
18
25
|
<ListMoleculesResultsContainer
|
|
19
26
|
v-for="type in filteredSortedModules"
|
|
20
27
|
:key="type"
|
|
@@ -48,7 +55,6 @@ import {
|
|
|
48
55
|
useI18n,
|
|
49
56
|
useAppConfig,
|
|
50
57
|
useRoute,
|
|
51
|
-
ref,
|
|
52
58
|
reactive,
|
|
53
59
|
useAsyncQuery,
|
|
54
60
|
computed,
|
|
@@ -64,8 +70,6 @@ if (route.query.search) {
|
|
|
64
70
|
$rootStore.search = route.query.search
|
|
65
71
|
}
|
|
66
72
|
|
|
67
|
-
const loading = ref(true)
|
|
68
|
-
|
|
69
73
|
const open = reactive(
|
|
70
74
|
appConfig.list.modules.reduce((acc, type) => {
|
|
71
75
|
acc[type] = false
|
|
@@ -73,10 +77,14 @@ const open = reactive(
|
|
|
73
77
|
}, {}),
|
|
74
78
|
)
|
|
75
79
|
|
|
76
|
-
const selectedCategories =
|
|
80
|
+
const selectedCategories = reactive([...appConfig.list.modules])
|
|
77
81
|
|
|
78
82
|
const handleFilterChange = (filterData) => {
|
|
79
|
-
selectedCategories.
|
|
83
|
+
selectedCategories.splice(
|
|
84
|
+
0,
|
|
85
|
+
selectedCategories.length,
|
|
86
|
+
...filterData.categories,
|
|
87
|
+
)
|
|
80
88
|
}
|
|
81
89
|
|
|
82
90
|
const sortedModules = computed(() => {
|
|
@@ -93,9 +101,7 @@ const sortedModules = computed(() => {
|
|
|
93
101
|
})
|
|
94
102
|
})
|
|
95
103
|
const filteredSortedModules = computed(() => {
|
|
96
|
-
return sortedModules.value.filter((type) =>
|
|
97
|
-
selectedCategories.value.includes(type),
|
|
98
|
-
)
|
|
104
|
+
return sortedModules.value.filter((type) => selectedCategories.includes(type))
|
|
99
105
|
})
|
|
100
106
|
|
|
101
107
|
const searchTerm = computed(() => $rootStore.search || "")
|
|
@@ -113,13 +119,8 @@ const { data, pending, error } = useAsyncQuery(
|
|
|
113
119
|
enabled: computed(() => searchTerm.value.length > 0),
|
|
114
120
|
},
|
|
115
121
|
)
|
|
116
|
-
if (error.value) {
|
|
117
|
-
console.error("GraphQL query error: ", error.value)
|
|
118
|
-
} else {
|
|
119
|
-
/* console.log("Query result data: ", data.value.items?.length) */
|
|
120
|
-
}
|
|
121
122
|
|
|
122
|
-
|
|
123
|
+
watch(data, (newData) => {
|
|
123
124
|
if (!newData) return
|
|
124
125
|
$rootStore.applyListResult("all", newData)
|
|
125
126
|
appConfig.list.modules.forEach((type) => {
|
|
@@ -127,18 +128,364 @@ const applyData = (newData) => {
|
|
|
127
128
|
open[type] = true
|
|
128
129
|
}
|
|
129
130
|
})
|
|
130
|
-
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
watch(data, applyData, { immediate: true })
|
|
131
|
+
})
|
|
134
132
|
|
|
135
133
|
watch(error, (err) => {
|
|
136
|
-
if (err)
|
|
137
|
-
console.error("GraphQL query error:", err)
|
|
138
|
-
loading.value = false
|
|
139
|
-
}
|
|
134
|
+
if (err) console.error("GraphQL query error:", err)
|
|
140
135
|
})
|
|
141
136
|
</script>
|
|
137
|
+
|
|
142
138
|
<style scoped>
|
|
143
|
-
|
|
139
|
+
@charset "UTF-8";
|
|
140
|
+
.results-container {
|
|
141
|
+
margin-left: 8px;
|
|
142
|
+
display: flex;
|
|
143
|
+
flex-direction: column;
|
|
144
|
+
gap: 8px;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.search-empty {
|
|
148
|
+
min-height: 100vh;
|
|
149
|
+
display: flex;
|
|
150
|
+
justify-content: center;
|
|
151
|
+
opacity: 0.8;
|
|
152
|
+
}
|
|
153
|
+
.search-empty svg {
|
|
154
|
+
width: min(32vh, 32vw);
|
|
155
|
+
height: min(32vh, 32vw);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.search-pending {
|
|
159
|
+
display: flex;
|
|
160
|
+
justify-content: center;
|
|
161
|
+
padding: 48px 0;
|
|
162
|
+
}
|
|
163
|
+
.search-pending svg {
|
|
164
|
+
width: min(32vh, 32vw);
|
|
165
|
+
height: min(32vh, 32vw);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
.search-pending__inner {
|
|
169
|
+
display: flex;
|
|
170
|
+
flex-direction: column;
|
|
171
|
+
align-items: center;
|
|
172
|
+
gap: 24px;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
.loader-logo {
|
|
176
|
+
filter: drop-shadow(0 4px 12px rgba(0, 0, 0, 0.1));
|
|
177
|
+
width: 200px;
|
|
178
|
+
height: auto;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Drawing animation — mirrors ListOrganismsLoader exactly */
|
|
182
|
+
.loader-logo--active :deep([class^="IEA_"]) {
|
|
183
|
+
fill: transparent;
|
|
184
|
+
stroke: #000;
|
|
185
|
+
stroke-opacity: 1;
|
|
186
|
+
fill-opacity: 1;
|
|
187
|
+
fill-rule: nonzero;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.loader-logo--active :deep(.IEA_0) {
|
|
191
|
+
stroke-dasharray: 1223 1225;
|
|
192
|
+
stroke-dashoffset: 1224;
|
|
193
|
+
animation: IEA_draw_0 3141ms ease 0ms infinite;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.loader-logo--active :deep(.IEA_5) {
|
|
197
|
+
stroke-dasharray: 335 337;
|
|
198
|
+
stroke-dashoffset: 336;
|
|
199
|
+
animation: IEA_draw_5 3141ms ease 0ms infinite;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.loader-logo--active :deep(.IEA_1) {
|
|
203
|
+
stroke-dasharray: 1351 1353;
|
|
204
|
+
stroke-dashoffset: 1352;
|
|
205
|
+
animation: IEA_draw_1 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.loader-logo--active :deep(.IEA_2) {
|
|
209
|
+
stroke-dasharray: 1311 1313;
|
|
210
|
+
stroke-dashoffset: 1312;
|
|
211
|
+
animation: IEA_draw_2 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.loader-logo--active :deep(.IEA_3),
|
|
215
|
+
.loader-logo--active :deep(.IEA_4) {
|
|
216
|
+
stroke-dasharray: 13 15;
|
|
217
|
+
stroke-dashoffset: 14;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.loader-logo--active :deep(.IEA_3) {
|
|
221
|
+
animation: IEA_draw_3 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
.loader-logo--active :deep(.IEA_4) {
|
|
225
|
+
animation: IEA_draw_4 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
.loader-logo--active :deep(.IEA_6),
|
|
229
|
+
.loader-logo--active :deep(.IEA_7),
|
|
230
|
+
.loader-logo--active :deep(.IEA_8) {
|
|
231
|
+
stroke-dasharray: 102 104;
|
|
232
|
+
stroke-dashoffset: 103;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
.loader-logo--active :deep(.IEA_6) {
|
|
236
|
+
animation: IEA_draw_6 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
.loader-logo--active :deep(.IEA_7) {
|
|
240
|
+
animation: IEA_draw_7 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
.loader-logo--active :deep(.IEA_8) {
|
|
244
|
+
animation: IEA_draw_8 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.loader-logo--active :deep(.IEA_9) {
|
|
248
|
+
stroke-dasharray: 372 374;
|
|
249
|
+
stroke-dashoffset: 373;
|
|
250
|
+
animation: IEA_draw_9 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.loader-logo--active :deep(.IEA_10) {
|
|
254
|
+
stroke-dasharray: 96 98;
|
|
255
|
+
stroke-dashoffset: 97;
|
|
256
|
+
animation: IEA_draw_10 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.loader-logo--active :deep(.IEA_11) {
|
|
260
|
+
stroke-dasharray: 184 186;
|
|
261
|
+
stroke-dashoffset: 185;
|
|
262
|
+
animation: IEA_draw_11 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
.loader-logo--active :deep(.IEA_12) {
|
|
266
|
+
stroke-dasharray: 169 171;
|
|
267
|
+
stroke-dashoffset: 170;
|
|
268
|
+
animation: IEA_draw_12 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.loader-logo--active :deep(.IEA_13) {
|
|
272
|
+
stroke-dasharray: 1020 1022;
|
|
273
|
+
stroke-dashoffset: 1021;
|
|
274
|
+
animation: IEA_draw_13 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-circles 3141ms ease 0ms infinite;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.loader-logo--active :deep(.IEA_14) {
|
|
278
|
+
stroke-dasharray: 939 941;
|
|
279
|
+
stroke-dashoffset: 940;
|
|
280
|
+
animation: IEA_draw_14 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-circles 3141ms ease 0ms infinite;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.loader-logo--active :deep(.IEA_15) {
|
|
284
|
+
stroke-dasharray: 326 328;
|
|
285
|
+
stroke-dashoffset: 327;
|
|
286
|
+
animation: IEA_draw_15 3141ms ease 0ms infinite, stroke-fade 3141ms linear 0ms infinite, fill-standard 3141ms ease 0ms infinite;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
@keyframes fill-standard {
|
|
290
|
+
0%, 35% {
|
|
291
|
+
fill: transparent;
|
|
292
|
+
}
|
|
293
|
+
60% {
|
|
294
|
+
fill: rgba(0, 0, 0, 0.3);
|
|
295
|
+
}
|
|
296
|
+
80% {
|
|
297
|
+
fill: rgba(0, 0, 0, 0.7);
|
|
298
|
+
}
|
|
299
|
+
100% {
|
|
300
|
+
fill: #000;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
@keyframes fill-circles {
|
|
304
|
+
0%, 35% {
|
|
305
|
+
fill: transparent;
|
|
306
|
+
}
|
|
307
|
+
60% {
|
|
308
|
+
fill: rgba(0, 0, 0, 0.2);
|
|
309
|
+
}
|
|
310
|
+
80% {
|
|
311
|
+
fill: rgba(0, 0, 0, 0.5);
|
|
312
|
+
}
|
|
313
|
+
100% {
|
|
314
|
+
fill: #000;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
@keyframes stroke-fade {
|
|
318
|
+
0%, 65% {
|
|
319
|
+
stroke-opacity: 1;
|
|
320
|
+
}
|
|
321
|
+
80% {
|
|
322
|
+
stroke-opacity: 0.5;
|
|
323
|
+
}
|
|
324
|
+
95% {
|
|
325
|
+
stroke-opacity: 0.2;
|
|
326
|
+
}
|
|
327
|
+
100% {
|
|
328
|
+
stroke-opacity: 0;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
@keyframes IEA_draw_0 {
|
|
332
|
+
5% {
|
|
333
|
+
stroke-dashoffset: 1224;
|
|
334
|
+
}
|
|
335
|
+
30%, 100% {
|
|
336
|
+
stroke-dashoffset: 0;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
@keyframes IEA_draw_1 {
|
|
340
|
+
8% {
|
|
341
|
+
stroke-dashoffset: 1352;
|
|
342
|
+
}
|
|
343
|
+
35%, 100% {
|
|
344
|
+
stroke-dashoffset: 0;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
@keyframes IEA_draw_2 {
|
|
348
|
+
10% {
|
|
349
|
+
stroke-dashoffset: 1312;
|
|
350
|
+
}
|
|
351
|
+
40%, 100% {
|
|
352
|
+
stroke-dashoffset: 0;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
@keyframes IEA_draw_3 {
|
|
356
|
+
12% {
|
|
357
|
+
stroke-dashoffset: 14;
|
|
358
|
+
}
|
|
359
|
+
45%, 100% {
|
|
360
|
+
stroke-dashoffset: 0;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
@keyframes IEA_draw_4 {
|
|
364
|
+
15% {
|
|
365
|
+
stroke-dashoffset: 14;
|
|
366
|
+
}
|
|
367
|
+
50%, 100% {
|
|
368
|
+
stroke-dashoffset: 0;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
@keyframes IEA_draw_5 {
|
|
372
|
+
15.74% {
|
|
373
|
+
stroke-dashoffset: 336;
|
|
374
|
+
}
|
|
375
|
+
43.52%, 100% {
|
|
376
|
+
stroke-dashoffset: 0;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
@keyframes IEA_draw_6 {
|
|
380
|
+
16.67% {
|
|
381
|
+
stroke-dashoffset: 103;
|
|
382
|
+
}
|
|
383
|
+
44.44%, 100% {
|
|
384
|
+
stroke-dashoffset: 0;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
@keyframes IEA_draw_7 {
|
|
388
|
+
17.59% {
|
|
389
|
+
stroke-dashoffset: 103;
|
|
390
|
+
}
|
|
391
|
+
45.37%, 100% {
|
|
392
|
+
stroke-dashoffset: 0;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
@keyframes IEA_draw_8 {
|
|
396
|
+
18.52% {
|
|
397
|
+
stroke-dashoffset: 103;
|
|
398
|
+
}
|
|
399
|
+
46.3%, 100% {
|
|
400
|
+
stroke-dashoffset: 0;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
@keyframes IEA_draw_9 {
|
|
404
|
+
19.44% {
|
|
405
|
+
stroke-dashoffset: 373;
|
|
406
|
+
}
|
|
407
|
+
47.22%, 100% {
|
|
408
|
+
stroke-dashoffset: 0;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
@keyframes IEA_draw_10 {
|
|
412
|
+
20.37% {
|
|
413
|
+
stroke-dashoffset: 97;
|
|
414
|
+
}
|
|
415
|
+
48.15%, 100% {
|
|
416
|
+
stroke-dashoffset: 0;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
@keyframes IEA_draw_11 {
|
|
420
|
+
21.3% {
|
|
421
|
+
stroke-dashoffset: 185;
|
|
422
|
+
}
|
|
423
|
+
49.07%, 100% {
|
|
424
|
+
stroke-dashoffset: 0;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
@keyframes IEA_draw_12 {
|
|
428
|
+
22.22% {
|
|
429
|
+
stroke-dashoffset: 170;
|
|
430
|
+
}
|
|
431
|
+
50%, 100% {
|
|
432
|
+
stroke-dashoffset: 0;
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
@keyframes IEA_draw_13 {
|
|
436
|
+
23.15% {
|
|
437
|
+
stroke-dashoffset: 1021;
|
|
438
|
+
}
|
|
439
|
+
50.93%, 100% {
|
|
440
|
+
stroke-dashoffset: 0;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
@keyframes IEA_draw_14 {
|
|
444
|
+
24.07% {
|
|
445
|
+
stroke-dashoffset: 940;
|
|
446
|
+
}
|
|
447
|
+
51.85%, 100% {
|
|
448
|
+
stroke-dashoffset: 0;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
@keyframes IEA_draw_15 {
|
|
452
|
+
25% {
|
|
453
|
+
stroke-dashoffset: 327;
|
|
454
|
+
}
|
|
455
|
+
52.78%, 100% {
|
|
456
|
+
stroke-dashoffset: 0;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
/* Minimalist three-dot indicator */
|
|
460
|
+
.search-pending__dots {
|
|
461
|
+
display: flex;
|
|
462
|
+
gap: 6px;
|
|
463
|
+
align-items: center;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.search-pending__dot {
|
|
467
|
+
display: block;
|
|
468
|
+
width: 5px;
|
|
469
|
+
height: 5px;
|
|
470
|
+
border-radius: 50%;
|
|
471
|
+
background: #000;
|
|
472
|
+
animation: dot-bounce 1.2s ease-in-out infinite;
|
|
473
|
+
}
|
|
474
|
+
.search-pending__dot:nth-child(2) {
|
|
475
|
+
animation-delay: 0.2s;
|
|
476
|
+
}
|
|
477
|
+
.search-pending__dot:nth-child(3) {
|
|
478
|
+
animation-delay: 0.4s;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
@keyframes dot-bounce {
|
|
482
|
+
0%, 80%, 100% {
|
|
483
|
+
opacity: 0.15;
|
|
484
|
+
transform: translateY(0);
|
|
485
|
+
}
|
|
486
|
+
40% {
|
|
487
|
+
opacity: 0.7;
|
|
488
|
+
transform: translateY(-4px);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
144
491
|
</style>
|
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
<v-skeleton-loader v-if="loading" height="100%" type="image" />
|
|
9
9
|
|
|
10
10
|
<template v-else>
|
|
11
|
-
<div
|
|
11
|
+
<div
|
|
12
|
+
class="overflow-hidden"
|
|
13
|
+
:style="width ? `width: ${width}px; height: ${Math.round(width / ratio)}px; max-width: 100%` : 'max-width: 100%'"
|
|
14
|
+
>
|
|
12
15
|
<!-- TODO debug why the picture is not displaying/sizing properly -->
|
|
13
16
|
<v-img
|
|
14
17
|
v-if="src && computedSrc"
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row v-ripple no-gutters class="cursor-pointer highlight-on-hover pa-2">
|
|
3
|
+
<v-col v-if="mdAndUp" cols="1">
|
|
4
|
+
<MiscAtomsDateStamp
|
|
5
|
+
v-if="item.date"
|
|
6
|
+
:loading
|
|
7
|
+
:date-start="item.date"
|
|
8
|
+
class="pr-4"
|
|
9
|
+
/>
|
|
10
|
+
</v-col>
|
|
3
11
|
<v-col v-if="mdAndUp" align-self="center" cols="1">
|
|
4
12
|
<MiscAtomsImageContainer
|
|
5
13
|
cover
|
|
@@ -8,7 +16,7 @@
|
|
|
8
16
|
item && item.image && item.image.url ? item.image.url : '/default.png'
|
|
9
17
|
"
|
|
10
18
|
:ratio="1 / 1"
|
|
11
|
-
:width="
|
|
19
|
+
:width="80"
|
|
12
20
|
/>
|
|
13
21
|
</v-col>
|
|
14
22
|
<v-col align-self="start" class="text-h5 dense mx-2 paragraph">
|
|
@@ -36,12 +44,8 @@
|
|
|
36
44
|
</template>
|
|
37
45
|
<div
|
|
38
46
|
v-html="
|
|
39
|
-
|
|
40
|
-
? highlightAndTruncate(
|
|
41
|
-
300,
|
|
42
|
-
item.name,
|
|
43
|
-
rootStore.search.split(' '),
|
|
44
|
-
)
|
|
47
|
+
searchQuery.length
|
|
48
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
45
49
|
: item.name
|
|
46
50
|
"
|
|
47
51
|
/>
|
|
@@ -54,10 +58,17 @@
|
|
|
54
58
|
import { useDisplay } from "vuetify"
|
|
55
59
|
import { useRootStore } from "../../stores/root"
|
|
56
60
|
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
57
|
-
import { computed } from "#imports"
|
|
61
|
+
import { computed, useRoute, useNuxtApp } from "#imports"
|
|
58
62
|
|
|
59
63
|
const { name, mdAndUp } = useDisplay()
|
|
60
64
|
const rootStore = useRootStore()
|
|
65
|
+
const { name: routeName } = useRoute()
|
|
66
|
+
const { $stores } = useNuxtApp()
|
|
67
|
+
const searchQuery = computed(() =>
|
|
68
|
+
routeName.startsWith("search")
|
|
69
|
+
? rootStore.search
|
|
70
|
+
: $stores["news"].search || "",
|
|
71
|
+
)
|
|
61
72
|
|
|
62
73
|
const props = defineProps({
|
|
63
74
|
item: {
|
|
@@ -36,9 +36,14 @@
|
|
|
36
36
|
<br />
|
|
37
37
|
</template>
|
|
38
38
|
|
|
39
|
-
<div
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
<div
|
|
40
|
+
class="text-wrap text-h5 text-md-h4 text-black"
|
|
41
|
+
v-html="
|
|
42
|
+
searchQuery.length
|
|
43
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
44
|
+
: item.name
|
|
45
|
+
"
|
|
46
|
+
/>
|
|
42
47
|
<div class="tex-overline mt-3">
|
|
43
48
|
{{ formatDateValue(item.date, locale) }}
|
|
44
49
|
</div>
|
|
@@ -104,11 +109,19 @@
|
|
|
104
109
|
<script setup>
|
|
105
110
|
import { useDisplay } from "vuetify"
|
|
106
111
|
import { useRootStore } from "../../stores/root"
|
|
107
|
-
import { useI18n, computed } from "#imports"
|
|
112
|
+
import { useI18n, computed, useRoute, useNuxtApp } from "#imports"
|
|
113
|
+
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
108
114
|
|
|
109
115
|
const { locale } = useI18n()
|
|
110
116
|
const rootStore = useRootStore()
|
|
111
117
|
const { name, smAndDown, mdAndDown, mdAndUp, lgAndUp } = useDisplay()
|
|
118
|
+
const { $stores } = useNuxtApp()
|
|
119
|
+
const { name: routeName } = useRoute()
|
|
120
|
+
const searchQuery = computed(() =>
|
|
121
|
+
routeName.startsWith("search")
|
|
122
|
+
? rootStore.search
|
|
123
|
+
: $stores["news"].search || "",
|
|
124
|
+
)
|
|
112
125
|
const eventCategory = computed(() => {
|
|
113
126
|
if (props.item.category) {
|
|
114
127
|
return "list.filters.news.category." + props.item.category
|
|
@@ -138,8 +151,10 @@ const props = defineProps({
|
|
|
138
151
|
|
|
139
152
|
const processedSummary = computed(() => {
|
|
140
153
|
const raw = props.item.summary || ""
|
|
141
|
-
|
|
142
|
-
return
|
|
154
|
+
const linked = replaceMarkdownLinksWithSlug(raw, props.path)
|
|
155
|
+
return searchQuery.value.length
|
|
156
|
+
? highlightAndTruncate(500, linked, searchQuery.value.split(" "))
|
|
157
|
+
: linked
|
|
143
158
|
})
|
|
144
159
|
|
|
145
160
|
function replaceMarkdownLinksWithSlug(markdownText, slugPath) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row v-ripple no-gutters class="cursor-pointer highlight-on-hover">
|
|
3
|
-
<v-col v-if="mdAndUp" cols="1">
|
|
3
|
+
<v-col v-if="mdAndUp" cols="1" :offset="name.startsWith('search') ? 1 : 0">
|
|
4
4
|
<MiscAtomsImageContainer
|
|
5
5
|
cover
|
|
6
6
|
:loading="loading"
|
|
@@ -8,20 +8,23 @@
|
|
|
8
8
|
item && item.image && item.image.url ? item.image.url : '/default.png'
|
|
9
9
|
"
|
|
10
10
|
:ratio="1 / 1"
|
|
11
|
-
:width="
|
|
11
|
+
:width="80"
|
|
12
12
|
class="ma-1"
|
|
13
13
|
/>
|
|
14
14
|
</v-col>
|
|
15
|
-
<v-col align-self="start" class="text-h6 dense
|
|
15
|
+
<v-col align-self="start" class="text-sm-h6 dense">
|
|
16
16
|
<v-skeleton-loader v-if="loading" type="heading" />
|
|
17
|
-
<div
|
|
17
|
+
<div
|
|
18
|
+
v-else
|
|
19
|
+
class="d-flex justify-space-between text-title text-md-h5 align-center"
|
|
20
|
+
>
|
|
18
21
|
<span
|
|
19
22
|
v-html="
|
|
20
|
-
|
|
23
|
+
searchQuery.length
|
|
21
24
|
? highlightAndTruncate(
|
|
22
25
|
300,
|
|
23
26
|
item.firstname + ' ' + item.lastname,
|
|
24
|
-
|
|
27
|
+
searchQuery.split(' '),
|
|
25
28
|
)
|
|
26
29
|
: item.firstname + ' ' + item.lastname
|
|
27
30
|
"
|
|
@@ -33,15 +36,30 @@
|
|
|
33
36
|
v-if="item.group && item.groups.vintage && item.groups.vintage[0].theme"
|
|
34
37
|
class="text-body-1 font-weight-light paragraph"
|
|
35
38
|
v-html="
|
|
36
|
-
|
|
39
|
+
searchQuery.length
|
|
37
40
|
? highlightAndTruncate(
|
|
38
41
|
300,
|
|
39
42
|
item.groups.vintage[0].theme,
|
|
40
|
-
|
|
43
|
+
searchQuery.split(' '),
|
|
41
44
|
)
|
|
42
45
|
: item.groups.vintage[0].theme
|
|
43
46
|
"
|
|
44
47
|
/>
|
|
48
|
+
<div
|
|
49
|
+
v-if="item.summary && mdAndUp"
|
|
50
|
+
class="text-body-1 font-weight-light paragraph"
|
|
51
|
+
:style="
|
|
52
|
+
'-webkit-line-clamp:' +
|
|
53
|
+
[1, 1, 1, 2, 3, 3][
|
|
54
|
+
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(displayName || 'md')
|
|
55
|
+
]
|
|
56
|
+
"
|
|
57
|
+
v-html="
|
|
58
|
+
searchQuery.length
|
|
59
|
+
? highlightAndTruncate(100, item.summary, searchQuery.split(' '))
|
|
60
|
+
: item.summary
|
|
61
|
+
"
|
|
62
|
+
/>
|
|
45
63
|
</v-col>
|
|
46
64
|
</v-row>
|
|
47
65
|
</template>
|
|
@@ -49,11 +67,16 @@
|
|
|
49
67
|
<script setup>
|
|
50
68
|
import { useRootStore } from "../../stores/root"
|
|
51
69
|
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
52
|
-
import { computed } from "#imports"
|
|
70
|
+
import { computed, useRoute, useNuxtApp } from "#imports"
|
|
53
71
|
import { useDisplay } from "vuetify"
|
|
72
|
+
const { name } = useRoute()
|
|
54
73
|
|
|
55
|
-
const { mdAndUp } = useDisplay()
|
|
74
|
+
const { mdAndUp, name: displayName } = useDisplay()
|
|
56
75
|
const rootStore = useRootStore()
|
|
76
|
+
const { $stores } = useNuxtApp()
|
|
77
|
+
const searchQuery = computed(() =>
|
|
78
|
+
name.startsWith("search") ? rootStore.search : $stores["people"].search || "",
|
|
79
|
+
)
|
|
57
80
|
const props = defineProps({
|
|
58
81
|
item: {
|
|
59
82
|
type: Object,
|
|
@@ -72,5 +95,5 @@ const props = defineProps({
|
|
|
72
95
|
})
|
|
73
96
|
</script>
|
|
74
97
|
<style>
|
|
75
|
-
.paragraph{max-width:83ch!important}
|
|
98
|
+
.paragraph{display:-webkit-box;max-width:83ch!important;-webkit-box-orient:vertical;overflow:hidden}
|
|
76
99
|
</style>
|
|
@@ -26,17 +26,22 @@
|
|
|
26
26
|
/>
|
|
27
27
|
|
|
28
28
|
<div v-else class="ml-md-8">
|
|
29
|
-
<div
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
<div
|
|
30
|
+
class="text-wrap text-h5 text-md-h4 text-black"
|
|
31
|
+
v-html="
|
|
32
|
+
searchQuery.length
|
|
33
|
+
? highlightAndTruncate(300, item.firstname + ' ' + item.lastname, searchQuery.split(' '))
|
|
34
|
+
: item.firstname + ' ' + item.lastname
|
|
35
|
+
"
|
|
36
|
+
/>
|
|
32
37
|
<MiscAtomsSocials v-if="item.socials" :socials="item.socials" />
|
|
33
38
|
<PeoplepBadges :item="item" />
|
|
34
39
|
<div
|
|
35
|
-
v-if="item.
|
|
40
|
+
v-if="item.summary && item.summary.length > 0"
|
|
36
41
|
class="text-wrap clamped-text text-black"
|
|
37
42
|
:style="'-webkit-line-clamp:' + lineClamp"
|
|
38
43
|
>
|
|
39
|
-
<MDC :value="item.
|
|
44
|
+
<MDC :value="searchQuery.length ? highlightAndTruncate(500, item.summary, searchQuery.split(' ')) : item.summary" />
|
|
40
45
|
</div>
|
|
41
46
|
|
|
42
47
|
<div v-else class="text-body-2">
|
|
@@ -49,9 +54,17 @@
|
|
|
49
54
|
|
|
50
55
|
<script setup>
|
|
51
56
|
import { useDisplay } from "vuetify"
|
|
52
|
-
import { computed } from "#imports"
|
|
57
|
+
import { computed, useRoute, useNuxtApp } from "#imports"
|
|
58
|
+
import { useRootStore } from "../../stores/root"
|
|
59
|
+
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
53
60
|
|
|
54
61
|
const { name, mdAndUp } = useDisplay()
|
|
62
|
+
const rootStore = useRootStore()
|
|
63
|
+
const { $stores } = useNuxtApp()
|
|
64
|
+
const { name: routeName } = useRoute()
|
|
65
|
+
const searchQuery = computed(() =>
|
|
66
|
+
routeName.startsWith('search') ? rootStore.search : ($stores['people'].search || '')
|
|
67
|
+
)
|
|
55
68
|
|
|
56
69
|
const props = defineProps({
|
|
57
70
|
item: {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-row v-ripple no-gutters class="cursor-pointer highlight-on-hover
|
|
3
|
-
<v-col
|
|
2
|
+
<v-row v-ripple no-gutters class="cursor-pointer highlight-on-hover">
|
|
3
|
+
<v-col
|
|
4
|
+
v-if="mdAndUp"
|
|
5
|
+
align-self="center"
|
|
6
|
+
cols="1"
|
|
7
|
+
:offset="name.startsWith('search') ? 1 : 0"
|
|
8
|
+
>
|
|
4
9
|
<MiscAtomsImageContainer
|
|
5
10
|
cover
|
|
6
11
|
:loading="loading"
|
|
@@ -8,16 +13,16 @@
|
|
|
8
13
|
item && item.image && item.image.url ? item.image.url : '/default.png'
|
|
9
14
|
"
|
|
10
15
|
:ratio="1 / 1"
|
|
11
|
-
:width="
|
|
16
|
+
:width="80"
|
|
12
17
|
/>
|
|
13
18
|
</v-col>
|
|
14
|
-
<v-col align-self="center" class="text-h5 dense
|
|
19
|
+
<v-col align-self="center" class="text-h5 dense pt-2">
|
|
15
20
|
<v-skeleton-loader v-if="loading" type="heading" width="50%" />
|
|
16
21
|
<span
|
|
17
22
|
v-else
|
|
18
23
|
v-html="
|
|
19
|
-
|
|
20
|
-
? highlightAndTruncate(300, item.name,
|
|
24
|
+
searchQuery.length
|
|
25
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
21
26
|
: item.name
|
|
22
27
|
"
|
|
23
28
|
/>
|
|
@@ -36,7 +41,7 @@
|
|
|
36
41
|
:value="`${highlightAndTruncate(
|
|
37
42
|
150,
|
|
38
43
|
item.summary,
|
|
39
|
-
|
|
44
|
+
searchQuery.split(' '),
|
|
40
45
|
)}`"
|
|
41
46
|
/>
|
|
42
47
|
</v-col>
|
|
@@ -47,10 +52,17 @@
|
|
|
47
52
|
import { useDisplay } from "vuetify"
|
|
48
53
|
import { useRootStore } from "../../stores/root"
|
|
49
54
|
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
50
|
-
|
|
55
|
+
import { useRoute, useNuxtApp, computed } from "#imports"
|
|
51
56
|
const { mdAndUp } = useDisplay()
|
|
57
|
+
const { name } = useRoute()
|
|
52
58
|
|
|
53
59
|
const rootStore = useRootStore()
|
|
60
|
+
const { $stores } = useNuxtApp()
|
|
61
|
+
const searchQuery = computed(() =>
|
|
62
|
+
name.startsWith("search")
|
|
63
|
+
? rootStore.search
|
|
64
|
+
: $stores["projects"].search || "",
|
|
65
|
+
)
|
|
54
66
|
const props = defineProps({
|
|
55
67
|
item: {
|
|
56
68
|
type: Object,
|
|
@@ -23,9 +23,14 @@
|
|
|
23
23
|
/>
|
|
24
24
|
|
|
25
25
|
<template v-else>
|
|
26
|
-
<div
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
<div
|
|
27
|
+
class="text-h5 text-sm-h3 text-md-h4 text-md-h4 my-6"
|
|
28
|
+
v-html="
|
|
29
|
+
searchQuery.length
|
|
30
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
31
|
+
: item.name
|
|
32
|
+
"
|
|
33
|
+
/>
|
|
29
34
|
<div
|
|
30
35
|
v-if="item.summary"
|
|
31
36
|
class="mt-n3 text-wrap clamped-text"
|
|
@@ -36,7 +41,17 @@
|
|
|
36
41
|
]
|
|
37
42
|
"
|
|
38
43
|
>
|
|
39
|
-
<MDC
|
|
44
|
+
<MDC
|
|
45
|
+
:value="
|
|
46
|
+
searchQuery.length
|
|
47
|
+
? highlightAndTruncate(
|
|
48
|
+
500,
|
|
49
|
+
item.summary,
|
|
50
|
+
searchQuery.split(' '),
|
|
51
|
+
)
|
|
52
|
+
: item.summary
|
|
53
|
+
"
|
|
54
|
+
/>
|
|
40
55
|
</div>
|
|
41
56
|
|
|
42
57
|
<v-btn
|
|
@@ -54,7 +69,7 @@
|
|
|
54
69
|
<v-btn
|
|
55
70
|
variant="outlined"
|
|
56
71
|
tile
|
|
57
|
-
class="mt-4 ml-4"
|
|
72
|
+
class="mt-4 ml-0 ml-md-4"
|
|
58
73
|
prepend-icon="mdi-web"
|
|
59
74
|
:size="
|
|
60
75
|
['small', 'small', 'small', 'default', 'default', 'large'][
|
|
@@ -67,13 +82,24 @@
|
|
|
67
82
|
</template>
|
|
68
83
|
</v-col>
|
|
69
84
|
</v-row>
|
|
70
|
-
<v-divider />
|
|
85
|
+
<v-divider class="my-6" />
|
|
71
86
|
</template>
|
|
72
87
|
|
|
73
88
|
<script setup>
|
|
74
89
|
import { useDisplay } from "vuetify"
|
|
90
|
+
import { computed, useRoute, useNuxtApp } from "#imports"
|
|
91
|
+
import { useRootStore } from "../../stores/root"
|
|
92
|
+
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
75
93
|
|
|
76
94
|
const { name } = useDisplay()
|
|
95
|
+
const rootStore = useRootStore()
|
|
96
|
+
const { $stores } = useNuxtApp()
|
|
97
|
+
const { name: routeName } = useRoute()
|
|
98
|
+
const searchQuery = computed(() =>
|
|
99
|
+
routeName.startsWith("search")
|
|
100
|
+
? rootStore.search
|
|
101
|
+
: $stores["projects"].search || "",
|
|
102
|
+
)
|
|
77
103
|
|
|
78
104
|
const props = defineProps({
|
|
79
105
|
item: {
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row v-ripple no-gutters class="cursor-pointer highlight-on-hover my-2">
|
|
3
|
-
<v-col
|
|
3
|
+
<v-col
|
|
4
|
+
v-if="mdAndUp"
|
|
5
|
+
cols="1"
|
|
6
|
+
class="align-center"
|
|
7
|
+
:offset="name.startsWith('search') ? 1 : 0"
|
|
8
|
+
>
|
|
4
9
|
<MiscAtomsImageContainer
|
|
5
10
|
cover
|
|
6
11
|
:loading="loading"
|
|
@@ -8,7 +13,7 @@
|
|
|
8
13
|
item && item.image && item.image.url ? item.image.url : '/default.png'
|
|
9
14
|
"
|
|
10
15
|
:ratio="1 / 1"
|
|
11
|
-
:width="
|
|
16
|
+
:width="80"
|
|
12
17
|
/>
|
|
13
18
|
</v-col>
|
|
14
19
|
<v-col class="pl-2">
|
|
@@ -44,12 +49,8 @@
|
|
|
44
49
|
v-else
|
|
45
50
|
class="text-h5 dense paragraph"
|
|
46
51
|
v-html="
|
|
47
|
-
|
|
48
|
-
? highlightAndTruncate(
|
|
49
|
-
300,
|
|
50
|
-
item.name,
|
|
51
|
-
rootStore.search.split(' '),
|
|
52
|
-
)
|
|
52
|
+
searchQuery.length
|
|
53
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
53
54
|
: item.name
|
|
54
55
|
"
|
|
55
56
|
/>
|
|
@@ -61,7 +62,7 @@
|
|
|
61
62
|
:value="`${highlightAndTruncate(
|
|
62
63
|
150,
|
|
63
64
|
item.summary,
|
|
64
|
-
|
|
65
|
+
searchQuery.split(' '),
|
|
65
66
|
)}`"
|
|
66
67
|
/>
|
|
67
68
|
</div> </v-col
|
|
@@ -72,9 +73,15 @@
|
|
|
72
73
|
import { useDisplay } from "vuetify"
|
|
73
74
|
import { useRootStore } from "../../stores/root"
|
|
74
75
|
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
75
|
-
import { computed } from "#imports"
|
|
76
|
+
import { computed, useRoute, useNuxtApp } from "#imports"
|
|
76
77
|
const rootStore = useRootStore()
|
|
77
|
-
|
|
78
|
+
const { name } = useRoute()
|
|
79
|
+
const { $stores } = useNuxtApp()
|
|
80
|
+
const searchQuery = computed(() =>
|
|
81
|
+
name.startsWith("search")
|
|
82
|
+
? rootStore.search
|
|
83
|
+
: $stores["publications"].search || "",
|
|
84
|
+
)
|
|
78
85
|
const { mdAndUp } = useDisplay()
|
|
79
86
|
const props = defineProps({
|
|
80
87
|
item: {
|
|
@@ -25,9 +25,14 @@
|
|
|
25
25
|
|
|
26
26
|
<template v-else>
|
|
27
27
|
<div v-if="item.type" class="text-overline">{{ $t(item.type) }}</div>
|
|
28
|
-
<div
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
<div
|
|
29
|
+
class="text-h5 text-sm-h3 text-md-h4 text-md-h4 my-6"
|
|
30
|
+
v-html="
|
|
31
|
+
searchQuery.length
|
|
32
|
+
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
33
|
+
: item.name
|
|
34
|
+
"
|
|
35
|
+
/>
|
|
31
36
|
<div
|
|
32
37
|
v-if="item.summary"
|
|
33
38
|
class="text-wrap clamped-text"
|
|
@@ -38,7 +43,7 @@
|
|
|
38
43
|
]
|
|
39
44
|
"
|
|
40
45
|
>
|
|
41
|
-
<MDC :value="item.summary" />
|
|
46
|
+
<MDC :value="searchQuery.length ? highlightAndTruncate(500, item.summary, searchQuery.split(' ')) : item.summary" />
|
|
42
47
|
</div>
|
|
43
48
|
<v-btn
|
|
44
49
|
class="mt-4"
|
|
@@ -77,8 +82,17 @@
|
|
|
77
82
|
|
|
78
83
|
<script setup>
|
|
79
84
|
import { useDisplay } from "vuetify"
|
|
85
|
+
import { computed, useRoute, useNuxtApp } from "#imports"
|
|
86
|
+
import { useRootStore } from "../../stores/root"
|
|
87
|
+
import { highlightAndTruncate } from "../../composables/useUtils"
|
|
80
88
|
|
|
81
89
|
const { name } = useDisplay()
|
|
90
|
+
const rootStore = useRootStore()
|
|
91
|
+
const { $stores } = useNuxtApp()
|
|
92
|
+
const { name: routeName } = useRoute()
|
|
93
|
+
const searchQuery = computed(() =>
|
|
94
|
+
routeName.startsWith('search') ? rootStore.search : ($stores['publications'].search || '')
|
|
95
|
+
)
|
|
82
96
|
|
|
83
97
|
const props = defineProps({
|
|
84
98
|
item: {
|