@paris-ias/list 1.0.112 → 1.0.113

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.
Files changed (151) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/list/molecules/Pagination.vue +2 -0
  3. package/dist/runtime/components/list/organisms/List.vue +11 -1
  4. package/dist/runtime/runtime/components/actions/ExpandedItem.vue +14 -0
  5. package/dist/runtime/runtime/components/actions/RowsItem.vue +12 -0
  6. package/dist/runtime/runtime/components/actions/View.vue +20 -0
  7. package/dist/runtime/runtime/components/affiliations/ExpandedItem.vue +14 -0
  8. package/dist/runtime/runtime/components/affiliations/RowsItem.vue +12 -0
  9. package/dist/runtime/runtime/components/affiliations/View.vue +20 -0
  10. package/dist/runtime/runtime/components/apps/ExpandedItem.vue +14 -0
  11. package/dist/runtime/runtime/components/apps/RowsItem.vue +12 -0
  12. package/dist/runtime/runtime/components/apps/View.vue +20 -0
  13. package/dist/runtime/runtime/components/disciplines/ExpandedItem.vue +14 -0
  14. package/dist/runtime/runtime/components/disciplines/RowsItem.vue +12 -0
  15. package/dist/runtime/runtime/components/disciplines/View.vue +20 -0
  16. package/dist/runtime/runtime/components/events/Badges.vue +73 -0
  17. package/dist/runtime/runtime/components/events/DateTimePlace.vue +77 -0
  18. package/dist/runtime/runtime/components/events/DenseItem.vue +60 -0
  19. package/dist/runtime/runtime/components/events/ExpandedItem.vue +9 -0
  20. package/dist/runtime/runtime/components/events/RegisterModal.vue +50 -0
  21. package/dist/runtime/runtime/components/events/RelatedItem.vue +44 -0
  22. package/dist/runtime/runtime/components/events/RowsItem.vue +118 -0
  23. package/dist/runtime/runtime/components/events/SlidingItem.vue +63 -0
  24. package/dist/runtime/runtime/components/events/View.vue +333 -0
  25. package/dist/runtime/runtime/components/fellowships/Badges.vue +47 -0
  26. package/dist/runtime/runtime/components/fellowships/DenseItem.vue +42 -0
  27. package/dist/runtime/runtime/components/fellowships/ExpandedItem.vue +7 -0
  28. package/dist/runtime/runtime/components/fellowships/RegisterModal.vue +41 -0
  29. package/dist/runtime/runtime/components/fellowships/RowsItem.vue +58 -0
  30. package/dist/runtime/runtime/components/fellowships/View.vue +203 -0
  31. package/dist/runtime/runtime/components/files/ExpandedItem.vue +14 -0
  32. package/dist/runtime/runtime/components/files/RowsItem.vue +12 -0
  33. package/dist/runtime/runtime/components/files/View.vue +20 -0
  34. package/dist/runtime/runtime/components/list/atoms/FiltersMenu.vue +44 -0
  35. package/dist/runtime/runtime/components/list/atoms/ResetButton.vue +33 -0
  36. package/dist/runtime/runtime/components/list/atoms/ResultsList.vue +27 -0
  37. package/dist/runtime/runtime/components/list/atoms/SearchInput.vue +59 -0
  38. package/dist/runtime/runtime/components/list/atoms/SearchItem.vue +65 -0
  39. package/dist/runtime/runtime/components/list/atoms/SearchString.vue +160 -0
  40. package/dist/runtime/runtime/components/list/atoms/SortMenu.vue +80 -0
  41. package/dist/runtime/runtime/components/list/atoms/ViewMenu.vue +63 -0
  42. package/dist/runtime/runtime/components/list/atoms/itemsPerPage.vue +33 -0
  43. package/dist/runtime/runtime/components/list/inputs/AutoComplete.vue +24 -0
  44. package/dist/runtime/runtime/components/list/inputs/BooleanSwitch.vue +20 -0
  45. package/dist/runtime/runtime/components/list/inputs/Checkbox.vue +20 -0
  46. package/dist/runtime/runtime/components/list/inputs/Select.vue +28 -0
  47. package/dist/runtime/runtime/components/list/molecules/Filters.vue +98 -0
  48. package/dist/runtime/runtime/components/list/molecules/GlobalSearchInput.vue +131 -0
  49. package/dist/runtime/runtime/components/list/molecules/Header.vue +51 -0
  50. package/dist/runtime/runtime/components/list/molecules/Pagination.vue +194 -0
  51. package/dist/runtime/runtime/components/list/molecules/ResultsContainer.vue +78 -0
  52. package/dist/runtime/runtime/components/list/organisms/List.vue +110 -0
  53. package/dist/runtime/runtime/components/list/organisms/Results.vue +72 -0
  54. package/dist/runtime/runtime/components/list/organisms/Slider.vue +180 -0
  55. package/dist/runtime/runtime/components/list/views/Dense.vue +12 -0
  56. package/dist/runtime/runtime/components/list/views/Expanded.vue +10 -0
  57. package/dist/runtime/runtime/components/list/views/Grid.vue +13 -0
  58. package/dist/runtime/runtime/components/list/views/Rows.vue +12 -0
  59. package/dist/runtime/runtime/components/list/views/Slider.vue +147 -0
  60. package/dist/runtime/runtime/components/list/views/Table.vue +13 -0
  61. package/dist/runtime/runtime/components/mailing/ExpandedItem.vue +14 -0
  62. package/dist/runtime/runtime/components/mailing/RowsItem.vue +12 -0
  63. package/dist/runtime/runtime/components/mailing/View.vue +20 -0
  64. package/dist/runtime/runtime/components/misc/atoms/DateStamp.vue +101 -0
  65. package/dist/runtime/runtime/components/misc/atoms/ImageContainer.vue +127 -0
  66. package/dist/runtime/runtime/components/misc/atoms/ShareMenu.vue +61 -0
  67. package/dist/runtime/runtime/components/misc/atoms/Socials.vue +120 -0
  68. package/dist/runtime/runtime/components/misc/molecules/ChipContainer.vue +31 -0
  69. package/dist/runtime/runtime/components/misc/molecules/Related.vue +28 -0
  70. package/dist/runtime/runtime/components/misc/molecules/RelatedItems.vue +27 -0
  71. package/dist/runtime/runtime/components/misc/molecules/SearchItem.vue +26 -0
  72. package/dist/runtime/runtime/components/news/DenseItem.vue +73 -0
  73. package/dist/runtime/runtime/components/news/ExpandedItem.vue +145 -0
  74. package/dist/runtime/runtime/components/news/Header.vue +7 -0
  75. package/dist/runtime/runtime/components/news/RelatedItem.vue +44 -0
  76. package/dist/runtime/runtime/components/news/RowsItem.vue +182 -0
  77. package/dist/runtime/runtime/components/news/View.vue +174 -0
  78. package/dist/runtime/runtime/components/people/DenseItem.vue +60 -0
  79. package/dist/runtime/runtime/components/people/ExpandedItem.vue +14 -0
  80. package/dist/runtime/runtime/components/people/GroupBadges.vue +54 -0
  81. package/dist/runtime/runtime/components/people/RelatedItem.vue +41 -0
  82. package/dist/runtime/runtime/components/people/RowsItem.vue +93 -0
  83. package/dist/runtime/runtime/components/people/View.vue +172 -0
  84. package/dist/runtime/runtime/components/projects/DenseItem.vue +77 -0
  85. package/dist/runtime/runtime/components/projects/ExpandedItem.vue +12 -0
  86. package/dist/runtime/runtime/components/projects/RelatedItem.vue +44 -0
  87. package/dist/runtime/runtime/components/projects/RowsItem.vue +103 -0
  88. package/dist/runtime/runtime/components/projects/View.vue +130 -0
  89. package/dist/runtime/runtime/components/publications/DenseItem.vue +89 -0
  90. package/dist/runtime/runtime/components/publications/RelatedItem.vue +44 -0
  91. package/dist/runtime/runtime/components/publications/RowsItem.vue +105 -0
  92. package/dist/runtime/runtime/components/publications/View.vue +132 -0
  93. package/dist/runtime/runtime/components/tags/ExpandedItem.vue +14 -0
  94. package/dist/runtime/runtime/components/tags/RowsItem.vue +12 -0
  95. package/dist/runtime/runtime/components/tags/View.vue +20 -0
  96. package/dist/runtime/runtime/components/users/ExpandedItem.vue +14 -0
  97. package/dist/runtime/runtime/components/users/RowsItem.vue +12 -0
  98. package/dist/runtime/runtime/components/users/View.vue +20 -0
  99. package/dist/runtime/runtime/composables/useFetchItem.d.ts +6 -0
  100. package/dist/runtime/runtime/composables/useFetchItem.js +49 -0
  101. package/dist/runtime/runtime/composables/useIcons.d.ts +1 -0
  102. package/dist/runtime/runtime/composables/useIcons.js +30 -0
  103. package/dist/runtime/runtime/composables/useUtils.d.ts +12 -0
  104. package/dist/runtime/runtime/composables/useUtils.js +48 -0
  105. package/dist/runtime/runtime/graphql/buildFiltersValues.gql +35 -0
  106. package/dist/runtime/runtime/graphql/item/action.gql +22 -0
  107. package/dist/runtime/runtime/graphql/item/affiliations.gql +37 -0
  108. package/dist/runtime/runtime/graphql/item/apps.gql +34 -0
  109. package/dist/runtime/runtime/graphql/item/disciplines.gql +17 -0
  110. package/dist/runtime/runtime/graphql/item/events.gql +120 -0
  111. package/dist/runtime/runtime/graphql/item/fellowships.gql +164 -0
  112. package/dist/runtime/runtime/graphql/item/files.gql +25 -0
  113. package/dist/runtime/runtime/graphql/item/mailing.gql +10 -0
  114. package/dist/runtime/runtime/graphql/item/news.gql +129 -0
  115. package/dist/runtime/runtime/graphql/item/people.gql +174 -0
  116. package/dist/runtime/runtime/graphql/item/projects.gql +171 -0
  117. package/dist/runtime/runtime/graphql/item/publications.gql +169 -0
  118. package/dist/runtime/runtime/graphql/item/tags.gql +13 -0
  119. package/dist/runtime/runtime/graphql/item/users.gql +14 -0
  120. package/dist/runtime/runtime/graphql/list/action.gql +31 -0
  121. package/dist/runtime/runtime/graphql/list/affiliations.gql +42 -0
  122. package/dist/runtime/runtime/graphql/list/apps.gql +42 -0
  123. package/dist/runtime/runtime/graphql/list/disciplines.gql +22 -0
  124. package/dist/runtime/runtime/graphql/list/events.gql +44 -0
  125. package/dist/runtime/runtime/graphql/list/fellowships.gql +53 -0
  126. package/dist/runtime/runtime/graphql/list/files.gql +37 -0
  127. package/dist/runtime/runtime/graphql/list/mailing.gql +22 -0
  128. package/dist/runtime/runtime/graphql/list/news.gql +40 -0
  129. package/dist/runtime/runtime/graphql/list/people.gql +50 -0
  130. package/dist/runtime/runtime/graphql/list/projects.gql +37 -0
  131. package/dist/runtime/runtime/graphql/list/publications.gql +38 -0
  132. package/dist/runtime/runtime/graphql/list/search.gql +161 -0
  133. package/dist/runtime/runtime/graphql/list/tags.gql +22 -0
  134. package/dist/runtime/runtime/graphql/list/users.gql +38 -0
  135. package/dist/runtime/runtime/graphql/login.gql +0 -0
  136. package/dist/runtime/runtime/plugins/pinia.d.ts +2 -0
  137. package/dist/runtime/runtime/plugins/pinia.js +134 -0
  138. package/dist/runtime/runtime/plugins/vuetify.d.ts +2 -0
  139. package/dist/runtime/runtime/plugins/vuetify.js +21 -0
  140. package/dist/runtime/runtime/public/default.png +0 -0
  141. package/dist/runtime/runtime/public/filters.json +72 -0
  142. package/dist/runtime/runtime/server/tsconfig.json +3 -0
  143. package/dist/runtime/runtime/stores/factory.d.ts +25 -0
  144. package/dist/runtime/runtime/stores/factory.js +19 -0
  145. package/dist/runtime/runtime/stores/root.d.ts +60 -0
  146. package/dist/runtime/runtime/stores/root.js +315 -0
  147. package/dist/runtime/runtime/translations/en.json +350 -0
  148. package/dist/runtime/runtime/translations/fr.json +349 -0
  149. package/dist/runtime/runtime/types/imports.d.ts +13 -0
  150. package/dist/runtime/runtime/types/stores.d.ts +11 -0
  151. package/package.json +1 -1
