@paris-ias/list 1.0.111 → 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 (163) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/components/events/DenseItem.vue +24 -15
  3. package/dist/runtime/components/fellowships/DenseItem.vue +1 -1
  4. package/dist/runtime/components/list/atoms/SearchInput.vue +4 -2
  5. package/dist/runtime/components/list/molecules/Pagination.vue +2 -0
  6. package/dist/runtime/components/list/organisms/List.vue +16 -2
  7. package/dist/runtime/components/list/views/Dense.vue +0 -1
  8. package/dist/runtime/components/news/DenseItem.vue +24 -23
  9. package/dist/runtime/components/people/Badges.vue +74 -0
  10. package/dist/runtime/components/people/DenseItem.vue +11 -8
  11. package/dist/runtime/components/people/RowsItem.vue +2 -2
  12. package/dist/runtime/components/people/View.vue +1 -1
  13. package/dist/runtime/components/publications/DenseItem.vue +14 -7
  14. package/dist/runtime/graphql/list/publications.gql +2 -0
  15. package/dist/runtime/runtime/components/actions/ExpandedItem.vue +14 -0
  16. package/dist/runtime/runtime/components/actions/RowsItem.vue +12 -0
  17. package/dist/runtime/runtime/components/actions/View.vue +20 -0
  18. package/dist/runtime/runtime/components/affiliations/ExpandedItem.vue +14 -0
  19. package/dist/runtime/runtime/components/affiliations/RowsItem.vue +12 -0
  20. package/dist/runtime/runtime/components/affiliations/View.vue +20 -0
  21. package/dist/runtime/runtime/components/apps/ExpandedItem.vue +14 -0
  22. package/dist/runtime/runtime/components/apps/RowsItem.vue +12 -0
  23. package/dist/runtime/runtime/components/apps/View.vue +20 -0
  24. package/dist/runtime/runtime/components/disciplines/ExpandedItem.vue +14 -0
  25. package/dist/runtime/runtime/components/disciplines/RowsItem.vue +12 -0
  26. package/dist/runtime/runtime/components/disciplines/View.vue +20 -0
  27. package/dist/runtime/runtime/components/events/Badges.vue +73 -0
  28. package/dist/runtime/runtime/components/events/DateTimePlace.vue +77 -0
  29. package/dist/runtime/runtime/components/events/DenseItem.vue +60 -0
  30. package/dist/runtime/runtime/components/events/ExpandedItem.vue +9 -0
  31. package/dist/runtime/runtime/components/events/RegisterModal.vue +50 -0
  32. package/dist/runtime/runtime/components/events/RelatedItem.vue +44 -0
  33. package/dist/runtime/runtime/components/events/RowsItem.vue +118 -0
  34. package/dist/runtime/runtime/components/events/SlidingItem.vue +63 -0
  35. package/dist/runtime/runtime/components/events/View.vue +333 -0
  36. package/dist/runtime/runtime/components/fellowships/Badges.vue +47 -0
  37. package/dist/runtime/runtime/components/fellowships/DenseItem.vue +42 -0
  38. package/dist/runtime/runtime/components/fellowships/ExpandedItem.vue +7 -0
  39. package/dist/runtime/runtime/components/fellowships/RegisterModal.vue +41 -0
  40. package/dist/runtime/runtime/components/fellowships/RowsItem.vue +58 -0
  41. package/dist/runtime/runtime/components/fellowships/View.vue +203 -0
  42. package/dist/runtime/runtime/components/files/ExpandedItem.vue +14 -0
  43. package/dist/runtime/runtime/components/files/RowsItem.vue +12 -0
  44. package/dist/runtime/runtime/components/files/View.vue +20 -0
  45. package/dist/runtime/runtime/components/list/atoms/FiltersMenu.vue +44 -0
  46. package/dist/runtime/runtime/components/list/atoms/ResetButton.vue +33 -0
  47. package/dist/runtime/runtime/components/list/atoms/ResultsList.vue +27 -0
  48. package/dist/runtime/runtime/components/list/atoms/SearchInput.vue +59 -0
  49. package/dist/runtime/runtime/components/list/atoms/SearchItem.vue +65 -0
  50. package/dist/runtime/runtime/components/list/atoms/SearchString.vue +160 -0
  51. package/dist/runtime/runtime/components/list/atoms/SortMenu.vue +80 -0
  52. package/dist/runtime/runtime/components/list/atoms/ViewMenu.vue +63 -0
  53. package/dist/runtime/runtime/components/list/atoms/itemsPerPage.vue +33 -0
  54. package/dist/runtime/runtime/components/list/inputs/AutoComplete.vue +24 -0
  55. package/dist/runtime/runtime/components/list/inputs/BooleanSwitch.vue +20 -0
  56. package/dist/runtime/runtime/components/list/inputs/Checkbox.vue +20 -0
  57. package/dist/runtime/runtime/components/list/inputs/Select.vue +28 -0
  58. package/dist/runtime/runtime/components/list/molecules/Filters.vue +98 -0
  59. package/dist/runtime/runtime/components/list/molecules/GlobalSearchInput.vue +131 -0
  60. package/dist/runtime/runtime/components/list/molecules/Header.vue +51 -0
  61. package/dist/runtime/runtime/components/list/molecules/Pagination.vue +194 -0
  62. package/dist/runtime/runtime/components/list/molecules/ResultsContainer.vue +78 -0
  63. package/dist/runtime/runtime/components/list/organisms/List.vue +110 -0
  64. package/dist/runtime/runtime/components/list/organisms/Results.vue +72 -0
  65. package/dist/runtime/runtime/components/list/organisms/Slider.vue +180 -0
  66. package/dist/runtime/runtime/components/list/views/Dense.vue +12 -0
  67. package/dist/runtime/runtime/components/list/views/Expanded.vue +10 -0
  68. package/dist/runtime/runtime/components/list/views/Grid.vue +13 -0
  69. package/dist/runtime/runtime/components/list/views/Rows.vue +12 -0
  70. package/dist/runtime/runtime/components/list/views/Slider.vue +147 -0
  71. package/dist/runtime/runtime/components/list/views/Table.vue +13 -0
  72. package/dist/runtime/runtime/components/mailing/ExpandedItem.vue +14 -0
  73. package/dist/runtime/runtime/components/mailing/RowsItem.vue +12 -0
  74. package/dist/runtime/runtime/components/mailing/View.vue +20 -0
  75. package/dist/runtime/runtime/components/misc/atoms/DateStamp.vue +101 -0
  76. package/dist/runtime/runtime/components/misc/atoms/ImageContainer.vue +127 -0
  77. package/dist/runtime/runtime/components/misc/atoms/ShareMenu.vue +61 -0
  78. package/dist/runtime/runtime/components/misc/atoms/Socials.vue +120 -0
  79. package/dist/runtime/runtime/components/misc/molecules/ChipContainer.vue +31 -0
  80. package/dist/runtime/runtime/components/misc/molecules/Related.vue +28 -0
  81. package/dist/runtime/runtime/components/misc/molecules/RelatedItems.vue +27 -0
  82. package/dist/runtime/runtime/components/misc/molecules/SearchItem.vue +26 -0
  83. package/dist/runtime/runtime/components/news/DenseItem.vue +73 -0
  84. package/dist/runtime/runtime/components/news/ExpandedItem.vue +145 -0
  85. package/dist/runtime/runtime/components/news/Header.vue +7 -0
  86. package/dist/runtime/runtime/components/news/RelatedItem.vue +44 -0
  87. package/dist/runtime/runtime/components/news/RowsItem.vue +182 -0
  88. package/dist/runtime/runtime/components/news/View.vue +174 -0
  89. package/dist/runtime/runtime/components/people/DenseItem.vue +60 -0
  90. package/dist/runtime/runtime/components/people/ExpandedItem.vue +14 -0
  91. package/dist/runtime/runtime/components/people/RelatedItem.vue +41 -0
  92. package/dist/runtime/runtime/components/people/RowsItem.vue +93 -0
  93. package/dist/runtime/runtime/components/people/View.vue +172 -0
  94. package/dist/runtime/runtime/components/projects/DenseItem.vue +77 -0
  95. package/dist/runtime/runtime/components/projects/ExpandedItem.vue +12 -0
  96. package/dist/runtime/runtime/components/projects/RelatedItem.vue +44 -0
  97. package/dist/runtime/runtime/components/projects/RowsItem.vue +103 -0
  98. package/dist/runtime/runtime/components/projects/View.vue +130 -0
  99. package/dist/runtime/runtime/components/publications/DenseItem.vue +89 -0
  100. package/dist/runtime/runtime/components/publications/RelatedItem.vue +44 -0
  101. package/dist/runtime/runtime/components/publications/RowsItem.vue +105 -0
  102. package/dist/runtime/runtime/components/publications/View.vue +132 -0
  103. package/dist/runtime/runtime/components/tags/ExpandedItem.vue +14 -0
  104. package/dist/runtime/runtime/components/tags/RowsItem.vue +12 -0
  105. package/dist/runtime/runtime/components/tags/View.vue +20 -0
  106. package/dist/runtime/runtime/components/users/ExpandedItem.vue +14 -0
  107. package/dist/runtime/runtime/components/users/RowsItem.vue +12 -0
  108. package/dist/runtime/runtime/components/users/View.vue +20 -0
  109. package/dist/runtime/runtime/composables/useFetchItem.d.ts +6 -0
  110. package/dist/runtime/runtime/composables/useFetchItem.js +49 -0
  111. package/dist/runtime/runtime/composables/useIcons.d.ts +1 -0
  112. package/dist/runtime/runtime/composables/useIcons.js +30 -0
  113. package/dist/runtime/runtime/composables/useUtils.d.ts +12 -0
  114. package/dist/runtime/runtime/composables/useUtils.js +48 -0
  115. package/dist/runtime/runtime/graphql/buildFiltersValues.gql +35 -0
  116. package/dist/runtime/runtime/graphql/item/action.gql +22 -0
  117. package/dist/runtime/runtime/graphql/item/affiliations.gql +37 -0
  118. package/dist/runtime/runtime/graphql/item/apps.gql +34 -0
  119. package/dist/runtime/runtime/graphql/item/disciplines.gql +17 -0
  120. package/dist/runtime/runtime/graphql/item/events.gql +120 -0
  121. package/dist/runtime/runtime/graphql/item/fellowships.gql +164 -0
  122. package/dist/runtime/runtime/graphql/item/files.gql +25 -0
  123. package/dist/runtime/runtime/graphql/item/mailing.gql +10 -0
  124. package/dist/runtime/runtime/graphql/item/news.gql +129 -0
  125. package/dist/runtime/runtime/graphql/item/people.gql +174 -0
  126. package/dist/runtime/runtime/graphql/item/projects.gql +171 -0
  127. package/dist/runtime/runtime/graphql/item/publications.gql +169 -0
  128. package/dist/runtime/runtime/graphql/item/tags.gql +13 -0
  129. package/dist/runtime/runtime/graphql/item/users.gql +14 -0
  130. package/dist/runtime/runtime/graphql/list/action.gql +31 -0
  131. package/dist/runtime/runtime/graphql/list/affiliations.gql +42 -0
  132. package/dist/runtime/runtime/graphql/list/apps.gql +42 -0
  133. package/dist/runtime/runtime/graphql/list/disciplines.gql +22 -0
  134. package/dist/runtime/runtime/graphql/list/events.gql +44 -0
  135. package/dist/runtime/runtime/graphql/list/fellowships.gql +53 -0
  136. package/dist/runtime/runtime/graphql/list/files.gql +37 -0
  137. package/dist/runtime/runtime/graphql/list/mailing.gql +22 -0
  138. package/dist/runtime/runtime/graphql/list/news.gql +40 -0
  139. package/dist/runtime/runtime/graphql/list/people.gql +50 -0
  140. package/dist/runtime/runtime/graphql/list/projects.gql +37 -0
  141. package/dist/runtime/runtime/graphql/list/publications.gql +38 -0
  142. package/dist/runtime/runtime/graphql/list/search.gql +161 -0
  143. package/dist/runtime/runtime/graphql/list/tags.gql +22 -0
  144. package/dist/runtime/runtime/graphql/list/users.gql +38 -0
  145. package/dist/runtime/runtime/graphql/login.gql +0 -0
  146. package/dist/runtime/runtime/plugins/pinia.d.ts +2 -0
  147. package/dist/runtime/runtime/plugins/pinia.js +134 -0
  148. package/dist/runtime/runtime/plugins/vuetify.d.ts +2 -0
  149. package/dist/runtime/runtime/plugins/vuetify.js +21 -0
  150. package/dist/runtime/runtime/public/default.png +0 -0
  151. package/dist/runtime/runtime/public/filters.json +72 -0
  152. package/dist/runtime/runtime/server/tsconfig.json +3 -0
  153. package/dist/runtime/runtime/stores/factory.d.ts +25 -0
  154. package/dist/runtime/runtime/stores/factory.js +19 -0
  155. package/dist/runtime/runtime/stores/root.d.ts +60 -0
  156. package/dist/runtime/runtime/stores/root.js +315 -0
  157. package/dist/runtime/runtime/translations/en.json +350 -0
  158. package/dist/runtime/runtime/translations/fr.json +349 -0
  159. package/dist/runtime/runtime/types/imports.d.ts +13 -0
  160. package/dist/runtime/runtime/types/stores.d.ts +11 -0
  161. package/dist/runtime/translations/en.json +1 -1
  162. package/package.json +2 -2
  163. /package/dist/runtime/{components → runtime/components}/people/GroupBadges.vue +0 -0
