@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@paris-ias/list",
3
3
  "configKey": "list",
4
- "version": "1.0.115",
4
+ "version": "1.0.116",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.0",
7
7
  "unbuild": "3.5.0"
@@ -27,21 +27,39 @@
27
27
  />
28
28
  </v-col>
29
29
 
30
- <v-col align-self="top" class="pl-2">
30
+ <v-col align-self="start" class="pl-2">
31
31
  <v-chip
32
32
  class="mr-3"
33
33
  color="black"
34
- :size="mdAndUp ? 'default' : 'small'"
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 class="text-h5 dense paragraph">
43
- {{ item.name }}
44
- </div>
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 { mdAndUp } = useDisplay();
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
- {{ item.name }}
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 $rootStore.results[type].items"
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, $rootStore } = useNuxtApp();
15
- console.log("rootStore: ", $rootStore);
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' : false"
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' ? null : router.push(localePath('/search'))"
17
- @click:append="type === 'all' ? null : router.push(localePath('/search'))"
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:#f5f5f5!important}
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
- <div class="d-flex flex-row flex-wrap" v-bind="attrs">
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
- :size="
6
- ['small', 'small', 'small', 'default', 'large'][
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
- </div>
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,
@@ -11,9 +11,6 @@
11
11
  </template>
12
12
 
13
13
  <script setup>
14
- import { useRootStore } from "../../../stores/root";
15
- import { capitalize } from "../../../composables/useUtils";
16
- const rootStore = useRootStore();
17
14
  const props = defineProps({
18
15
  type: {
19
16
  type: String,
@@ -17,7 +17,7 @@
17
17
  width="80px"
18
18
  />
19
19
  </v-col>
20
- <v-col align-self="top" class="text-h5 dense px-2 paragraph">
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
- :size="mdAndUp ? 'default' : 'small'"
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
- {{ item.name }}
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
- :size="mdAndUp ? 'default' : 'small'"
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
- :size="mdAndUp ? 'default' : 'small'"
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
- :size="mdAndUp ? 'default' : 'small'"
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="top" class="text-h6 dense px-2">
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
- {{ item.firstname + " " + item.lastname }}
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 class="text-body-1 font-weight-light paragraph">
35
- {{ item.groups.vintage ? item.groups.vintage[0].theme : "" }}
36
- </div>
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
- <template v-else>
30
- {{ item.name }}
31
- </template>
32
- </v-col>
33
-
34
- <v-col align-self="center" cols="5" class="dense">
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
- <template v-else>
45
- <MiscMoleculesChipContainer :items="item.tags" size="small" />
46
- </template>
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" align-self="center" cols="1">
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 align-self="center" class="text-h5 dense pl-2">
23
- <v-skeleton-loader v-if="rootStore.loading" type="heading" />
24
- <template v-else>
25
- {{ item.name }}
26
- </template>
27
- <MDC class="text-caption" :value="item.summary" />
28
- </v-col>
29
-
30
- <v-col align-self="center">
31
- <v-skeleton-loader
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
- <template v-else>
41
- <v-chip
42
- v-if="eventCategory"
43
- class="ma-2"
44
- style="background-color: white; color: black"
45
- >
46
- {{ $t(eventCategory) }} </v-chip
47
- ><v-chip
48
- v-if="eventType"
49
- c
50
- class="ma-2"
51
- style="background-color: white; color: black"
52
- >
53
- {{ $t(eventType) }}
54
- </v-chip>
55
- <MiscMoleculesChipContainer :items="item.tags" size="small" />
56
- </template>
57
- </v-col>
58
- </v-row>
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
- "discipline": {
130
- "label": "Discipline"
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": "Discipline"
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": "Discipline"
189
+ "label": "Disciplines"
189
190
  }
190
191
  },
191
192
  "projects": {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "license": "AGPL-3.0-only",
3
3
  "main": "./dist/module.mjs",
4
- "version": "1.0.115",
4
+ "version": "1.0.116",
5
5
  "name": "@paris-ias/list",
6
6
  "repository": {
7
7
  "url": "git+https://github.com/IEA-Paris/list.git",