@@ -0,0 +1,160 @@
1
+ <template>
2
+ <div class="mt-4 font-weight-light">
3
+ <template
4
+ v-if="
5
+ (!$stores[type].search || $stores[type].search.length === 0) &&
6
+ $stores[type].filtersCount === 0
7
+ "
8
+ >
9
+ {{
10
+ feminine
11
+ ? $t(
12
+ "list.0-items-found-f",
13
+ [
14
+ $stores[type].total,
15
+ $t("items." + props.type, $stores[type].total),
16
+ ],
17
+ $stores[type].total,
18
+ )
19
+ : $t(
20
+ "list.0-items-found",
21
+ [
22
+ $stores[type].total,
23
+ $t("items." + props.type, $stores[type].total),
24
+ ],
25
+ $stores[type].total,
26
+ )
27
+ }}
28
+ </template>
29
+ <!-- searching for "XXX" -->
30
+ <template
31
+ v-else-if="
32
+ !(!$stores[type].search || $stores[type].search.length === 0) &&
33
+ $stores[type].filtersCount === 0
34
+ "
35
+ >
36
+ {{
37
+ feminine
38
+ ? $t(
39
+ "list.0-items-found-searching-for-f",
40
+ [
41
+ $stores[type].total,
42
+ $t(
43
+ "items." + props.type,
44
+ $stores[type].total,
45
+ $stores[type].total,
46
+ ),
47
+ $stores[type].search,
48
+ ],
49
+ $stores[type].total,
50
+ )
51
+ : $t(
52
+ "list.0-items-found-searching-for",
53
+ [
54
+ $stores[type].total,
55
+ $t(
56
+ "items." + props.type,
57
+ $stores[type].total,
58
+ $stores[type].total,
59
+ ),
60
+ $stores[type].search,
61
+ ],
62
+ $stores[type].total,
63
+ )
64
+ }}
65
+ </template>
66
+ <!-- with X filters -->
67
+ <template
68
+ v-else-if="
69
+ (!$stores[type].search || $stores[type].search.length === 0) &&
70
+ $stores[type].filtersCount > 0
71
+ "
72
+ >
73
+ {{
74
+ feminine
75
+ ? $t(
76
+ "list.0-items-found-with-1-filter-f",
77
+ [
78
+ $stores[type].total,
79
+ $t(
80
+ "items." + props.type,
81
+ $stores[type].total,
82
+ $stores[type].total,
83
+ ),
84
+ $stores[type].filtersCount,
85
+ $t("filters", $stores[type].filtersCount),
86
+ ],
87
+ $stores[type].total,
88
+ )
89
+ : $t(
90
+ "list.0-items-found-with-1-filter",
91
+ [
92
+ $stores[type].total,
93
+ $t("items." + type, $stores[type].total, $stores[type].total),
94
+ $stores[type].filtersCount,
95
+ $t("filters", $stores[type].filtersCount),
96
+ ],
97
+ $stores[type].total,
98
+ )
99
+ }}
100
+ </template>
101
+ <!-- searching for "XXX" with Y filters -->
102
+ <template
103
+ v-else-if="
104
+ $stores[type].search &&
105
+ $stores[type].search.length &&
106
+ $stores[type].filtersCount > 0
107
+ "
108
+ >
109
+ {{
110
+ feminine
111
+ ? $t(
112
+ "list.0-items-found-searching-for-with-1-filter-f",
113
+ [
114
+ $stores[type].total,
115
+ $t("items." + type, $stores[type].total),
116
+ $stores[type].search,
117
+ $stores[type].filtersCount,
118
+ $t("filters", $stores[type].filtersCount),
119
+ ],
120
+ $stores[type].total,
121
+ )
122
+ : $t(
123
+ "list.0-items-found-searching-for-with-1-filter",
124
+ [
125
+ $stores[type].total,
126
+ $t("items." + type, $stores[type].total),
127
+ $stores[type].search,
128
+ $stores[type].filtersCount,
129
+ $t("filters", $stores[type].filtersCount),
130
+ ],
131
+ $stores[type].total,
132
+ )
133
+ }}
134
+ </template>
135
+ <template v-if="$stores[type].numberOfPages > 1">
136
+ <!-- // Page X of Y -->
137
+ {{
138
+ $t("list.page-0-of-1", [
139
+ $stores[type].page || 1,
140
+ $stores[type].numberOfPages || 1,
141
+ ])
142
+ }}
143
+ </template>
144
+ <!-- X items per page -->
145
+ <!-- displayed by X -->
146
+ <!-- and sorted by X -->
147
+ </div>
148
+ </template>
149
+
150
+ <script setup>
151
+ import { useNuxtApp, ref } from "#imports";
152
+ const { $stores } = useNuxtApp();
153
+ const props = defineProps({
154
+ type: {
155
+ type: String,
156
+ required: true
157
+ }
158
+ });
159
+ const feminine = ref(["news", "publications", "people"].includes(props.type));
160
+ </script>
@@ -0,0 +1,80 @@
1
+ <template>
2
+ <v-menu>
3
+ <template #activator="{ props: menu }">
4
+ <v-tooltip location="top">
5
+ <template #activator="{ props: tooltip }">
6
+ <v-btn
7
+ x-large
8
+ outlined
9
+ tile
10
+ flat
11
+ icon
12
+ :class="{
13
+ 'mt-3': isXsDisplay,
14
+ }"
15
+ v-bind="mergeProps(menu, tooltip)"
16
+ >
17
+ <v-icon>mdi-{{ current?.icon || defaultSort?.icon }}</v-icon>
18
+ </v-btn>
19
+ </template>
20
+ <div
21
+ v-html="
22
+ $t('list.sort-mode') +
23
+ $t('list.' + current.text || defaultSort.text)
24
+ "
25
+ />
26
+ </v-tooltip>
27
+ </template>
28
+ <v-list density="compact">
29
+ <template v-for="(item, index) in items">
30
+ <v-list-item
31
+ v-if="item.text !== current.text"
32
+ :key="index"
33
+ @click="updateSort(item.value)"
34
+ >
35
+ <template #prepend>
36
+ <v-icon>mdi-{{ item.icon }}</v-icon>
37
+ </template>
38
+ <v-list-item-title>{{ $t("list." + item.text) }}</v-list-item-title>
39
+ </v-list-item>
40
+ </template>
41
+ </v-list>
42
+ </v-menu>
43
+ </template>
44
+
45
+ <script setup>
46
+ import { mergeProps } from "vue";
47
+ import { useDisplay } from "vuetify";
48
+ import { useRootStore } from "../../../stores/root";
49
+ import { useNuxtApp, computed, ref, useI18n } from "#imports";
50
+ const { $stores } = useNuxtApp();
51
+ const { xs: isXsDisplay } = useDisplay();
52
+ const { locale } = useI18n();
53
+ const rootStore = useRootStore();
54
+ const props = defineProps({
55
+ type: {
56
+ type: String,
57
+ default: "articles",
58
+ required: true
59
+ }
60
+ });
61
+ const items = ref($stores[props.type].sort);
62
+ const defaultSort = ref(
63
+ $stores[props.type].sort[Object.keys($stores[props.type].sort).find(
64
+ (item) => $stores[props.type].sort[item].default === true
65
+ )]
66
+ );
67
+ const current = computed(() => {
68
+ try {
69
+ return $stores[props.type].sort[Object.keys($stores[props.type].sort).find((item) => {
70
+ return $stores[props.type].sort[item].value[0] === $stores[props.type].sortBy[0] && $stores[props.type].sort[item].value[1] === $stores[props.type].sortDesc[0];
71
+ })];
72
+ } catch (error) {
73
+ console.log("error: ", error);
74
+ return items[Object.keys(items).find((item) => item.default)];
75
+ }
76
+ });
77
+ const updateSort = async (value) => {
78
+ await rootStore.updateSort({ value, type: props.type, lang: locale.value });
79
+ };
80
+ </script>
@@ -0,0 +1,63 @@
1
+ <template>
2
+ <v-menu>
3
+ <template #activator="{ props: menu }">
4
+ <v-tooltip location="top">
5
+ <template #activator="{ props: tooltip }">
6
+ <v-btn
7
+ x-large
8
+ tile
9
+ flat
10
+ :icon="'mdi-' + current?.icon || defaultView?.icon"
11
+ :class="{
12
+ 'mt-3': isXsDisplay,
13
+ }"
14
+ v-bind="mergeProps(menu, tooltip)"
15
+ />
16
+ </template>
17
+ <div
18
+ v-html="
19
+ $t('list.view-mode') +
20
+ $t('list.' + current.name || defaultView.name)
21
+ "
22
+ />
23
+ </v-tooltip>
24
+ </template>
25
+ <v-list density="compact">
26
+ <v-list-item
27
+ v-for="(value, key, index) in items"
28
+ :key="index"
29
+ @click="updateView(value.name || key)"
30
+ >
31
+ <template #prepend>
32
+ <v-icon>mdi-{{ value.icon }}</v-icon>
33
+ </template>
34
+ <v-list-item-title>
35
+ {{ $t("list." + (value.name || key)) }}
36
+ </v-list-item-title>
37
+ </v-list-item>
38
+ </v-list>
39
+ </v-menu>
40
+ </template>
41
+
42
+ <script setup>
43
+ import { mergeProps } from "vue";
44
+ import { useDisplay } from "vuetify";
45
+ import { useRootStore } from "../../../stores/root";
46
+ import { useNuxtApp, ref, useI18n } from "#imports";
47
+ const { locale } = useI18n();
48
+ const { $stores } = useNuxtApp();
49
+ const props = defineProps({
50
+ type: {
51
+ type: String,
52
+ default: "articles",
53
+ required: true
54
+ }
55
+ });
56
+ const { xs: isXsDisplay } = useDisplay();
57
+ const rootStore = useRootStore();
58
+ const items = ref($stores[props.type].views);
59
+ const current = ref($stores[props.type].view);
60
+ const updateView = async (value) => {
61
+ await rootStore.updateView({ value, type: props.type, lang: locale.value });
62
+ };
63
+ </script>
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="perpage-select" :class="smAndDown ? 'text-center' : ''">
3
+ <span class="grey--text pr-3" :class="{ 'ml-6': !scrolled }">{{
4
+ $t("items-per-page")
5
+ }}</span>
6
+ </div>
7
+ <v-select
8
+ v-model="itemsPerPage"
9
+ class="perPageSelect"
10
+ density="compact"
11
+ variant="outlined"
12
+ :items="itemsPerPageArray"
13
+ hide-details
14
+ />
15
+ </template>
16
+
17
+ <script setup>
18
+ import { useNuxtApp } from "#imports";
19
+ import { useDisplay } from "vuetify";
20
+ import { computed, ref } from "vue";
21
+ const { smAndDown } = useDisplay();
22
+ const { $stores } = useNuxtApp();
23
+ const props = defineProps({
24
+ type: {
25
+ type: String,
26
+ required: false,
27
+ default: ""
28
+ }
29
+ });
30
+ const itemsPerPage = ref($stores[props.type].itemsPerPage);
31
+ const itemsPerPageArray = computed(() => $stores[props.type].itemsPerPageArray);
32
+ const scrolled = computed(() => $stores.scrolled);
33
+ </script>
@@ -0,0 +1,24 @@
1
+ <template>
2
+ <v-autocomplete
3
+ v-model="val"
4
+ :items="props.items"
5
+ :multiple="$stores[type].filters[name]?.multiple || false"
6
+ />
7
+ </template>
8
+
9
+ <script setup>
10
+ import { useRootStore } from "../../../stores/root";
11
+ import { useNuxtApp, computed, useI18n } from "#imports";
12
+ const { locale } = useI18n();
13
+ const rootStore = useRootStore();
14
+ const { $stores } = useNuxtApp();
15
+ const props = defineProps(["type", "items", "name"]);
16
+ const val = computed({
17
+ get() {
18
+ return $stores[props.type].filters[props.name]?.value || [];
19
+ },
20
+ set(value) {
21
+ return rootStore.updateFilter(props.name, value, props.type, locale.value);
22
+ }
23
+ });
24
+ </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <v-switch v-model="val" />
3
+ </template>
4
+
5
+ <script setup>
6
+ import { useRootStore } from "../../../stores/root";
7
+ import { useNuxtApp, computed, useI18n } from "#imports";
8
+ const { locale } = useI18n();
9
+ const rootStore = useRootStore();
10
+ const props = defineProps(["type", "items", "name"]);
11
+ const { $stores } = useNuxtApp();
12
+ const val = computed({
13
+ get() {
14
+ return $stores[props.type].filters[props.name]?.value;
15
+ },
16
+ set(value) {
17
+ rootStore.updateFilter(props.name, value, props.type, locale.value);
18
+ }
19
+ });
20
+ </script>
@@ -0,0 +1,20 @@
1
+ <template>
2
+ <v-checkbox v-model="val" />
3
+ </template>
4
+
5
+ <script setup>
6
+ import { useRootStore } from "../../../stores/root";
7
+ import { useNuxtApp, computed, useI18n } from "#imports";
8
+ const { locale } = useI18n();
9
+ const rootStore = useRootStore();
10
+ const props = defineProps(["type", "items", "name"]);
11
+ const { $stores } = useNuxtApp();
12
+ const val = computed({
13
+ get() {
14
+ return $stores[props.type].filters[props.name]?.value;
15
+ },
16
+ set(value) {
17
+ rootStore.updateFilter(props.name, value, props.type, locale.value);
18
+ }
19
+ });
20
+ </script>
@@ -0,0 +1,28 @@
1
+ <template>
2
+ <v-select
3
+ v-model="val"
4
+ :items="props.items"
5
+ :multiple="$stores[type].filters[name]?.multiple || false"
6
+ />
7
+ </template>
8
+
9
+ <script setup>
10
+ import { useRootStore } from "../../../stores/root";
11
+ import { useNuxtApp, computed, useI18n } from "#imports";
12
+ const { locale } = useI18n();
13
+ const rootStore = useRootStore();
14
+ const { $stores } = useNuxtApp();
15
+ const props = defineProps(["type", "items", "name"]);
16
+ const val = computed({
17
+ get() {
18
+ console.log(
19
+ "$stores[props.type].filters[props.name]?.value: ",
20
+ $stores[props.type].filters[props.name]?.value
21
+ );
22
+ return $stores[props.type].filters[props.name]?.value || [];
23
+ },
24
+ set(value) {
25
+ rootStore.updateFilter(props.name, value, props.type, locale.value || "en");
26
+ }
27
+ });
28
+ </script>
@@ -0,0 +1,98 @@
1
+ <template>
2
+ <v-row>
3
+ <template v-for="filterItem in Object.keys($stores[type].filters)">
4
+ <v-col
5
+ v-if="computeVisibility(filterItem)"
6
+ :key="type + filterItem"
7
+ cols="12"
8
+ sm="6"
9
+ md="4"
10
+ >
11
+ <component
12
+ :is="ComponentName(filterItem)"
13
+ tile
14
+ :name="filterItem"
15
+ hide-details
16
+ :filter="true"
17
+ :dense="smAndDown"
18
+ :items="getItems(filterItem)"
19
+ clearable
20
+ :label="$t('list.filters.' + type + '.' + filterItem + '.label')"
21
+ min-height="56"
22
+ variant="outlined"
23
+ :loading="$stores[type].loading"
24
+ :type="type"
25
+ color="black"
26
+ style="min-width: 150px"
27
+ class="transition-swing pb-1"
28
+ />
29
+ <!-- <template
30
+ v-else
31
+ v-for="filterItem in Object.keys(rootStore[type].list.filters).slice()"
32
+ >
33
+ <div v-if="computeVisibility(filterItem)">
34
+ {{ filterItem }}
35
+ </div>
36
+ </template> -->
37
+ </v-col>
38
+ </template>
39
+ </v-row>
40
+ </template>
41
+
42
+ <script setup>
43
+ import { useDisplay } from "vuetify";
44
+ import { useRootStore } from "../../../stores/root";
45
+ import { capitalize } from "../../../composables/useUtils";
46
+ import { useNuxtApp, onMounted, resolveComponent, useI18n } from "#imports";
47
+ const { smAndDown } = useDisplay();
48
+ const i18n = useI18n();
49
+ const { locale, messages } = useI18n();
50
+ const { $stores, $filters } = useNuxtApp();
51
+ const rootStore = useRootStore();
52
+ const props = defineProps(["type", "expanded"]);
53
+ const ComponentName = (name) => {
54
+ return resolveComponent(
55
+ "ListInputs" + capitalize($stores[props.type].filters[name].type)
56
+ );
57
+ };
58
+ const getItems = (name) => {
59
+ if ($stores[props.type].filters[name].type === "Checkbox") {
60
+ return [];
61
+ }
62
+ if ($filters?.[props.type]?.[name]) {
63
+ console.log("filters found for ", name, $filters[props.type][name]);
64
+ return $filters[props.type][name].filter((key) => key !== "label").map((item) => ({
65
+ title: i18n.t(
66
+ props.type === "people" && name === "vintage" ? item : `list.filters.${props.type}.${name}.${item}`
67
+ ),
68
+ value: item
69
+ }));
70
+ }
71
+ if (messages.value[locale.value].list.filters[props.type][name] === void 0) {
72
+ console.log("name not found, no item for this filmter: ", name);
73
+ return [];
74
+ }
75
+ return Object.keys(
76
+ messages.value[locale.value].list.filters[props.type][name]
77
+ ).filter((key) => key !== "label").map((item) => ({
78
+ title: i18n.t(`list.filters.${props.type}.${name}.${item}`),
79
+ value: item
80
+ }));
81
+ };
82
+ onMounted(() => {
83
+ rootStore.loadRouteQuery(props.type);
84
+ });
85
+ const computeVisibility = (filterItem) => {
86
+ return (
87
+ // if anything is set in the visibility key
88
+ !$stores[props.type].filters[filterItem].visibility || $stores[props.type].filters[filterItem].visibility?.default || $stores[props.type].filters[filterItem].visibility?.switchIf.find(
89
+ // for each of the rules set in the switchIf key
90
+ (rule) => {
91
+ return Object.keys(rule).find((value, index, obj) => {
92
+ return $stores[props.type].filters[value].multiple ? $stores[props.type].filters[value]?.value && $stores[props.type].filters[value]?.value.includes(rule[value]) : $stores[props.type].filters[value]?.value === rule[value];
93
+ });
94
+ }
95
+ )
96
+ );
97
+ };
98
+ </script>
@@ -0,0 +1,131 @@
1
+ <template>
2
+ <div class="d-flex flex-grow-1 flex-column">
3
+ <div class="d-flex align-center">
4
+ <v-text-field
5
+ v-model.trim="search"
6
+ :placeholder="$t('list.search-type', [$t('items.' + type, 2)])"
7
+ prepend-inner-icon="mdi-magnify"
8
+ single-line
9
+ class="transition-swing flex-grow-1"
10
+ variant="outlined"
11
+ hide-details
12
+ clearable
13
+ tile
14
+ type="search"
15
+ :loading="rootStore.loading"
16
+ >
17
+ <!-- :loading="$nuxt.loading || $store.state.loading" :class="{ 'mt-3':
18
+ $store.state.scrolled }" -->
19
+ <template v-if="!search" #label>
20
+ <div class="searchLabel">
21
+ {{
22
+ type === "all"
23
+ ? $t("search")
24
+ : $t("list.search-type", [$t("items." + type, 2)])
25
+ }}
26
+ </div>
27
+ </template>
28
+ </v-text-field>
29
+
30
+ <v-menu
31
+ v-model="filterMenuOpen"
32
+ :close-on-content-click="false"
33
+ location="bottom end"
34
+ offset="4"
35
+ >
36
+ <template #activator="{ props: menuProps }">
37
+ <v-btn
38
+ v-bind="menuProps"
39
+ :rounded="0"
40
+ variant="outlined"
41
+ size="large"
42
+ height="56"
43
+ >
44
+ <v-icon>mdi-filter</v-icon>
45
+ <v-icon class="ml-1" size="small">
46
+ {{ filterMenuOpen ? "mdi-chevron-up" : "mdi-chevron-down" }}
47
+ </v-icon>
48
+ </v-btn>
49
+ </template>
50
+
51
+ <v-card min-width="200">
52
+ <v-list density="compact">
53
+ <v-list-item
54
+ v-for="option in filterOptions"
55
+ :key="option.value"
56
+ @click="toggleFilter(option)"
57
+ >
58
+ <template #prepend>
59
+ <v-checkbox
60
+ hide-details
61
+ :model-value="categories.includes(option.value)"
62
+ @update:model-value="toggleFilter(option)"
63
+ />
64
+ </template>
65
+ <v-list-item-title>{{ option.label }}</v-list-item-title>
66
+ </v-list-item>
67
+ </v-list>
68
+ </v-card>
69
+ </v-menu>
70
+ </div>
71
+ </div>
72
+ </template>
73
+
74
+ <script setup>
75
+ import { useDebounceFn } from "@vueuse/core";
76
+ import { useRootStore } from "../../../stores/root";
77
+ import { computed, useI18n, ref } from "#imports";
78
+ const { locale, t } = useI18n();
79
+ const rootStore = useRootStore();
80
+ const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
81
+ const emit = defineEmits(["filter-change"]);
82
+ const props = defineProps({
83
+ type: {
84
+ type: String,
85
+ required: true
86
+ },
87
+ loading: {
88
+ type: Boolean,
89
+ default: false
90
+ },
91
+ categories: {
92
+ type: Array,
93
+ default: () => []
94
+ }
95
+ });
96
+ const filterMenuOpen = ref(false);
97
+ const filterOptions = [
98
+ { value: "people", label: capitalize(t("items.people", 2)) },
99
+ { value: "events", label: capitalize(t("items.events", 2)) },
100
+ { value: "news", label: capitalize(t("items.news", 2)) },
101
+ { value: "publications", label: capitalize(t("items.publications", 2)) },
102
+ { value: "fellowships", label: capitalize(t("items.fellowships", 2)) },
103
+ { value: "projects", label: capitalize(t("items.projects", 2)) }
104
+ ];
105
+ const toggleFilter = (option) => {
106
+ const currentCategories = [...props.categories];
107
+ const index = currentCategories.indexOf(option.value);
108
+ if (index > -1) {
109
+ currentCategories.splice(index, 1);
110
+ } else {
111
+ currentCategories.push(option.value);
112
+ }
113
+ emit("filter-change", {
114
+ name: option.value,
115
+ value: currentCategories.includes(option.value),
116
+ categories: currentCategories
117
+ });
118
+ };
119
+ const search = computed({
120
+ get() {
121
+ return rootStore.search;
122
+ },
123
+ set: await useDebounceFn(async function(v) {
124
+ await rootStore.updateSearch({
125
+ type: props.type,
126
+ search: v || "",
127
+ lang: locale.value
128
+ });
129
+ }, 300)
130
+ });
131
+ </script>