@@ -0,0 +1,194 @@
1
+ <template>
2
+ <v-btn-toggle
3
+ value="currentPage"
4
+ role="navigation"
5
+ aria-label="Pagination Navigation"
6
+ >
7
+ <!-- TODO: switch to page as route param -->
8
+ <v-btn
9
+ v-if="!(hidePrevNext && firstPageSelected())"
10
+ :disabled="firstPageSelected()"
11
+ min-width="35"
12
+ height="35"
13
+ width="35"
14
+ :tabindex="!hidePrevNext && firstPageSelected() ? -1 : 0"
15
+ aria-label="Previous Page"
16
+ nuxt
17
+ @click="updatePage(currentPage - 1)"
18
+ @keyup.enter="updatePage(currentPage - 1)"
19
+ >
20
+ <v-icon>mdi-chevron-left</v-icon>
21
+ </v-btn>
22
+
23
+ <template v-for="(page, index) in renderPages" :key="page.key">
24
+ <v-btn
25
+ v-if="page.isGap"
26
+ min-width="35"
27
+ height="35"
28
+ width="35"
29
+ icon
30
+ nuxt
31
+ @keyup.enter="updatePage(getGapPage(index))"
32
+ @click="updatePage(getGapPage(index))"
33
+ >
34
+ ...
35
+ </v-btn>
36
+ <template v-else>
37
+ <v-btn
38
+ :class="{ 'active-page': !!page.current }"
39
+ tabindex="0"
40
+ outlined
41
+ min-width="35"
42
+ height="35"
43
+ tile
44
+ nuxt
45
+ :active="!!page.current"
46
+ :color="!!page.current ? 'white' : 'black'"
47
+ text
48
+ width="35"
49
+ :aria-current="!!page.current ? 'true' : 'false'"
50
+ :aria-label="
51
+ page.current
52
+ ? `Current page, Page ${page.value}`
53
+ : `Goto Page ${page.value}`
54
+ "
55
+ @click="updatePage(page.value)"
56
+ @keyup.enter="updatePage(page.value)"
57
+ >
58
+ {{ page.value }}
59
+ </v-btn>
60
+ </template>
61
+ </template>
62
+
63
+ <v-btn
64
+ v-if="!(hidePrevNext && lastPageSelected())"
65
+ :tabindex="!hidePrevNext && lastPageSelected() ? -1 : 0"
66
+ :disabled="lastPageSelected()"
67
+ aria-label="Next Page"
68
+ min-width="35"
69
+ height="35"
70
+ width="35"
71
+ nuxt
72
+ @click="updatePage(currentPage + 1)"
73
+ @keyup.enter="updatePage(currentPage + 1)"
74
+ >
75
+ <v-icon>mdi-chevron-right</v-icon>
76
+ </v-btn>
77
+ </v-btn-toggle>
78
+ </template>
79
+
80
+ <script setup>
81
+ import { useRootStore } from "../../../stores/root";
82
+ import { useRoute, computed, useI18n } from "#imports";
83
+ const { locale } = useI18n();
84
+ const route = useRoute();
85
+ const rootStore = useRootStore();
86
+ const props = defineProps({
87
+ totalPages: {
88
+ type: Number,
89
+ required: true
90
+ },
91
+ currentPage: {
92
+ type: Number,
93
+ default: 1
94
+ },
95
+ pagePadding: {
96
+ type: Number,
97
+ default: 1,
98
+ validator: (value) => {
99
+ return value > 0;
100
+ }
101
+ },
102
+ pageGap: {
103
+ type: Number,
104
+ default: 2,
105
+ validator: (value) => {
106
+ return value > 0;
107
+ }
108
+ },
109
+ hidePrevNext: {
110
+ type: Boolean,
111
+ default: false
112
+ },
113
+ type: {
114
+ type: String,
115
+ default: "",
116
+ required: true
117
+ }
118
+ });
119
+ const renderPages = computed(() => {
120
+ const pages = [];
121
+ for (let pageIndex = 1; pageIndex <= props.totalPages; pageIndex++) {
122
+ if (pageIndex === props.currentPage || pageIndex < props.pageGap || pageIndex > props.totalPages - props.pageGap + 1) {
123
+ pages.push(createPage(pageIndex));
124
+ continue;
125
+ }
126
+ let minimum;
127
+ let maximum;
128
+ if (props.currentPage <= props.pageGap + props.pagePadding) {
129
+ minimum = props.pageGap + 1;
130
+ maximum = minimum + props.pagePadding * 2;
131
+ } else if (props.currentPage >= props.totalPages - props.pageGap - props.pagePadding) {
132
+ maximum = props.totalPages - props.pageGap;
133
+ minimum = maximum - props.pagePadding * 2;
134
+ } else {
135
+ minimum = props.currentPage - props.pagePadding;
136
+ maximum = props.currentPage + props.pagePadding;
137
+ }
138
+ if (pageIndex >= minimum && pageIndex <= props.currentPage || pageIndex >= props.currentPage && pageIndex <= maximum) {
139
+ pages.push(createPage(pageIndex));
140
+ continue;
141
+ }
142
+ if (pageIndex === props.pageGap) {
143
+ if (minimum > props.pageGap + 1 && props.currentPage > props.pageGap + props.pagePadding + 1) {
144
+ pages.push(createGap(pageIndex));
145
+ } else {
146
+ pages.push(createPage(pageIndex));
147
+ }
148
+ continue;
149
+ }
150
+ if (pageIndex === props.totalPages - props.pageGap + 1) {
151
+ if (maximum < props.totalPages - props.pageGap && props.currentPage < props.totalPages - props.pageGap - props.pagePadding) {
152
+ pages.push(createGap(pageIndex));
153
+ } else {
154
+ pages.push(createPage(pageIndex));
155
+ }
156
+ continue;
157
+ }
158
+ }
159
+ return pages;
160
+ });
161
+ const createPage = (pageIndex) => {
162
+ return {
163
+ key: pageIndex,
164
+ current: props.currentPage === pageIndex,
165
+ value: pageIndex
166
+ };
167
+ };
168
+ const firstPageSelected = () => {
169
+ return props.currentPage === 1;
170
+ };
171
+ const lastPageSelected = () => {
172
+ return props.currentPage === props.totalPages || props.totalPages === 0;
173
+ };
174
+ const createGap = (pageIndex) => {
175
+ return {
176
+ key: pageIndex,
177
+ isGap: true
178
+ };
179
+ };
180
+ const emit = defineEmits(["update"]);
181
+ const updatePage = (page) => {
182
+ rootStore.updatePage({ page, type: props.type, lang: locale.value });
183
+ emit("update", page);
184
+ };
185
+ const getGapPage = (index) => {
186
+ return Math.floor(
187
+ renderPages.value[index - 1].key + ((renderPages.value[index + 1].key || props.totalPages) - renderPages.value[index - 1].key) / 2
188
+ );
189
+ };
190
+ </script>
191
+
192
+ <style>
193
+ .active-page{background-color:#000!important;color:#f5f5f5!important}
194
+ </style>
@@ -0,0 +1,78 @@
1
+ <template>
2
+ <div>
3
+ <div class="d-flex align-center justify-space-between my-6">
4
+ <v-btn
5
+ variant="text"
6
+ size="large"
7
+ class=""
8
+ @click="$emit('toggle', type)"
9
+ >
10
+ <v-icon size="large">{{
11
+ open ? "mdi-chevron-down" : "mdi-chevron-right"
12
+ }}</v-icon>
13
+ </v-btn>
14
+ <div
15
+ class="d-flex flex-column cursor-pointer"
16
+ @click="$emit('toggle', type)"
17
+ >
18
+ <div class="text-h4">
19
+ {{ capitalize($t("items." + props.type, 2)) }}
20
+ </div>
21
+ <div class="text-overline">
22
+ {{
23
+ feminine
24
+ ? $t(
25
+ "list.0-items-found-f",
26
+ [
27
+ $rootStore.results[type].total,
28
+ $t("items." + props.type, $rootStore.results[type].total),
29
+ ],
30
+ $rootStore.results[type].total,
31
+ )
32
+ : $t(
33
+ "list.0-items-found",
34
+ [
35
+ $rootStore.results[type].total,
36
+ $t("items." + props.type, $rootStore.results[type].total),
37
+ ],
38
+ $rootStore.results[type].total,
39
+ )
40
+ }}
41
+ </div>
42
+ </div>
43
+ <v-spacer />
44
+ </div>
45
+ <slot />
46
+ <v-btn
47
+ class="ma-2 float-right"
48
+ color="default"
49
+ variant="text"
50
+ rounded="0"
51
+ :to="localePath(type === 'people' ? '/people' : '/activities/' + type)"
52
+ >
53
+ {{ $t("list.pls-x-more", [$rootStore.results[type].total]) }}
54
+ </v-btn>
55
+ </div>
56
+ </template>
57
+
58
+ <script setup>
59
+ import { useNuxtApp, useLocalePath } from "#imports";
60
+ const localePath = useLocalePath();
61
+ const { $rootStore } = useNuxtApp();
62
+ const props = defineProps({
63
+ type: {
64
+ type: String,
65
+ required: true
66
+ },
67
+ feminine: {
68
+ type: Boolean,
69
+ required: false,
70
+ default: false
71
+ },
72
+ open: {
73
+ type: Boolean,
74
+ required: false,
75
+ default: true
76
+ }
77
+ });
78
+ </script>
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <ListMoleculesHeader :type="type" />
3
+ <component :is="view">
4
+ <component
5
+ :is="itemTemplate"
6
+ v-for="(item, index) in items"
7
+ :key="index"
8
+ :item="item"
9
+ :index="index"
10
+ />
11
+ </component>
12
+ <div class="text-center">
13
+ <ListMoleculesPagination
14
+ v-if="numberOfPages > 1"
15
+ :type="type"
16
+ color="black"
17
+ large
18
+ :current-page="page"
19
+ :total-pages="numberOfPages"
20
+ :page-padding="1"
21
+ :page-gap="2"
22
+ :hide-prev-next="false"
23
+ @update="onPageChange"
24
+ />
25
+ </div>
26
+ </template>
27
+
28
+ <script setup>
29
+ import { useRootStore } from "../../../stores/root";
30
+ import { capitalize } from "../../../composables/useUtils";
31
+ import {
32
+ useNuxtApp,
33
+ resolveComponent,
34
+ computed,
35
+ onBeforeUnmount,
36
+ onMounted,
37
+ useI18n,
38
+ useRoute
39
+ } from "#imports";
40
+ const { $stores } = useNuxtApp();
41
+ const { locale } = useI18n();
42
+ const route = useRoute();
43
+ const rootStore = useRootStore();
44
+ const props = defineProps({
45
+ addBtn: {
46
+ type: Boolean,
47
+ required: false,
48
+ default: false
49
+ },
50
+ type: {
51
+ type: String,
52
+ default: "people",
53
+ required: true
54
+ },
55
+ layout: {
56
+ type: Object,
57
+ required: false,
58
+ default: () => {
59
+ return {
60
+ cols: 12,
61
+ xl: 12
62
+ };
63
+ }
64
+ },
65
+ pagination: {
66
+ type: Object,
67
+ required: false,
68
+ default: () => {
69
+ return {};
70
+ }
71
+ },
72
+ addButton: {
73
+ type: Boolean,
74
+ required: false,
75
+ default: false
76
+ },
77
+ items: [Object]
78
+ });
79
+ const view = computed(
80
+ () => props.customView ? resolveComponent("ListViews" + capitalize(props.customView)) : resolveComponent("ListViews" + capitalize($stores[props.type].view.name))
81
+ );
82
+ const itemTemplate = computed(
83
+ () => resolveComponent(
84
+ (capitalize(props.type) + capitalize($stores[props.type].view.name) + "Item").toString()
85
+ )
86
+ );
87
+ const numberOfPages = computed(() => $stores[props.type].numberOfPages);
88
+ const page = computed(() => +$stores[props.type].page);
89
+ const items = computed(() => $stores[props.type].items);
90
+ console.log("setup list");
91
+ onMounted(() => {
92
+ console.log("mounted list");
93
+ });
94
+ rootStore.loadRouteQuery(props.type);
95
+ try {
96
+ await rootStore.update(props.type, locale.value);
97
+ } catch (error) {
98
+ console.log("error fetching update list: ", error);
99
+ }
100
+ onBeforeUnmount(() => {
101
+ rootStore.resetState(props.type, locale.value);
102
+ });
103
+ const onPageChange = (newPage) => {
104
+ rootStore.updatePage({ page: newPage, type: props.type, lang: locale.value });
105
+ window.scrollTo({
106
+ top: 0,
107
+ behavior: "smooth"
108
+ });
109
+ };
110
+ </script>
@@ -0,0 +1,72 @@
1
+ <template>
2
+ <ListMoleculesGlobalSearchInput
3
+ type="all"
4
+ :placeholder="$t('search')"
5
+ variant="outlined"
6
+ />
7
+ <ListMoleculesResultsContainer
8
+ v-for="type in sortedModules"
9
+ :key="type"
10
+ :feminine="type === 'people'"
11
+ :type
12
+ :open="
13
+ open[type] !== undefined
14
+ ? open[type]
15
+ : $rootStore.results[type]?.total > 0
16
+ "
17
+ @toggle="open[$event] = !open[$event]"
18
+ >
19
+ <v-expand-transition class="results-container">
20
+ <div v-show="open[type]">
21
+ <ListAtomsResultsList :type />
22
+ </div>
23
+ </v-expand-transition>
24
+ </ListMoleculesResultsContainer>
25
+ </template>
26
+
27
+ <script setup>
28
+ import {
29
+ useNuxtApp,
30
+ useLocalePath,
31
+ onBeforeUnmount,
32
+ onMounted,
33
+ useI18n,
34
+ useAppConfig,
35
+ ref,
36
+ computed
37
+ } from "#imports";
38
+ const localePath = useLocalePath();
39
+ defineOptions({
40
+ name: "SearchResults"
41
+ });
42
+ const { $rootStore } = useNuxtApp();
43
+ const appConfig = useAppConfig();
44
+ const { locale } = useI18n();
45
+ const open = ref({});
46
+ const sortedModules = computed(() => {
47
+ return appConfig.list.modules.slice().sort((a, b) => {
48
+ const aResults = $rootStore.results[a] || { total: 0 };
49
+ const bResults = $rootStore.results[b] || { total: 0 };
50
+ return (bResults.total || 0) - (aResults.total || 0);
51
+ });
52
+ });
53
+ onMounted(async () => {
54
+ console.log("mounted list");
55
+ try {
56
+ await $rootStore.update("all", locale.value);
57
+ appConfig.list.modules.forEach((type) => {
58
+ if ($rootStore.results[type]?.total > 0) {
59
+ open.value[type] = true;
60
+ }
61
+ });
62
+ } catch (error) {
63
+ console.log("error fetching update list: ", error);
64
+ }
65
+ });
66
+ onBeforeUnmount(() => {
67
+ });
68
+ </script>
69
+
70
+ <style scoped>
71
+ .results-container{display:flex;flex-direction:column;gap:8px;margin-left:8px}
72
+ </style>
@@ -0,0 +1,180 @@
1
+ <template>
2
+ <div class="slider-container">
3
+ <!-- Header with counter and navigation -->
4
+ <div class="slider-header">
5
+ <div class="slide-counter">
6
+ {{ activeSlideIndex + 1 }}/{{ items.length }}
7
+ </div>
8
+ <div class="navigation-controls">
9
+ <button
10
+ :disabled="!canGoBack"
11
+ class="nav-button nav-prev"
12
+ @click="goToSlide(activeSlideIndex - 1)"
13
+ >
14
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
15
+ <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" />
16
+ </svg>
17
+ </button>
18
+ <button
19
+ :disabled="!canGoForward"
20
+ class="nav-button nav-next"
21
+ @click="goToSlide(activeSlideIndex + 1)"
22
+ >
23
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="currentColor">
24
+ <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" />
25
+ </svg>
26
+ </button>
27
+ </div>
28
+ </div>
29
+
30
+ <!-- Slider container -->
31
+ <div ref="sliderRef" class="slider-viewport" @scroll="handleScroll">
32
+ <div
33
+ class="slider-track"
34
+ :style="{ transform: `translateX(${offsetX}px)` }"
35
+ >
36
+ <div
37
+ v-for="(item, index) in items"
38
+ :key="index"
39
+ class="slide-item"
40
+ :class="{
41
+ 'slide-visible': isSlideVisible(index),
42
+ 'slide-entering': isSlideEntering(index),
43
+ 'slide-exiting': isSlideExiting(index),
44
+ }"
45
+ :style="getSlideStyle(index)"
46
+ >
47
+ <component :is="itemComponent" :item="item" :index="index" />
48
+ </div>
49
+ </div>
50
+ </div>
51
+ </div>
52
+ </template>
53
+
54
+ <script setup>
55
+ import { ref, computed, onMounted, onBeforeUnmount, nextTick, watch } from "vue";
56
+ import { useRootStore } from "../../../stores/root";
57
+ import { capitalize } from "../../../composables/useUtils";
58
+ import { useNuxtApp, useI18n } from "#imports";
59
+ defineOptions({ name: "ListOrganismsSlider" });
60
+ const { $stores } = useNuxtApp();
61
+ const { locale } = useI18n();
62
+ const rootStore = useRootStore();
63
+ const props = defineProps({
64
+ type: {
65
+ type: String,
66
+ required: true
67
+ }
68
+ });
69
+ const items = computed(() => $stores[props.type].items);
70
+ const sliderRef = ref(null);
71
+ const activeSlideIndex = ref(0);
72
+ const offsetX = ref(0);
73
+ const containerWidth = ref(0);
74
+ const slideWidth = ref(0);
75
+ const slidesPerView = ref(1);
76
+ const itemComponent = computed(() => {
77
+ return capitalize(props.type) + "SlidingItem";
78
+ });
79
+ const totalSlides = computed(() => items.value.length);
80
+ const canGoBack = computed(() => activeSlideIndex.value > 0);
81
+ const canGoForward = computed(() => {
82
+ const maxIndex = Math.max(0, totalSlides.value - slidesPerView.value);
83
+ return activeSlideIndex.value < maxIndex;
84
+ });
85
+ const visibleSlideIndices = computed(() => {
86
+ const start = activeSlideIndex.value;
87
+ const end = Math.min(start + slidesPerView.value, totalSlides.value);
88
+ return Array.from({ length: end - start }, (_, i) => start + i);
89
+ });
90
+ const calculateDimensions = () => {
91
+ if (!sliderRef.value) return;
92
+ containerWidth.value = sliderRef.value.offsetWidth;
93
+ const breakpoints = {
94
+ 320: { slidesPerView: 1.2, spacing: 20 },
95
+ 640: { slidesPerView: 2, spacing: 24 },
96
+ 960: { slidesPerView: 2.5, spacing: 28 },
97
+ 1280: { slidesPerView: 3, spacing: 32 },
98
+ 1600: { slidesPerView: 3.5, spacing: 36 }
99
+ };
100
+ const currentBreakpoint = Object.entries(breakpoints).reverse().find(([width]) => window.innerWidth >= Number.parseInt(width));
101
+ const config = currentBreakpoint ? currentBreakpoint[1] : breakpoints[320];
102
+ slidesPerView.value = Math.floor(config.slidesPerView);
103
+ slideWidth.value = (containerWidth.value - config.spacing * (config.slidesPerView - 1)) / config.slidesPerView;
104
+ };
105
+ const isSlideVisible = (index) => {
106
+ return visibleSlideIndices.value.includes(index);
107
+ };
108
+ const isSlideEntering = (index) => {
109
+ const rightmostVisible = Math.max(...visibleSlideIndices.value);
110
+ return index === rightmostVisible && index > activeSlideIndex.value;
111
+ };
112
+ const isSlideExiting = (index) => {
113
+ const leftmostVisible = Math.min(...visibleSlideIndices.value);
114
+ return index === leftmostVisible && index < activeSlideIndex.value;
115
+ };
116
+ const getSlideStyle = (index) => {
117
+ const baseStyles = {
118
+ width: `${slideWidth.value}px`,
119
+ opacity: isSlideVisible(index) ? 1 : 0,
120
+ transform: `translateX(${index * (slideWidth.value + 24)}px)`,
121
+ transition: "all 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94)"
122
+ };
123
+ if (isSlideEntering(index)) {
124
+ baseStyles.transform += " translateX(20px)";
125
+ baseStyles.opacity = 0.8;
126
+ }
127
+ if (isSlideExiting(index)) {
128
+ baseStyles.transform += " translateX(-20px)";
129
+ baseStyles.opacity = 0.6;
130
+ }
131
+ return baseStyles;
132
+ };
133
+ const goToSlide = (targetIndex) => {
134
+ const maxIndex = Math.max(0, totalSlides.value - slidesPerView.value);
135
+ const newIndex = Math.max(0, Math.min(targetIndex, maxIndex));
136
+ if (newIndex === activeSlideIndex.value) return;
137
+ activeSlideIndex.value = newIndex;
138
+ updateSliderPosition();
139
+ };
140
+ const updateSliderPosition = () => {
141
+ const newOffset = -(activeSlideIndex.value * (slideWidth.value + 24));
142
+ const visualOffset = activeSlideIndex.value > 0 ? -40 : 0;
143
+ offsetX.value = newOffset + visualOffset;
144
+ };
145
+ const handleScroll = () => {
146
+ };
147
+ const handleResize = () => {
148
+ calculateDimensions();
149
+ updateSliderPosition();
150
+ };
151
+ onMounted(async () => {
152
+ await nextTick();
153
+ calculateDimensions();
154
+ updateSliderPosition();
155
+ window.addEventListener("resize", handleResize);
156
+ });
157
+ onBeforeUnmount(() => {
158
+ window.removeEventListener("resize", handleResize);
159
+ rootStore.resetState(props.type, locale.value);
160
+ });
161
+ watch(
162
+ () => items.value,
163
+ () => {
164
+ nextTick(() => {
165
+ calculateDimensions();
166
+ updateSliderPosition();
167
+ });
168
+ },
169
+ { deep: true }
170
+ );
171
+ try {
172
+ await rootStore.update(props.type, locale.value);
173
+ } catch (error) {
174
+ console.log("error fetching update list: ", error);
175
+ }
176
+ </script>
177
+
178
+ <style scoped>
179
+ .slider-container{overflow:hidden;position:relative;width:100%}.slider-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:24px;padding:0 20px}.slide-counter{color:#666;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;font-size:14px;font-weight:500}.navigation-controls{display:flex;gap:8px}.nav-button{align-items:center;background:#fff;border:1px solid #e0e0e0;border-radius:4px;color:#333;cursor:pointer;display:flex;height:40px;justify-content:center;transition:all .2s ease;width:40px}.nav-button:hover:not(:disabled){background:#f5f5f5;border-color:#d0d0d0}.nav-button:disabled{color:#999;cursor:not-allowed;opacity:.4}.slider-viewport{overflow:hidden;padding:0 20px;position:relative;width:100%}.slider-track{display:flex;transition:transform .4s cubic-bezier(.25,.46,.45,.94);will-change:transform}.slide-item{flex-shrink:0;margin-right:24px;transform-origin:center;will-change:transform,opacity}.slide-item:last-child{margin-right:0}.slide-entering{animation:slideInFromRight .4s cubic-bezier(.25,.46,.45,.94)}.slide-exiting{animation:slideOutToLeft .4s cubic-bezier(.25,.46,.45,.94)}@keyframes slideInFromRight{0%{opacity:0;transform:translateX(40px)}to{opacity:1;transform:translateX(0)}}@keyframes slideOutToLeft{0%{opacity:1;transform:translateX(0)}to{opacity:.6;transform:translateX(-40px)}}@media (max-width:640px){.slider-header{margin-bottom:20px;padding:0 16px}.slider-viewport{padding:0 16px}.slide-item{margin-right:16px}}@media (max-width:480px){.slide-counter{font-size:12px}.nav-button{height:36px;width:36px}.nav-button svg{height:20px;width:20px}}
180
+ </style>
@@ -0,0 +1,12 @@
1
+ <template>
2
+ <section class="my-6 ml-2 pb-6">
3
+ <slot>
4
+ <!-- fallback content -->
5
+ Dense view
6
+ </slot>
7
+ </section>
8
+ </template>
9
+
10
+ <style>
11
+ section{display:table;width:100%}section>*{display:table-row}section .v-col.dense{display:table-cell;vertical-align:middle}
12
+ </style>
@@ -0,0 +1,10 @@
1
+ <template>
2
+ <section>
3
+ <slot>
4
+ <!-- fallback content -->
5
+ Expanded view
6
+ </slot>
7
+ </section>
8
+ </template>
9
+
10
+ <script setup lang="ts"></script>
@@ -0,0 +1,13 @@
1
+ <template>
2
+ GRID DISPLAY
3
+ <template v-for="(item, index) in items" :key="index">
4
+ <slot name="data" :item="item" />
5
+ </template>
6
+ </template>
7
+
8
+ <script setup>
9
+ const props = defineProps({
10
+ items: [Object],
11
+ type: String
12
+ });
13
+ </script>
@@ -0,0 +1,12 @@
1
+ <template>
2
+ <v-row>
3
+ <slot>
4
+ <!-- fallback content -->
5
+ Rows view
6
+ </slot>
7
+ </v-row>
8
+ </template>
9
+
10
+ <script setup>
11
+
12
+ </script>