@paris-ias/list 1.0.136 → 1.0.138
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/actions/DenseItem.vue +64 -0
- package/dist/runtime/components/actions/ExpandedItem.vue +17 -10
- package/dist/runtime/components/actions/RowsItem.vue +57 -7
- package/dist/runtime/components/actions/View.vue +5 -17
- package/dist/runtime/components/affiliation/DenseItem.vue +26 -6
- package/dist/runtime/components/affiliation/ExpandedItem.vue +4 -0
- package/dist/runtime/components/affiliation/RowsItem.vue +27 -7
- package/dist/runtime/components/affiliation/View.vue +4 -4
- package/dist/runtime/components/apps/DenseItem.vue +26 -6
- package/dist/runtime/components/apps/ExpandedItem.vue +5 -1
- package/dist/runtime/components/apps/RowsItem.vue +27 -7
- package/dist/runtime/components/apps/View.vue +4 -4
- package/dist/runtime/components/disciplines/DenseItem.vue +26 -6
- package/dist/runtime/components/disciplines/ExpandedItem.vue +4 -0
- package/dist/runtime/components/disciplines/RowsItem.vue +27 -7
- package/dist/runtime/components/disciplines/View.vue +4 -4
- package/dist/runtime/components/events/Badges.vue +8 -12
- package/dist/runtime/components/events/DenseItem.vue +26 -16
- package/dist/runtime/components/events/ExpandedItem.vue +4 -0
- package/dist/runtime/components/events/RelatedItem.vue +4 -13
- package/dist/runtime/components/events/RowsItem.vue +20 -20
- package/dist/runtime/components/events/SlidingItem.vue +39 -47
- package/dist/runtime/components/events/View.vue +1 -1
- package/dist/runtime/components/fellowships/Badges.vue +15 -11
- package/dist/runtime/components/fellowships/DenseItem.vue +22 -11
- package/dist/runtime/components/fellowships/ExpandedItem.vue +8 -1
- package/dist/runtime/components/fellowships/RowsItem.vue +22 -15
- package/dist/runtime/components/fellowships/View.vue +2 -2
- package/dist/runtime/components/files/DenseItem.vue +26 -6
- package/dist/runtime/components/files/ExpandedItem.vue +4 -0
- package/dist/runtime/components/files/RowsItem.vue +27 -7
- package/dist/runtime/components/files/View.vue +4 -4
- package/dist/runtime/components/list/atoms/FiltersMenu.vue +9 -0
- package/dist/runtime/components/list/atoms/PerPage.vue +3 -2
- package/dist/runtime/components/list/atoms/ResetButton.vue +5 -1
- package/dist/runtime/components/list/atoms/SearchInput.vue +15 -2
- package/dist/runtime/components/list/atoms/SearchString.vue +169 -133
- package/dist/runtime/components/list/atoms/SortMenu.vue +22 -18
- package/dist/runtime/components/list/atoms/ViewMenu.vue +26 -14
- package/dist/runtime/components/list/molecules/Filters.vue +8 -8
- package/dist/runtime/components/list/molecules/Header.vue +10 -19
- package/dist/runtime/components/list/molecules/Pagination.vue +51 -48
- package/dist/runtime/components/list/organisms/List.vue +104 -69
- package/dist/runtime/components/mailing/DenseItem.vue +4 -0
- package/dist/runtime/components/mailing/ExpandedItem.vue +4 -0
- package/dist/runtime/components/mailing/RowsItem.vue +27 -7
- package/dist/runtime/components/mailing/View.vue +4 -4
- package/dist/runtime/components/misc/atoms/ImageContainer.vue +3 -45
- package/dist/runtime/components/misc/molecules/Related.vue +1 -1
- package/dist/runtime/components/news/DenseItem.vue +63 -54
- package/dist/runtime/components/news/ExpandedItem.vue +11 -17
- package/dist/runtime/components/news/RelatedItem.vue +4 -13
- package/dist/runtime/components/news/RowsItem.vue +21 -42
- package/dist/runtime/components/news/View.vue +7 -7
- package/dist/runtime/components/people/DenseItem.vue +16 -20
- package/dist/runtime/components/people/RelatedItem.vue +4 -14
- package/dist/runtime/components/people/RowsItem.vue +14 -23
- package/dist/runtime/components/projects/DenseItem.vue +17 -17
- package/dist/runtime/components/projects/RelatedItem.vue +4 -13
- package/dist/runtime/components/projects/RowsItem.vue +16 -16
- package/dist/runtime/components/projects/View.vue +6 -6
- package/dist/runtime/components/publications/DenseItem.vue +17 -15
- package/dist/runtime/components/publications/RelatedItem.vue +4 -13
- package/dist/runtime/components/publications/RowsItem.vue +18 -18
- package/dist/runtime/components/tags/DenseItem.vue +4 -0
- package/dist/runtime/components/tags/ExpandedItem.vue +4 -0
- package/dist/runtime/components/tags/RowsItem.vue +24 -7
- package/dist/runtime/components/tags/View.vue +4 -4
- package/dist/runtime/components/users/DenseItem.vue +24 -6
- package/dist/runtime/components/users/ExpandedItem.vue +5 -1
- package/dist/runtime/components/users/RowsItem.vue +25 -7
- package/dist/runtime/components/users/View.vue +4 -4
- package/dist/runtime/composables/useUtils.js +1 -1
- package/dist/runtime/plugins/pinia.js +5 -2
- package/dist/runtime/stores/root.d.ts +10 -9
- package/dist/runtime/stores/root.js +83 -119
- package/package.json +3 -4
|
@@ -34,25 +34,6 @@ import { ref, computed } from "vue"
|
|
|
34
34
|
import { useNuxtApp } from "#imports"
|
|
35
35
|
const { $stores } = useNuxtApp()
|
|
36
36
|
|
|
37
|
-
const filtersOpen = ref(false)
|
|
38
|
-
const visible = computed(() => {
|
|
39
|
-
console.log(
|
|
40
|
-
"$stores[props.type]?.filtersCount > 0: ",
|
|
41
|
-
$stores[props.type]?.filtersCount > 0
|
|
42
|
-
)
|
|
43
|
-
console.log(
|
|
44
|
-
"$stores[props.type]?.filtersCount: ",
|
|
45
|
-
$stores[props.type]?.filtersCount
|
|
46
|
-
)
|
|
47
|
-
console.log(
|
|
48
|
-
!!(
|
|
49
|
-
$stores[props.type]?.filtersCount && $stores[props.type]?.filtersCount > 0
|
|
50
|
-
)
|
|
51
|
-
)
|
|
52
|
-
return !!(
|
|
53
|
-
$stores[props.type]?.filtersCount && $stores[props.type]?.filtersCount > 0
|
|
54
|
-
)
|
|
55
|
-
})
|
|
56
37
|
const props = defineProps({
|
|
57
38
|
type: {
|
|
58
39
|
type: String,
|
|
@@ -60,4 +41,14 @@ const props = defineProps({
|
|
|
60
41
|
default: "",
|
|
61
42
|
},
|
|
62
43
|
})
|
|
44
|
+
const visible = computed(() => {
|
|
45
|
+
console.log(
|
|
46
|
+
"SHOULD DISPLAY FILTERS:",
|
|
47
|
+
$stores[props.type]?.filtersCount && $stores[props.type]?.filtersCount > 0,
|
|
48
|
+
)
|
|
49
|
+
return !!(
|
|
50
|
+
$stores[props.type]?.filtersCount && $stores[props.type]?.filtersCount > 0
|
|
51
|
+
)
|
|
52
|
+
})
|
|
53
|
+
const filtersOpen = ref(unref(visible))
|
|
63
54
|
</script>
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
<v-btn
|
|
10
10
|
v-if="!(hidePrevNext && isFirstPage)"
|
|
11
11
|
:disabled="isFirstPage"
|
|
12
|
-
min-width="
|
|
13
|
-
height="
|
|
14
|
-
width="
|
|
12
|
+
min-width="40"
|
|
13
|
+
height="40"
|
|
14
|
+
width="40"
|
|
15
|
+
class="prev-btn"
|
|
15
16
|
:tabindex="isFirstPage && hidePrevNext ? -1 : 0"
|
|
16
17
|
aria-label="Previous Page"
|
|
17
18
|
@click="onChange(currentPage - 1)"
|
|
@@ -19,16 +20,16 @@
|
|
|
19
20
|
>
|
|
20
21
|
<v-icon>mdi-chevron-left</v-icon>
|
|
21
22
|
</v-btn>
|
|
22
|
-
|
|
23
23
|
<!-- Page buttons and gaps -->
|
|
24
24
|
<template v-for="(page, index) in renderPages" :key="page.key">
|
|
25
25
|
<!-- Ellipsis gap -->
|
|
26
26
|
<v-btn
|
|
27
|
+
class="ellipsis-btn"
|
|
27
28
|
v-if="page.isGap"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
height="
|
|
31
|
-
width="
|
|
29
|
+
min-width="40"
|
|
30
|
+
tile
|
|
31
|
+
height="40"
|
|
32
|
+
width="40"
|
|
32
33
|
@click="onChange(getGapPage(index))"
|
|
33
34
|
@keyup.enter="onChange(getGapPage(index))"
|
|
34
35
|
>
|
|
@@ -40,10 +41,10 @@
|
|
|
40
41
|
v-else
|
|
41
42
|
:class="['page-button', { 'active-page': page.current }]"
|
|
42
43
|
tabindex="0"
|
|
43
|
-
min-width="
|
|
44
|
-
height="
|
|
44
|
+
min-width="40"
|
|
45
|
+
height="40"
|
|
45
46
|
tile
|
|
46
|
-
width="
|
|
47
|
+
width="40"
|
|
47
48
|
:aria-current="page.current ? 'page' : undefined"
|
|
48
49
|
:aria-label="
|
|
49
50
|
page.current
|
|
@@ -63,9 +64,11 @@
|
|
|
63
64
|
:disabled="isLastPage"
|
|
64
65
|
:tabindex="isLastPage && hidePrevNext ? -1 : 0"
|
|
65
66
|
aria-label="Next Page"
|
|
66
|
-
min-width="
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
min-width="40"
|
|
68
|
+
tile
|
|
69
|
+
class="next-btn"
|
|
70
|
+
height="40"
|
|
71
|
+
width="40"
|
|
69
72
|
@click="onChange(currentPage + 1)"
|
|
70
73
|
@keyup.enter="onChange(currentPage + 1)"
|
|
71
74
|
>
|
|
@@ -75,7 +78,7 @@
|
|
|
75
78
|
</template>
|
|
76
79
|
|
|
77
80
|
<script setup>
|
|
78
|
-
import { computed } from "vue"
|
|
81
|
+
import { computed } from "vue"
|
|
79
82
|
|
|
80
83
|
const props = defineProps({
|
|
81
84
|
currentPage: { type: Number, required: true },
|
|
@@ -83,15 +86,15 @@ const props = defineProps({
|
|
|
83
86
|
pagePadding: { type: Number, default: 1, validator: (v) => v > 0 },
|
|
84
87
|
pageGap: { type: Number, default: 2, validator: (v) => v > 0 },
|
|
85
88
|
hidePrevNext: { type: Boolean, default: false },
|
|
86
|
-
})
|
|
89
|
+
})
|
|
87
90
|
|
|
88
|
-
const emit = defineEmits(["update"])
|
|
91
|
+
const emit = defineEmits(["update"])
|
|
89
92
|
|
|
90
93
|
// Computed state for prev/next disabled
|
|
91
|
-
const isFirstPage = computed(() => props.currentPage === 1)
|
|
94
|
+
const isFirstPage = computed(() => props.currentPage === 1)
|
|
92
95
|
const isLastPage = computed(
|
|
93
|
-
() => props.currentPage === props.totalPages || props.totalPages === 0
|
|
94
|
-
)
|
|
96
|
+
() => props.currentPage === props.totalPages || props.totalPages === 0,
|
|
97
|
+
)
|
|
95
98
|
|
|
96
99
|
// Generate pages and gap positions
|
|
97
100
|
const renderPages = computed(() => {
|
|
@@ -99,41 +102,41 @@ const renderPages = computed(() => {
|
|
|
99
102
|
key: `page-${pageIndex}`,
|
|
100
103
|
value: pageIndex,
|
|
101
104
|
current: pageIndex === props.currentPage,
|
|
102
|
-
})
|
|
103
|
-
const createGap = (pageIndex) => ({ key: `gap-${pageIndex}`, isGap: true })
|
|
105
|
+
})
|
|
106
|
+
const createGap = (pageIndex) => ({ key: `gap-${pageIndex}`, isGap: true })
|
|
104
107
|
|
|
105
|
-
const pages = []
|
|
108
|
+
const pages = []
|
|
106
109
|
for (let i = 1; i <= props.totalPages; i++) {
|
|
107
110
|
if (
|
|
108
111
|
i === props.currentPage ||
|
|
109
112
|
i < props.pageGap ||
|
|
110
113
|
i > props.totalPages - props.pageGap + 1
|
|
111
114
|
) {
|
|
112
|
-
pages.push(createPage(i))
|
|
113
|
-
continue
|
|
115
|
+
pages.push(createPage(i))
|
|
116
|
+
continue
|
|
114
117
|
}
|
|
115
118
|
|
|
116
|
-
let min, max
|
|
119
|
+
let min, max
|
|
117
120
|
if (props.currentPage <= props.pageGap + props.pagePadding) {
|
|
118
|
-
min = props.pageGap + 1
|
|
119
|
-
max = min + props.pagePadding * 2
|
|
121
|
+
min = props.pageGap + 1
|
|
122
|
+
max = min + props.pagePadding * 2
|
|
120
123
|
} else if (
|
|
121
124
|
props.currentPage >=
|
|
122
125
|
props.totalPages - props.pageGap - props.pagePadding
|
|
123
126
|
) {
|
|
124
|
-
max = props.totalPages - props.pageGap
|
|
125
|
-
min = max - props.pagePadding * 2
|
|
127
|
+
max = props.totalPages - props.pageGap
|
|
128
|
+
min = max - props.pagePadding * 2
|
|
126
129
|
} else {
|
|
127
|
-
min = props.currentPage - props.pagePadding
|
|
128
|
-
max = props.currentPage + props.pagePadding
|
|
130
|
+
min = props.currentPage - props.pagePadding
|
|
131
|
+
max = props.currentPage + props.pagePadding
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
if (
|
|
132
135
|
(i >= min && i <= props.currentPage) ||
|
|
133
136
|
(i <= max && i >= props.currentPage)
|
|
134
137
|
) {
|
|
135
|
-
pages.push(createPage(i))
|
|
136
|
-
continue
|
|
138
|
+
pages.push(createPage(i))
|
|
139
|
+
continue
|
|
137
140
|
}
|
|
138
141
|
|
|
139
142
|
if (i === props.pageGap) {
|
|
@@ -141,11 +144,11 @@ const renderPages = computed(() => {
|
|
|
141
144
|
min > props.pageGap + 1 &&
|
|
142
145
|
props.currentPage > props.pageGap + props.pagePadding + 1
|
|
143
146
|
) {
|
|
144
|
-
pages.push(createGap(i))
|
|
147
|
+
pages.push(createGap(i))
|
|
145
148
|
} else {
|
|
146
|
-
pages.push(createPage(i))
|
|
149
|
+
pages.push(createPage(i))
|
|
147
150
|
}
|
|
148
|
-
continue
|
|
151
|
+
continue
|
|
149
152
|
}
|
|
150
153
|
|
|
151
154
|
if (i === props.totalPages - props.pageGap + 1) {
|
|
@@ -153,28 +156,28 @@ const renderPages = computed(() => {
|
|
|
153
156
|
max < props.totalPages - props.pageGap &&
|
|
154
157
|
props.currentPage < props.totalPages - props.pageGap - props.pagePadding
|
|
155
158
|
) {
|
|
156
|
-
pages.push(createGap(i))
|
|
159
|
+
pages.push(createGap(i))
|
|
157
160
|
} else {
|
|
158
|
-
pages.push(createPage(i))
|
|
161
|
+
pages.push(createPage(i))
|
|
159
162
|
}
|
|
160
|
-
continue
|
|
163
|
+
continue
|
|
161
164
|
}
|
|
162
165
|
}
|
|
163
|
-
return pages
|
|
164
|
-
})
|
|
166
|
+
return pages
|
|
167
|
+
})
|
|
165
168
|
|
|
166
169
|
// Calculate page to jump when clicking gap
|
|
167
170
|
const getGapPage = (index) => {
|
|
168
|
-
const before = renderPages.value[index - 1]
|
|
169
|
-
const after = renderPages.value[index + 1] || { value: props.totalPages }
|
|
170
|
-
return Math.floor((before.value + after.value) / 2)
|
|
171
|
-
}
|
|
171
|
+
const before = renderPages.value[index - 1]
|
|
172
|
+
const after = renderPages.value[index + 1] || { value: props.totalPages }
|
|
173
|
+
return Math.floor((before.value + after.value) / 2)
|
|
174
|
+
}
|
|
172
175
|
|
|
173
176
|
function onChange(page) {
|
|
174
|
-
emit("update", page)
|
|
177
|
+
emit("update", page)
|
|
175
178
|
}
|
|
176
179
|
</script>
|
|
177
180
|
|
|
178
181
|
<style scoped>
|
|
179
|
-
.page-button{background-color:transparent;border:1px solid rgba(0,0,0,.2);
|
|
182
|
+
.ellipsis-btn,.next-btn,.page-button,.prev-btn{background-color:transparent;border:1px solid rgba(0,0,0,.2);font-size:16px;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}
|
|
180
183
|
</style>
|
|
@@ -1,28 +1,30 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<ListMoleculesHeader :type="type" />
|
|
3
|
-
<component
|
|
3
|
+
<component
|
|
4
|
+
:is="view"
|
|
5
|
+
:loading="$stores[type] && $stores[type].loading && pending"
|
|
6
|
+
>
|
|
4
7
|
<component
|
|
5
8
|
:is="itemTemplate"
|
|
6
9
|
v-for="(item, index) in items"
|
|
7
|
-
:key="index"
|
|
8
|
-
:item
|
|
9
|
-
:index
|
|
10
|
+
:key="(item.name || item.lastname) + type + index"
|
|
11
|
+
:item
|
|
12
|
+
:index
|
|
13
|
+
:loading="$stores[type] && $stores[type].loading && pending"
|
|
14
|
+
:pathPrefix="
|
|
15
|
+
localePath({ name: pathPrefix, params: { slug: item.slug } })
|
|
16
|
+
"
|
|
10
17
|
/>
|
|
11
18
|
</component>
|
|
12
19
|
<div class="text-center">
|
|
13
|
-
<ListAtomsPerPage
|
|
14
|
-
v-if="numberOfPages > 1"
|
|
15
|
-
:type="type"
|
|
16
|
-
class="float-right"
|
|
17
|
-
/>
|
|
20
|
+
<ListAtomsPerPage :type="type" class="float-right" />
|
|
18
21
|
|
|
19
22
|
<ListMoleculesPagination
|
|
20
|
-
v-if="numberOfPages > 1"
|
|
21
|
-
:type
|
|
22
|
-
color="black"
|
|
23
|
+
v-if="$stores[type].numberOfPages > 1"
|
|
24
|
+
:type
|
|
23
25
|
large
|
|
24
|
-
:current-page="page"
|
|
25
|
-
:total-pages="numberOfPages"
|
|
26
|
+
:current-page="$stores[type].page"
|
|
27
|
+
:total-pages="$stores[type].numberOfPages"
|
|
26
28
|
:page-padding="1"
|
|
27
29
|
:page-gap="2"
|
|
28
30
|
:hide-prev-next="false"
|
|
@@ -32,23 +34,25 @@
|
|
|
32
34
|
</template>
|
|
33
35
|
|
|
34
36
|
<script setup>
|
|
35
|
-
import {
|
|
37
|
+
import { computed, onUpdated, onMounted, watch } from "vue"
|
|
36
38
|
import { useRootStore } from "../../../stores/root"
|
|
37
39
|
import { capitalize } from "../../../composables/useUtils"
|
|
38
40
|
import {
|
|
39
41
|
useNuxtApp,
|
|
40
42
|
resolveComponent,
|
|
41
|
-
computed,
|
|
42
43
|
onBeforeUnmount,
|
|
43
|
-
onMounted,
|
|
44
44
|
useI18n,
|
|
45
45
|
useRoute,
|
|
46
|
-
|
|
46
|
+
useLocalePath,
|
|
47
|
+
useAsyncQuery,
|
|
47
48
|
} from "#imports"
|
|
48
|
-
|
|
49
|
+
|
|
50
|
+
const { $stores, $queries } = useNuxtApp()
|
|
49
51
|
const { locale } = useI18n()
|
|
50
52
|
const route = useRoute()
|
|
51
53
|
const rootStore = useRootStore()
|
|
54
|
+
const localePath = useLocalePath()
|
|
55
|
+
|
|
52
56
|
const props = defineProps({
|
|
53
57
|
addBtn: {
|
|
54
58
|
type: Boolean,
|
|
@@ -60,7 +64,7 @@ const props = defineProps({
|
|
|
60
64
|
default: "people",
|
|
61
65
|
required: true,
|
|
62
66
|
},
|
|
63
|
-
layout: {
|
|
67
|
+
/* layout: {
|
|
64
68
|
type: Object,
|
|
65
69
|
required: false,
|
|
66
70
|
default: () => {
|
|
@@ -69,88 +73,119 @@ const props = defineProps({
|
|
|
69
73
|
xl: 12,
|
|
70
74
|
}
|
|
71
75
|
},
|
|
76
|
+
}, */
|
|
77
|
+
pathPrefix: {
|
|
78
|
+
type: String,
|
|
79
|
+
required: true,
|
|
72
80
|
},
|
|
73
|
-
|
|
74
|
-
type: Object,
|
|
75
|
-
required: false,
|
|
76
|
-
default: () => {
|
|
77
|
-
return {}
|
|
78
|
-
},
|
|
79
|
-
},
|
|
81
|
+
|
|
80
82
|
addButton: {
|
|
81
83
|
type: Boolean,
|
|
82
84
|
required: false,
|
|
83
85
|
default: false,
|
|
84
86
|
},
|
|
85
|
-
items: [Object],
|
|
86
87
|
})
|
|
87
88
|
|
|
89
|
+
// Initialize loading state
|
|
90
|
+
console.log("start llocal loading from setup")
|
|
91
|
+
rootStore.setLoading(true, props.type)
|
|
92
|
+
|
|
93
|
+
// Initial route -> store (single source-of-truth on first load)
|
|
94
|
+
rootStore.loadRouteQuery(props.type)
|
|
95
|
+
|
|
96
|
+
// Computed properties for dynamic components
|
|
88
97
|
const view = computed(() =>
|
|
89
98
|
props.customView
|
|
90
99
|
? resolveComponent("ListViews" + capitalize(props.customView))
|
|
91
|
-
: resolveComponent(
|
|
100
|
+
: resolveComponent(
|
|
101
|
+
"ListViews" + capitalize($stores[props.type]?.view?.name || "list"),
|
|
102
|
+
),
|
|
92
103
|
)
|
|
93
104
|
const itemTemplate = computed(() =>
|
|
94
105
|
resolveComponent(
|
|
95
106
|
(
|
|
96
107
|
capitalize(props.type) +
|
|
97
|
-
capitalize($stores[props.type]
|
|
108
|
+
capitalize($stores[props.type]?.view?.name || "list") +
|
|
98
109
|
"Item"
|
|
99
|
-
).toString()
|
|
100
|
-
)
|
|
110
|
+
).toString(),
|
|
111
|
+
),
|
|
101
112
|
)
|
|
102
|
-
const numberOfPages = computed(() => $stores[props.type].numberOfPages)
|
|
103
113
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
// Apollo: reactive query using variables computed from store
|
|
115
|
+
const variables = computed(() => {
|
|
116
|
+
console.log("computed variables loop")
|
|
117
|
+
return rootStore.buildListVariables(props.type, locale.value)
|
|
107
118
|
})
|
|
119
|
+
console.log("Starting query for type: ", props.type)
|
|
120
|
+
console.log("Using variables: ", variables.value)
|
|
108
121
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
console.error("Error fetching list:", e)
|
|
130
|
-
}
|
|
131
|
-
})
|
|
122
|
+
// Apollo GraphQL query with proper reactivity
|
|
123
|
+
const { data, pending, error, refresh } = await useAsyncQuery(
|
|
124
|
+
$queries[props.type]?.list,
|
|
125
|
+
variables, // Pass the reactive computed, not its value
|
|
126
|
+
{
|
|
127
|
+
key: `list-${props.type}`, // Unique key for caching
|
|
128
|
+
server: true, // Enable SSR
|
|
129
|
+
},
|
|
130
|
+
)
|
|
131
|
+
if (error.value) {
|
|
132
|
+
console.error("GraphQL query error: ", error.value)
|
|
133
|
+
} else {
|
|
134
|
+
console.log("Query result data: ", data.value.items?.length)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Apply data to store immediately if available
|
|
138
|
+
if (data.value) {
|
|
139
|
+
console.log("Applying data to store directly [first load scenario]")
|
|
140
|
+
rootStore.applyListResult(props.type, data.value)
|
|
141
|
+
}
|
|
132
142
|
|
|
143
|
+
// Watch for variable changes to refresh and apply new data
|
|
133
144
|
watch(
|
|
134
|
-
|
|
135
|
-
async (
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
145
|
+
variables,
|
|
146
|
+
async (newVars, oldVars) => {
|
|
147
|
+
if (newVars && JSON.stringify(newVars) !== JSON.stringify(oldVars)) {
|
|
148
|
+
console.log("Variables changed, refreshing query, newVars: ", newVars)
|
|
149
|
+
console.log("start local loading from computed")
|
|
150
|
+
rootStore.setLoading(true, props.type)
|
|
151
|
+
await refresh()
|
|
152
|
+
if (data.value) {
|
|
153
|
+
console.log("Applying refreshed data to store")
|
|
154
|
+
rootStore.applyListResult(props.type, data.value)
|
|
155
|
+
}
|
|
156
|
+
rootStore.setLoading(false, props.type)
|
|
139
157
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
window.scrollTo({ top: 0, behavior: "smooth" })
|
|
143
|
-
}
|
|
158
|
+
},
|
|
159
|
+
{ deep: true },
|
|
144
160
|
)
|
|
161
|
+
|
|
162
|
+
// Reactive items computed from the store (single source of truth)
|
|
163
|
+
const items = computed(() => $stores[props.type]?.items || [])
|
|
164
|
+
|
|
165
|
+
onMounted(() => {
|
|
166
|
+
// On initial mount: clear loading state
|
|
167
|
+
console.log("STOP local loading from mounted")
|
|
168
|
+
rootStore.setLoading(false, props.type)
|
|
169
|
+
})
|
|
170
|
+
|
|
145
171
|
onBeforeUnmount(() => {
|
|
146
172
|
rootStore.resetState(props.type, locale.value)
|
|
147
173
|
})
|
|
148
174
|
|
|
149
175
|
async function onPageChange(newPage) {
|
|
150
|
-
|
|
176
|
+
console.log("onPageChange: ", newPage)
|
|
177
|
+
rootStore.updatePage({
|
|
151
178
|
page: newPage,
|
|
152
179
|
type: props.type,
|
|
153
180
|
lang: locale.value,
|
|
154
181
|
})
|
|
182
|
+
if (typeof window !== "undefined") {
|
|
183
|
+
window.scrollTo({ top: 0, behavior: "smooth" })
|
|
184
|
+
}
|
|
155
185
|
}
|
|
186
|
+
/*
|
|
187
|
+
onUpdated(() => {
|
|
188
|
+
console.log("STOP local loading from updated")
|
|
189
|
+
rootStore.setLoading(false, props.type)
|
|
190
|
+
}) */
|
|
156
191
|
</script>
|
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
|
|
2
|
+
<v-row
|
|
3
|
+
class="highlight-on-hover pa-3"
|
|
4
|
+
no-gutters
|
|
5
|
+
@click="$router.push(pathPrefix)"
|
|
6
|
+
>
|
|
7
|
+
<v-col cols="12" class="px-6">
|
|
8
|
+
<v-skeleton-loader v-if="isLoading" type="heading, text@8, button" />
|
|
9
|
+
<template v-else>
|
|
10
|
+
<div class="text-h5">{{ item.name }}</div>
|
|
11
|
+
<div v-if="item.summary" class="mt-2">
|
|
12
|
+
<MDC :value="item.summary" />
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
</v-col>
|
|
16
|
+
</v-row>
|
|
17
|
+
<v-divider />
|
|
3
18
|
</template>
|
|
4
19
|
|
|
5
20
|
<script setup>
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
21
|
+
import { computed } from "#imports"
|
|
22
|
+
import { useRootStore } from "../../stores/root"
|
|
23
|
+
|
|
24
|
+
const rootStore = useRootStore()
|
|
25
|
+
const props = defineProps({
|
|
26
|
+
item: { type: Object, required: true },
|
|
27
|
+
pathPrefix: { type: String, required: true },
|
|
28
|
+
loading: { type: Boolean, default: false },
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const isLoading = computed(() => rootStore.loading || props.loading)
|
|
12
32
|
</script>
|
|
13
33
|
|
|
14
34
|
<style></style>
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
</template>
|
|
4
4
|
|
|
5
5
|
<script setup>
|
|
6
|
-
import { useNuxtApp } from "#imports"
|
|
6
|
+
import { useNuxtApp } from "#imports"
|
|
7
7
|
|
|
8
|
-
const { $stores } = useNuxtApp()
|
|
8
|
+
const { $stores } = useNuxtApp()
|
|
9
9
|
defineProps({
|
|
10
10
|
item: {
|
|
11
11
|
type: Object,
|
|
@@ -16,7 +16,7 @@ defineProps({
|
|
|
16
16
|
required: false,
|
|
17
17
|
default: false,
|
|
18
18
|
},
|
|
19
|
-
})
|
|
19
|
+
})
|
|
20
20
|
|
|
21
|
-
$stores.mailing.loading = false
|
|
21
|
+
$stores.mailing.loading = false
|
|
22
22
|
</script>
|
|
@@ -8,46 +8,7 @@
|
|
|
8
8
|
<v-skeleton-loader v-if="loading" height="100%" type="image" />
|
|
9
9
|
|
|
10
10
|
<template v-else>
|
|
11
|
-
<
|
|
12
|
-
v-if="link"
|
|
13
|
-
v-slot="{ navigate, isActive }"
|
|
14
|
-
:to="
|
|
15
|
-
localePath({
|
|
16
|
-
name: link,
|
|
17
|
-
params: { slug },
|
|
18
|
-
})
|
|
19
|
-
"
|
|
20
|
-
custom
|
|
21
|
-
>
|
|
22
|
-
<div class="overflow-hidden mw-100">
|
|
23
|
-
<!-- TODO debug why the picture is not displaying/sizing properly -->
|
|
24
|
-
<v-img
|
|
25
|
-
v-if="src"
|
|
26
|
-
:aspect-ratio="ratio"
|
|
27
|
-
:active="isActive"
|
|
28
|
-
:class="{ 'img-animation': animate }"
|
|
29
|
-
:lazy-src="
|
|
30
|
-
img(computedSrc, {
|
|
31
|
-
width,
|
|
32
|
-
quality: 70,
|
|
33
|
-
})
|
|
34
|
-
"
|
|
35
|
-
:src="
|
|
36
|
-
img(computedSrc, {
|
|
37
|
-
width,
|
|
38
|
-
quality: 70,
|
|
39
|
-
})
|
|
40
|
-
"
|
|
41
|
-
:srcset="_srcset.srcset"
|
|
42
|
-
:sizes="_srcset.sizes"
|
|
43
|
-
:title="caption"
|
|
44
|
-
v-bind="$attrs"
|
|
45
|
-
@click="navigate"
|
|
46
|
-
>
|
|
47
|
-
<slot />
|
|
48
|
-
</v-img></div
|
|
49
|
-
></nuxt-link>
|
|
50
|
-
<div v-else class="overflow-hidden mw-100">
|
|
11
|
+
<div class="overflow-hidden mw-100">
|
|
51
12
|
<!-- TODO debug why the picture is not displaying/sizing properly -->
|
|
52
13
|
<v-img
|
|
53
14
|
v-if="src"
|
|
@@ -78,8 +39,7 @@
|
|
|
78
39
|
</template>
|
|
79
40
|
|
|
80
41
|
<script setup>
|
|
81
|
-
import { computed, useImage
|
|
82
|
-
const localePath = useLocalePath()
|
|
42
|
+
import { computed, useImage } from "#imports"
|
|
83
43
|
const img = useImage()
|
|
84
44
|
|
|
85
45
|
const computedSrc = computed(() => {
|
|
@@ -105,8 +65,6 @@ const props = defineProps({
|
|
|
105
65
|
width: { type: Number, default: 0 },
|
|
106
66
|
ratio: { type: Number, required: true, default: 1 },
|
|
107
67
|
caption: { type: String, default: "" },
|
|
108
|
-
slug: { type: [Object, String], default: "" },
|
|
109
|
-
link: { type: String, default: "" },
|
|
110
68
|
animate: { type: Boolean, default: true },
|
|
111
69
|
})
|
|
112
70
|
const _srcset = computed(() => {
|
|
@@ -119,7 +77,7 @@ const _srcset = computed(() => {
|
|
|
119
77
|
quality: 70,
|
|
120
78
|
...(props.width && { width: props.width }),
|
|
121
79
|
},
|
|
122
|
-
}
|
|
80
|
+
},
|
|
123
81
|
)
|
|
124
82
|
})
|
|
125
83
|
</script>
|