@paris-ias/list 1.0.115 → 1.0.116
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 +26 -7
- package/dist/runtime/components/fellowships/DenseItem.vue +9 -2
- package/dist/runtime/components/list/atoms/ResetButton.vue +2 -2
- package/dist/runtime/components/list/atoms/ResultsList.vue +5 -3
- package/dist/runtime/components/list/atoms/SearchInput.vue +5 -3
- package/dist/runtime/components/list/molecules/Pagination.vue +21 -2
- package/dist/runtime/components/misc/molecules/ChipContainer.vue +5 -15
- package/dist/runtime/components/misc/molecules/RelatedItems.vue +0 -3
- package/dist/runtime/components/news/DenseItem.vue +14 -3
- package/dist/runtime/components/news/ExpandedItem.vue +3 -3
- package/dist/runtime/components/news/RowsItem.vue +1 -7
- package/dist/runtime/components/people/Badges.vue +3 -3
- package/dist/runtime/components/people/DenseItem.vue +25 -5
- package/dist/runtime/components/projects/DenseItem.vue +13 -9
- package/dist/runtime/components/publications/DenseItem.vue +56 -38
- package/dist/runtime/composables/useUtils.d.ts +1 -0
- package/dist/runtime/composables/useUtils.js +44 -0
- package/dist/runtime/translations/en.json +3 -2
- package/dist/runtime/translations/fr.json +3 -2
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -27,21 +27,39 @@
|
|
|
27
27
|
/>
|
|
28
28
|
</v-col>
|
|
29
29
|
|
|
30
|
-
<v-col align-self="
|
|
30
|
+
<v-col align-self="start" class="pl-2">
|
|
31
31
|
<v-chip
|
|
32
32
|
class="mr-3"
|
|
33
33
|
color="black"
|
|
34
|
-
|
|
34
|
+
size="small"
|
|
35
35
|
style="background-color: white; color: black"
|
|
36
36
|
tile
|
|
37
37
|
variant="outlined"
|
|
38
38
|
>
|
|
39
39
|
{{ $t("list.filters.events.category." + item.category) }}
|
|
40
40
|
</v-chip>
|
|
41
|
+
<span v-if="smAndDown" class="text-overline">
|
|
42
|
+
{{
|
|
43
|
+
new Date(item.start).toLocaleDateString(locale, {
|
|
44
|
+
year: "numeric",
|
|
45
|
+
month: "numeric",
|
|
46
|
+
day: "numeric",
|
|
47
|
+
})
|
|
48
|
+
}}
|
|
49
|
+
</span>
|
|
41
50
|
|
|
42
|
-
<div
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
<div
|
|
52
|
+
class="text-h5 dense paragraph mt-2"
|
|
53
|
+
v-html="
|
|
54
|
+
$rootStore.search.length
|
|
55
|
+
? highlightAndTruncate(300, item.name, $rootStore.search.split(' '))
|
|
56
|
+
: item.name
|
|
57
|
+
"
|
|
58
|
+
/>
|
|
59
|
+
<MDC
|
|
60
|
+
class="text-body-1 font-weight-light paragraph"
|
|
61
|
+
:value="`${highlightAndTruncate(85, item.summary, $rootStore.search.split(' '))}`"
|
|
62
|
+
/>
|
|
45
63
|
</v-col>
|
|
46
64
|
|
|
47
65
|
<v-col align-self="center" cols="auto">
|
|
@@ -51,9 +69,10 @@
|
|
|
51
69
|
</template>
|
|
52
70
|
|
|
53
71
|
<script setup>
|
|
54
|
-
import { useLocalePath, useI18n } from "#imports";
|
|
72
|
+
import { useLocalePath, useI18n, useNuxtApp } from "#imports";
|
|
55
73
|
import { useDisplay } from "vuetify";
|
|
56
|
-
const {
|
|
74
|
+
const { $rootStore } = useNuxtApp();
|
|
75
|
+
const { smAndDown, mdAndUp, lgAndUp } = useDisplay();
|
|
57
76
|
const { locale } = useI18n();
|
|
58
77
|
const localePath = useLocalePath();
|
|
59
78
|
const props = defineProps({
|
|
@@ -8,7 +8,13 @@
|
|
|
8
8
|
"
|
|
9
9
|
>
|
|
10
10
|
<v-col align-self="center" cols="8" class="text-h5 dense">
|
|
11
|
-
|
|
11
|
+
<div
|
|
12
|
+
v-html="
|
|
13
|
+
$rootStore.search.length
|
|
14
|
+
? highlightAndTruncate(300, item.name, $rootStore.search.split(' '))
|
|
15
|
+
: item.name
|
|
16
|
+
"
|
|
17
|
+
/>
|
|
12
18
|
<FellowshipsBadges :item="item" />
|
|
13
19
|
</v-col>
|
|
14
20
|
<v-col align-self="center" cols="4">
|
|
@@ -26,7 +32,8 @@
|
|
|
26
32
|
</template>
|
|
27
33
|
|
|
28
34
|
<script setup>
|
|
29
|
-
import { useLocalePath, useI18n } from "#imports";
|
|
35
|
+
import { useLocalePath, useI18n, useNuxtApp } from "#imports";
|
|
36
|
+
const { $rootStore } = useNuxtApp();
|
|
30
37
|
const { locale } = useI18n();
|
|
31
38
|
const localePath = useLocalePath();
|
|
32
39
|
const props = defineProps({
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
icon
|
|
10
10
|
class="ml-auto"
|
|
11
11
|
v-bind="tooltip"
|
|
12
|
-
@click="rootStore.resetState(type, locale)"
|
|
12
|
+
@click="rootStore.resetState(props.type, locale)"
|
|
13
13
|
>
|
|
14
14
|
<v-icon>mdi-restore</v-icon>
|
|
15
15
|
</v-btn>
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
<script setup>
|
|
22
22
|
import { useRootStore } from "../../../stores/root";
|
|
23
23
|
import { useI18n } from "#imports";
|
|
24
|
-
const rootStore = useRootStore();
|
|
25
24
|
const { locale } = useI18n();
|
|
25
|
+
const rootStore = useRootStore();
|
|
26
26
|
const props = defineProps({
|
|
27
27
|
type: {
|
|
28
28
|
type: String,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<component
|
|
3
3
|
:is="itemTemplate"
|
|
4
|
-
v-for="(item, index) in
|
|
4
|
+
v-for="(item, index) in rootStore.results[type].items"
|
|
5
5
|
:key="index"
|
|
6
6
|
:item="item"
|
|
7
7
|
:index="index"
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
|
|
11
11
|
<script setup>
|
|
12
12
|
import { capitalize } from "../../../composables/useUtils";
|
|
13
|
+
import { useRootStore } from "../../../stores/root";
|
|
13
14
|
import { useNuxtApp, resolveComponent, computed } from "#imports";
|
|
14
|
-
const { $stores
|
|
15
|
-
|
|
15
|
+
const { $stores } = useNuxtApp();
|
|
16
|
+
const rootStore = useRootStore();
|
|
17
|
+
console.log("rootStore: ", rootStore);
|
|
16
18
|
const props = defineProps({
|
|
17
19
|
type: {
|
|
18
20
|
type: String,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<v-text-field
|
|
4
4
|
v-model.trim="search"
|
|
5
5
|
:placeholder="$t('list.search-type', [$t('items.' + type, 2)])"
|
|
6
|
-
:append-icon="type === 'all' ? 'mdi-magnify' :
|
|
6
|
+
:append-icon="type === 'all' ? 'mdi-magnify' : ''"
|
|
7
7
|
prepend-inner-icon="mdi-magnify"
|
|
8
8
|
single-line
|
|
9
9
|
class="transition-swing"
|
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
tile
|
|
14
14
|
type="search"
|
|
15
15
|
:loading="rootStore.loading"
|
|
16
|
-
@keyup.enter="type === 'all' ?
|
|
17
|
-
@click:append="
|
|
16
|
+
@keyup.enter="type === 'all' ? $router.push(localePath('/search')) : null"
|
|
17
|
+
@click:append="
|
|
18
|
+
type === 'all' ? $router.push(localePath('/search')) : null
|
|
19
|
+
"
|
|
18
20
|
>
|
|
19
21
|
<!-- :loading="$nuxt.loading || $store.state.loading" :class="{ 'mt-3':
|
|
20
22
|
$store.state.scrolled }" -->
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
...
|
|
35
35
|
</v-btn>
|
|
36
36
|
<template v-else>
|
|
37
|
-
<v-btn
|
|
37
|
+
<!-- <v-btn
|
|
38
38
|
:class="{ 'active-page': !!page.current }"
|
|
39
39
|
tabindex="0"
|
|
40
40
|
outlined
|
|
@@ -56,6 +56,25 @@
|
|
|
56
56
|
@keyup.enter="updatePage(page.value)"
|
|
57
57
|
>
|
|
58
58
|
{{ page.value }}
|
|
59
|
+
</v-btn> -->
|
|
60
|
+
|
|
61
|
+
<v-btn
|
|
62
|
+
:class="['page-button', { 'active-page': page.current }]"
|
|
63
|
+
tabindex="0"
|
|
64
|
+
min-width="35"
|
|
65
|
+
height="35"
|
|
66
|
+
tile
|
|
67
|
+
width="35"
|
|
68
|
+
aria-current="page"
|
|
69
|
+
:aria-label="
|
|
70
|
+
page.current
|
|
71
|
+
? `Current page, Page ${page.value}`
|
|
72
|
+
: `Goto Page ${page.value}`
|
|
73
|
+
"
|
|
74
|
+
@click="updatePage(page.value)"
|
|
75
|
+
@keyup.enter="updatePage(page.value)"
|
|
76
|
+
>
|
|
77
|
+
{{ page.value }}
|
|
59
78
|
</v-btn>
|
|
60
79
|
</template>
|
|
61
80
|
</template>
|
|
@@ -190,5 +209,5 @@ const getGapPage = (index) => {
|
|
|
190
209
|
</script>
|
|
191
210
|
|
|
192
211
|
<style>
|
|
193
|
-
.active-page{background-color:#000!important;color:#
|
|
212
|
+
.page-button{background-color:transparent;border:1px solid rgba(0,0,0,.2);color:#000;transition:background-color .3s ease,color .3s ease,transform .2s ease}.page-button:hover{background-color:#f0f0f0}.page-button.active-page{background-color:#000!important;color:#fff!important;transform:scale(1.05)}.page-button:focus{box-shadow:0 0 0 2px rgba(0,0,0,.3);outline:none}
|
|
194
213
|
</style>
|
|
@@ -1,26 +1,16 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
2
|
+
<span class="d-flex flex-row flex-wrap" v-bind="attrs">
|
|
3
3
|
<div v-for="(tag, index) in items" :key="tag + index" class="">
|
|
4
|
-
<v-chip
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
|
|
8
|
-
]
|
|
9
|
-
"
|
|
10
|
-
class="mr-2 mt-2"
|
|
11
|
-
variant="outlined"
|
|
12
|
-
label
|
|
13
|
-
>{{ tag }}</v-chip
|
|
14
|
-
>
|
|
4
|
+
<v-chip size="small" class="mr-2 mt-2" variant="outlined" label>{{
|
|
5
|
+
tag
|
|
6
|
+
}}</v-chip>
|
|
15
7
|
</div>
|
|
16
|
-
</
|
|
8
|
+
</span>
|
|
17
9
|
</template>
|
|
18
10
|
|
|
19
11
|
<script setup>
|
|
20
12
|
import { useAttrs } from "vue";
|
|
21
|
-
import { useDisplay } from "vuetify";
|
|
22
13
|
const attrs = useAttrs();
|
|
23
|
-
const { name, md, xl, lg, smAndDown, mdAndUp } = useDisplay();
|
|
24
14
|
const props = defineProps({
|
|
25
15
|
items: {
|
|
26
16
|
type: Array,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
width="80px"
|
|
18
18
|
/>
|
|
19
19
|
</v-col>
|
|
20
|
-
<v-col align-self="
|
|
20
|
+
<v-col align-self="start" class="text-h5 dense px-2 paragraph">
|
|
21
21
|
<v-skeleton-loader v-if="rootStore.loading" type="heading" />
|
|
22
22
|
<template v-else>
|
|
23
23
|
<v-skeleton-loader
|
|
@@ -33,13 +33,24 @@
|
|
|
33
33
|
<v-chip
|
|
34
34
|
class="ma-2"
|
|
35
35
|
style="background-color: white; color: black"
|
|
36
|
-
|
|
36
|
+
size="small"
|
|
37
|
+
variant="outlined"
|
|
37
38
|
>
|
|
38
39
|
{{ $t(eventCategory) }}
|
|
39
40
|
</v-chip>
|
|
40
41
|
<MiscMoleculesChipContainer :items="item.tags" size="small" />
|
|
41
42
|
</template>
|
|
42
|
-
|
|
43
|
+
<div
|
|
44
|
+
v-html="
|
|
45
|
+
$rootStore.search.length
|
|
46
|
+
? highlightAndTruncate(
|
|
47
|
+
300,
|
|
48
|
+
item.name,
|
|
49
|
+
$rootStore.search.split(' '),
|
|
50
|
+
)
|
|
51
|
+
: item.name
|
|
52
|
+
"
|
|
53
|
+
/>
|
|
43
54
|
</template>
|
|
44
55
|
</v-col>
|
|
45
56
|
</v-row>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
localePath({
|
|
16
16
|
name: 'news-slug',
|
|
17
17
|
params: { slug: item.slug[locale] },
|
|
18
|
-
})
|
|
18
|
+
}),
|
|
19
19
|
)
|
|
20
20
|
: null
|
|
21
21
|
"
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
localePath({
|
|
37
37
|
name: 'news-slug',
|
|
38
38
|
params: { slug: item.slug[locale] },
|
|
39
|
-
})
|
|
39
|
+
}),
|
|
40
40
|
)
|
|
41
41
|
: null
|
|
42
42
|
"
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
localePath({
|
|
72
72
|
name: 'news-slug',
|
|
73
73
|
params: { slug: item.slug[locale] },
|
|
74
|
-
})
|
|
74
|
+
}),
|
|
75
75
|
)
|
|
76
76
|
"
|
|
77
77
|
>
|
|
@@ -135,13 +135,7 @@
|
|
|
135
135
|
<script setup>
|
|
136
136
|
import { useDisplay } from "vuetify";
|
|
137
137
|
import { useRootStore } from "../../stores/root";
|
|
138
|
-
import {
|
|
139
|
-
useNuxtApp,
|
|
140
|
-
useI18n,
|
|
141
|
-
useLocalePath,
|
|
142
|
-
computed,
|
|
143
|
-
useRouter
|
|
144
|
-
} from "#imports";
|
|
138
|
+
import { useNuxtApp, useI18n, useLocalePath, computed } from "#imports";
|
|
145
139
|
const { $stores } = useNuxtApp();
|
|
146
140
|
const { locale } = useI18n();
|
|
147
141
|
const localePath = useLocalePath();
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<v-chip
|
|
11
11
|
v-for="(vintage, index2) in item.groups.vintage"
|
|
12
12
|
:key="index2"
|
|
13
|
-
|
|
13
|
+
size="small"
|
|
14
14
|
class="mt-3 mr-3"
|
|
15
15
|
variant="outlined"
|
|
16
16
|
tile
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
!['vintage', '__typename'].includes(key))
|
|
29
29
|
"
|
|
30
30
|
class="mt-3 mr-3"
|
|
31
|
-
|
|
31
|
+
size="small"
|
|
32
32
|
color="black"
|
|
33
33
|
style="background-color: white; color: black"
|
|
34
34
|
tile
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
v-if="value && index < 3"
|
|
46
46
|
class="mt-3 mr-3"
|
|
47
47
|
color="black"
|
|
48
|
-
|
|
48
|
+
size="small"
|
|
49
49
|
style="background-color: white; color: black"
|
|
50
50
|
tile
|
|
51
51
|
variant="outlined"
|
|
@@ -24,16 +24,36 @@
|
|
|
24
24
|
width="80px"
|
|
25
25
|
/>
|
|
26
26
|
</v-col>
|
|
27
|
-
<v-col align-self="
|
|
27
|
+
<v-col align-self="start" class="text-h6 dense px-2">
|
|
28
28
|
<v-skeleton-loader v-if="rootStore.loading" type="heading" />
|
|
29
29
|
<div v-else class="d-flex text-h5 align-center">
|
|
30
|
-
|
|
30
|
+
<span
|
|
31
|
+
v-html="
|
|
32
|
+
rootStore.search.length
|
|
33
|
+
? highlightAndTruncate(
|
|
34
|
+
300,
|
|
35
|
+
item.firstname + ' ' + item.lastname,
|
|
36
|
+
$rootStore.search.split(' '),
|
|
37
|
+
)
|
|
38
|
+
: item.firstname + ' ' + item.lastname
|
|
39
|
+
"
|
|
40
|
+
/>
|
|
31
41
|
<v-spacer />
|
|
32
42
|
<PeopleBadges :item="item" />
|
|
33
43
|
</div>
|
|
34
|
-
<div
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
<div
|
|
45
|
+
v-if="item.groups.vintage && item.groups.vintage[0].theme"
|
|
46
|
+
class="text-body-1 font-weight-light paragraph"
|
|
47
|
+
v-html="
|
|
48
|
+
rootStore.search.length
|
|
49
|
+
? highlightAndTruncate(
|
|
50
|
+
300,
|
|
51
|
+
item.groups.vintage[0].theme,
|
|
52
|
+
$rootStore.search.split(' '),
|
|
53
|
+
)
|
|
54
|
+
: item.groups.vintage[0].theme
|
|
55
|
+
"
|
|
56
|
+
/>
|
|
37
57
|
</v-col>
|
|
38
58
|
</v-row>
|
|
39
59
|
</template>
|
|
@@ -26,12 +26,14 @@
|
|
|
26
26
|
</v-col>
|
|
27
27
|
<v-col align-self="center" class="text-h5 dense pl-2">
|
|
28
28
|
<v-skeleton-loader v-if="rootStore.loading" type="heading" />
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
<span
|
|
30
|
+
v-else
|
|
31
|
+
v-html="
|
|
32
|
+
rootStore.search.length
|
|
33
|
+
? highlightAndTruncate(300, item.name, $rootStore.search.split(' '))
|
|
34
|
+
: item.name
|
|
35
|
+
"
|
|
36
|
+
/>
|
|
35
37
|
<v-skeleton-loader
|
|
36
38
|
v-if="rootStore.loading"
|
|
37
39
|
:type="
|
|
@@ -40,10 +42,12 @@
|
|
|
40
42
|
]
|
|
41
43
|
"
|
|
42
44
|
/>
|
|
45
|
+
<MiscMoleculesChipContainer :items="item.tags" size="small" />
|
|
43
46
|
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
+
<MDC
|
|
48
|
+
class="text-caption font-weight-light paragraph"
|
|
49
|
+
:value="`${highlightAndTruncate(150, item.summary, rootStore.search.split(' '))}`"
|
|
50
|
+
/>
|
|
47
51
|
</v-col>
|
|
48
52
|
</v-row>
|
|
49
53
|
</template>
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
$router.push(localePath('/activities/publications/' + item.slug[locale]))
|
|
8
8
|
"
|
|
9
9
|
>
|
|
10
|
-
<v-col v-if="mdAndUp"
|
|
10
|
+
<v-col v-if="mdAndUp" cols="1" class="align-center">
|
|
11
11
|
<MiscAtomsImageContainer
|
|
12
12
|
cover
|
|
13
13
|
:loading="$stores.people.loading"
|
|
@@ -19,54 +19,72 @@
|
|
|
19
19
|
width="80px"
|
|
20
20
|
/>
|
|
21
21
|
</v-col>
|
|
22
|
-
<v-col
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
v-if="rootStore.loading"
|
|
33
|
-
:type="
|
|
34
|
-
['chip', 'chip@2', 'chip@3', 'chip@4', 'chip@4', 'chip@4'][
|
|
35
|
-
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
|
|
36
|
-
]
|
|
37
|
-
"
|
|
38
|
-
/>
|
|
22
|
+
<v-col class="pl-2">
|
|
23
|
+
<div class="inline-flex flex-row flex-wrap">
|
|
24
|
+
<v-skeleton-loader
|
|
25
|
+
v-if="rootStore.loading"
|
|
26
|
+
:type="
|
|
27
|
+
['chip', 'chip@2', 'chip@3', 'chip@4', 'chip@4', 'chip@4'][
|
|
28
|
+
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
|
|
29
|
+
]
|
|
30
|
+
"
|
|
31
|
+
/>
|
|
39
32
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
33
|
+
<template v-else>
|
|
34
|
+
<v-chip
|
|
35
|
+
v-if="eventCategory"
|
|
36
|
+
class="ma-2"
|
|
37
|
+
variant="outlined"
|
|
38
|
+
size="small"
|
|
39
|
+
style="background-color: white; color: black"
|
|
40
|
+
>
|
|
41
|
+
{{ $t(eventCategory) }} </v-chip
|
|
42
|
+
><v-chip
|
|
43
|
+
v-if="eventType"
|
|
44
|
+
variant="outlined"
|
|
45
|
+
size="small"
|
|
46
|
+
class="mx-2"
|
|
47
|
+
style="background-color: white; color: black"
|
|
48
|
+
>
|
|
49
|
+
{{ $t(eventType) }}
|
|
50
|
+
</v-chip>
|
|
51
|
+
<MiscMoleculesChipContainer
|
|
52
|
+
v-if="item.tags && item.tags.length"
|
|
53
|
+
:items="item.tags"
|
|
54
|
+
size="small"
|
|
55
|
+
/>
|
|
56
|
+
</template>
|
|
57
|
+
<v-skeleton-loader v-if="rootStore.loading" type="heading" />
|
|
58
|
+
<span
|
|
59
|
+
v-else
|
|
60
|
+
class="text-h5 dense paragraph"
|
|
61
|
+
v-html="
|
|
62
|
+
rootStore.search.length
|
|
63
|
+
? highlightAndTruncate(
|
|
64
|
+
300,
|
|
65
|
+
item.name,
|
|
66
|
+
$rootStore.search.split(' '),
|
|
67
|
+
)
|
|
68
|
+
: item.name
|
|
69
|
+
"
|
|
70
|
+
/>
|
|
71
|
+
<MDC
|
|
72
|
+
class="text-body-1 font-weight-light paragraph"
|
|
73
|
+
:value="`${highlightAndTruncate(150, item.summary, rootStore.search.split(' '))}`"
|
|
74
|
+
/>
|
|
75
|
+
</div> </v-col
|
|
76
|
+
></v-row>
|
|
59
77
|
</template>
|
|
60
78
|
|
|
61
79
|
<script setup>
|
|
62
80
|
import { useDisplay } from "vuetify";
|
|
63
81
|
import { useRootStore } from "../../stores/root";
|
|
64
82
|
import { computed, useNuxtApp, useI18n, useLocalePath } from "#imports";
|
|
83
|
+
const rootStore = useRootStore();
|
|
65
84
|
const { $stores } = useNuxtApp();
|
|
66
85
|
const { name, mdAndUp } = useDisplay();
|
|
67
86
|
const localePath = useLocalePath();
|
|
68
87
|
const { locale } = useI18n();
|
|
69
|
-
const rootStore = useRootStore();
|
|
70
88
|
const props = defineProps({
|
|
71
89
|
item: {
|
|
72
90
|
type: Object,
|
|
@@ -10,3 +10,4 @@ export declare const getDetailedFormatedDate: (dateStr: string, locale: string)
|
|
|
10
10
|
export declare const capitalize: (value: string, multiple?: boolean) => string;
|
|
11
11
|
export declare const slugify: (str: string) => string;
|
|
12
12
|
export declare const formatDateValue: (date: string | Date, locale: string) => string;
|
|
13
|
+
export declare const highlightAndTruncate: (stop: number, text: string, query: string[]) => string;
|
|
@@ -46,3 +46,47 @@ export const formatDateValue = (date, locale) => {
|
|
|
46
46
|
const formattedDate = new Date(date);
|
|
47
47
|
return formattedDate.toLocaleDateString(locale);
|
|
48
48
|
};
|
|
49
|
+
export const highlightAndTruncate = (stop, text, query) => {
|
|
50
|
+
console.log("highlightAndTruncate", stop, text, query);
|
|
51
|
+
try {
|
|
52
|
+
if (query?.length && query[0]?.length) {
|
|
53
|
+
if (text.length > stop) {
|
|
54
|
+
console.log("text bigger than stop, truncate", text.length, stop);
|
|
55
|
+
const indexes = query.map((element) => text.indexOf(element)).filter((index) => index !== -1);
|
|
56
|
+
if (indexes.length) {
|
|
57
|
+
const firstIndex = Math.min(...indexes);
|
|
58
|
+
if (firstIndex > stop + Math.max(...query.map((element) => element.length))) {
|
|
59
|
+
if (text.length - firstIndex < stop) {
|
|
60
|
+
text = "..." + text.substring(text.length - stop, text.length);
|
|
61
|
+
} else {
|
|
62
|
+
text = "..." + text.substring(firstIndex - 5, stop - 5 + firstIndex);
|
|
63
|
+
}
|
|
64
|
+
} else {
|
|
65
|
+
text = text.slice(0, stop) + "...";
|
|
66
|
+
}
|
|
67
|
+
} else {
|
|
68
|
+
text = text.slice(0, stop) + "...";
|
|
69
|
+
}
|
|
70
|
+
query.forEach((element) => {
|
|
71
|
+
const check = new RegExp(element, "gi");
|
|
72
|
+
text = text.replace(check, function(matchedText) {
|
|
73
|
+
return '<strong style="color: white;background-color: black;">' + matchedText + "</strong>";
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
query.forEach((element) => {
|
|
78
|
+
const check = new RegExp(element, "gi");
|
|
79
|
+
text = text.replace(check, function(matchedText) {
|
|
80
|
+
return '<strong style="color: white;background-color: black;">' + matchedText + "</strong>";
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
text = text.slice(0, stop) + "...";
|
|
86
|
+
}
|
|
87
|
+
return text;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.log(error);
|
|
90
|
+
return text;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
@@ -53,6 +53,7 @@
|
|
|
53
53
|
"label": "Category",
|
|
54
54
|
"COLLOQUIUM": "Colloquium",
|
|
55
55
|
"CONFERENCE": "Conference",
|
|
56
|
+
"CONFERENCE_CYCLE": "Conference cycle",
|
|
56
57
|
"FELLOW_PRESENTATION": "Fellow's presentation",
|
|
57
58
|
"FORUM": "Forum",
|
|
58
59
|
"LECTURE": "Lecture",
|
|
@@ -126,8 +127,8 @@
|
|
|
126
127
|
"ONGOING": "Ongoing",
|
|
127
128
|
"PLANNED": "Planned"
|
|
128
129
|
},
|
|
129
|
-
"
|
|
130
|
-
"label": "
|
|
130
|
+
"disciplines": {
|
|
131
|
+
"label": "Disciplines"
|
|
131
132
|
}
|
|
132
133
|
},
|
|
133
134
|
"news": {
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"label": "Catégorie",
|
|
52
52
|
"COLLOQUIUM": "Colloque",
|
|
53
53
|
"CONFERENCE": "Conférence",
|
|
54
|
+
"CONFERENCE_CYCLE": "Cycle de conférences",
|
|
54
55
|
"FELLOW_PRESENTATION": "Présentation de Fellow",
|
|
55
56
|
"FORUM": "Forum",
|
|
56
57
|
"LECTURE": "Conférence",
|
|
@@ -95,7 +96,7 @@
|
|
|
95
96
|
"label": "Passé"
|
|
96
97
|
},
|
|
97
98
|
"disciplines": {
|
|
98
|
-
"label": "
|
|
99
|
+
"label": "Disciplines"
|
|
99
100
|
},
|
|
100
101
|
"status": {
|
|
101
102
|
"label": "Statut",
|
|
@@ -185,7 +186,7 @@
|
|
|
185
186
|
"label": "Année"
|
|
186
187
|
},
|
|
187
188
|
"disciplines": {
|
|
188
|
-
"label": "
|
|
189
|
+
"label": "Disciplines"
|
|
189
190
|
}
|
|
190
191
|
},
|
|
191
192
|
"projects": {
|