@paris-ias/list 1.0.137 → 1.0.139
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 -14
- package/dist/runtime/components/actions/RowsItem.vue +56 -10
- package/dist/runtime/components/actions/View.vue +5 -17
- package/dist/runtime/components/affiliation/DenseItem.vue +26 -10
- package/dist/runtime/components/affiliation/RowsItem.vue +26 -10
- package/dist/runtime/components/apps/DenseItem.vue +26 -10
- package/dist/runtime/components/apps/RowsItem.vue +26 -10
- package/dist/runtime/components/disciplines/DenseItem.vue +26 -10
- package/dist/runtime/components/disciplines/RowsItem.vue +26 -10
- package/dist/runtime/components/events/DenseItem.vue +12 -3
- package/dist/runtime/components/events/RowsItem.vue +12 -5
- package/dist/runtime/components/fellowships/DenseItem.vue +14 -0
- package/dist/runtime/components/fellowships/RowsItem.vue +16 -2
- package/dist/runtime/components/fellowships/View.vue +2 -2
- package/dist/runtime/components/files/DenseItem.vue +25 -10
- package/dist/runtime/components/files/RowsItem.vue +26 -10
- 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 +4 -4
- package/dist/runtime/components/list/molecules/GlobalSearchInput.vue +12 -14
- package/dist/runtime/components/list/molecules/Header.vue +11 -20
- package/dist/runtime/components/list/molecules/Pagination.vue +51 -48
- package/dist/runtime/components/list/molecules/ResultsContainer.vue +5 -2
- package/dist/runtime/components/list/organisms/List.vue +105 -74
- package/dist/runtime/components/list/organisms/Results.vue +31 -17
- package/dist/runtime/components/mailing/RowsItem.vue +26 -10
- package/dist/runtime/components/news/DenseItem.vue +59 -45
- package/dist/runtime/components/news/RowsItem.vue +11 -7
- package/dist/runtime/components/people/DenseItem.vue +10 -8
- package/dist/runtime/components/people/RowsItem.vue +11 -2
- package/dist/runtime/components/projects/DenseItem.vue +11 -4
- package/dist/runtime/components/projects/RowsItem.vue +10 -3
- package/dist/runtime/components/publications/DenseItem.vue +12 -8
- package/dist/runtime/components/publications/RowsItem.vue +12 -4
- package/dist/runtime/components/tags/RowsItem.vue +23 -10
- package/dist/runtime/components/users/DenseItem.vue +24 -10
- package/dist/runtime/components/users/RowsItem.vue +24 -10
- 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 +82 -117
- package/package.json +1 -1
|
@@ -1,34 +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"
|
|
10
14
|
:pathPrefix="
|
|
11
|
-
localePath({
|
|
12
|
-
name: pathPrefix,
|
|
13
|
-
params: { slug: item.slug },
|
|
14
|
-
})
|
|
15
|
+
localePath({ name: pathPrefix, params: { slug: item.slug } })
|
|
15
16
|
"
|
|
16
17
|
/>
|
|
17
18
|
</component>
|
|
18
19
|
<div class="text-center">
|
|
19
|
-
<ListAtomsPerPage
|
|
20
|
-
v-if="numberOfPages > 1"
|
|
21
|
-
:type="type"
|
|
22
|
-
class="float-right"
|
|
23
|
-
/>
|
|
20
|
+
<ListAtomsPerPage :type="type" class="float-right" />
|
|
24
21
|
|
|
25
22
|
<ListMoleculesPagination
|
|
26
|
-
v-if="numberOfPages > 1"
|
|
27
|
-
:type
|
|
28
|
-
color="black"
|
|
23
|
+
v-if="$stores[type].numberOfPages > 1"
|
|
24
|
+
:type
|
|
29
25
|
large
|
|
30
|
-
:current-page="page"
|
|
31
|
-
:total-pages="numberOfPages"
|
|
26
|
+
:current-page="$stores[type].page"
|
|
27
|
+
:total-pages="$stores[type].numberOfPages"
|
|
32
28
|
:page-padding="1"
|
|
33
29
|
:page-gap="2"
|
|
34
30
|
:hide-prev-next="false"
|
|
@@ -38,21 +34,20 @@
|
|
|
38
34
|
</template>
|
|
39
35
|
|
|
40
36
|
<script setup>
|
|
41
|
-
import {
|
|
37
|
+
import { computed, onUpdated, onMounted, watch } from "vue"
|
|
42
38
|
import { useRootStore } from "../../../stores/root"
|
|
43
39
|
import { capitalize } from "../../../composables/useUtils"
|
|
44
40
|
import {
|
|
45
41
|
useNuxtApp,
|
|
46
42
|
resolveComponent,
|
|
47
|
-
computed,
|
|
48
43
|
onBeforeUnmount,
|
|
49
|
-
onMounted,
|
|
50
44
|
useI18n,
|
|
51
45
|
useRoute,
|
|
52
|
-
navigateTo,
|
|
53
46
|
useLocalePath,
|
|
47
|
+
useAsyncQuery,
|
|
54
48
|
} from "#imports"
|
|
55
|
-
|
|
49
|
+
|
|
50
|
+
const { $stores, $queries } = useNuxtApp()
|
|
56
51
|
const { locale } = useI18n()
|
|
57
52
|
const route = useRoute()
|
|
58
53
|
const rootStore = useRootStore()
|
|
@@ -69,7 +64,7 @@ const props = defineProps({
|
|
|
69
64
|
default: "people",
|
|
70
65
|
required: true,
|
|
71
66
|
},
|
|
72
|
-
layout: {
|
|
67
|
+
/* layout: {
|
|
73
68
|
type: Object,
|
|
74
69
|
required: false,
|
|
75
70
|
default: () => {
|
|
@@ -78,94 +73,130 @@ const props = defineProps({
|
|
|
78
73
|
xl: 12,
|
|
79
74
|
}
|
|
80
75
|
},
|
|
81
|
-
},
|
|
76
|
+
}, */
|
|
82
77
|
pathPrefix: {
|
|
83
78
|
type: String,
|
|
84
79
|
required: true,
|
|
85
80
|
},
|
|
86
|
-
|
|
87
|
-
type: Object,
|
|
88
|
-
required: false,
|
|
89
|
-
default: () => {
|
|
90
|
-
return {}
|
|
91
|
-
},
|
|
92
|
-
},
|
|
81
|
+
|
|
93
82
|
addButton: {
|
|
94
83
|
type: Boolean,
|
|
95
84
|
required: false,
|
|
96
85
|
default: false,
|
|
97
86
|
},
|
|
98
|
-
items: [Object],
|
|
99
87
|
})
|
|
100
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
|
|
101
97
|
const view = computed(() =>
|
|
102
98
|
props.customView
|
|
103
99
|
? resolveComponent("ListViews" + capitalize(props.customView))
|
|
104
|
-
: resolveComponent(
|
|
100
|
+
: resolveComponent(
|
|
101
|
+
"ListViews" + capitalize($stores[props.type]?.view?.name || "list"),
|
|
102
|
+
),
|
|
105
103
|
)
|
|
106
104
|
const itemTemplate = computed(() =>
|
|
107
105
|
resolveComponent(
|
|
108
106
|
(
|
|
109
107
|
capitalize(props.type) +
|
|
110
|
-
capitalize($stores[props.type]
|
|
108
|
+
capitalize($stores[props.type]?.view?.name || "list") +
|
|
111
109
|
"Item"
|
|
112
110
|
).toString(),
|
|
113
111
|
),
|
|
114
112
|
)
|
|
115
|
-
const numberOfPages = computed(() => $stores[props.type].numberOfPages)
|
|
116
113
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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)
|
|
120
118
|
})
|
|
119
|
+
console.log("Starting query for type: ", props.type)
|
|
120
|
+
console.log("Using variables: ", variables.value)
|
|
121
121
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
})
|
|
137
|
-
}
|
|
138
|
-
// Fetch initial items
|
|
139
|
-
try {
|
|
140
|
-
await rootStore.update(props.type, locale.value)
|
|
141
|
-
} catch (e) {
|
|
142
|
-
console.error("Error fetching list:", e)
|
|
143
|
-
}
|
|
144
|
-
})
|
|
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
|
+
}
|
|
145
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
|
+
}
|
|
142
|
+
|
|
143
|
+
// Watch for variable changes to refresh and apply new data
|
|
146
144
|
watch(
|
|
147
|
-
|
|
148
|
-
async (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
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)
|
|
152
157
|
}
|
|
153
|
-
navigateTo({ query }, { replace: true })
|
|
154
|
-
await nextTick()
|
|
155
|
-
window.scrollTo({ top: 0, behavior: "smooth" })
|
|
156
158
|
},
|
|
159
|
+
{ deep: true },
|
|
157
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
|
+
|
|
158
171
|
onBeforeUnmount(() => {
|
|
159
172
|
rootStore.resetState(props.type, locale.value)
|
|
160
173
|
})
|
|
161
|
-
|
|
162
174
|
async function onPageChange(newPage) {
|
|
163
|
-
|
|
175
|
+
console.log("onPageChange: ", newPage)
|
|
176
|
+
|
|
177
|
+
// Set loading state first
|
|
178
|
+
rootStore.setLoading(true, props.type)
|
|
179
|
+
|
|
180
|
+
// Update the page in the store
|
|
181
|
+
rootStore.updatePage({
|
|
164
182
|
page: newPage,
|
|
165
183
|
type: props.type,
|
|
166
184
|
lang: locale.value,
|
|
167
185
|
})
|
|
168
|
-
}
|
|
169
186
|
|
|
170
|
-
|
|
187
|
+
// Wait for the next tick to ensure DOM updates
|
|
188
|
+
await nextTick()
|
|
189
|
+
|
|
190
|
+
// Use setTimeout to ensure the scroll happens after route transition completes
|
|
191
|
+
setTimeout(() => {
|
|
192
|
+
if (typeof window !== "undefined") {
|
|
193
|
+
window.scrollTo({ top: 0, behavior: "smooth" })
|
|
194
|
+
}
|
|
195
|
+
}, 0)
|
|
196
|
+
}
|
|
197
|
+
/*
|
|
198
|
+
onUpdated(() => {
|
|
199
|
+
console.log("STOP local loading from updated")
|
|
200
|
+
rootStore.setLoading(false, props.type)
|
|
201
|
+
}) */
|
|
171
202
|
</script>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
:placeholder="$t('search')"
|
|
5
5
|
variant="outlined"
|
|
6
6
|
:categories="selectedCategories"
|
|
7
|
+
@change="updateSearch($event)"
|
|
7
8
|
@filter-change="handleFilterChange"
|
|
8
9
|
/>
|
|
9
10
|
<ListMoleculesResultsContainer
|
|
@@ -31,8 +32,9 @@ import {
|
|
|
31
32
|
useAppConfig,
|
|
32
33
|
ref,
|
|
33
34
|
computed,
|
|
35
|
+
watch,
|
|
34
36
|
} from "#imports"
|
|
35
|
-
|
|
37
|
+
import SEARCH from "../../../graphql/list/search.gql"
|
|
36
38
|
// Component name for linting
|
|
37
39
|
defineOptions({
|
|
38
40
|
name: "SearchResults",
|
|
@@ -70,24 +72,36 @@ const filteredSortedModules = computed(() => {
|
|
|
70
72
|
)
|
|
71
73
|
})
|
|
72
74
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
// Apollo GraphQL query with proper reactivity
|
|
76
|
+
const { data, pending, error, refresh } = await useAsyncQuery(
|
|
77
|
+
SEARCH,
|
|
78
|
+
{ search: $rootStore.search, appId: "iea", locale: locale.value },
|
|
79
|
+
{
|
|
80
|
+
key: `search-${$rootStore.search}`, // Unique key for caching
|
|
81
|
+
server: true, // Enable SSR
|
|
82
|
+
},
|
|
83
|
+
)
|
|
84
|
+
if (error.value) {
|
|
85
|
+
console.error("GraphQL query error: ", error.value)
|
|
86
|
+
} else {
|
|
87
|
+
console.log("Query result data: ", data.value.items?.length)
|
|
88
|
+
}
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
90
|
+
// Apply data to store immediately if available
|
|
91
|
+
if (data.value) {
|
|
92
|
+
console.log("Applying data to store directly [first load scenario]")
|
|
93
|
+
$rootStore.applyListResult("all", data.value)
|
|
94
|
+
}
|
|
95
|
+
const updateSearch = async (newSearch) => {
|
|
96
|
+
console.log("update search")
|
|
97
|
+
if (newSearch !== $rootStore.search) {
|
|
98
|
+
await refresh()
|
|
99
|
+
if (data.value) {
|
|
100
|
+
console.log("Applying data to store directly [first load scenario]")
|
|
101
|
+
$rootStore.applyListResult("all", data.value)
|
|
102
|
+
}
|
|
88
103
|
}
|
|
89
|
-
}
|
|
90
|
-
|
|
104
|
+
}
|
|
91
105
|
onBeforeUnmount(() => {
|
|
92
106
|
/* rootStore.resetState("all", locale.value) */
|
|
93
107
|
})
|
|
@@ -1,18 +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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
},
|
|
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 },
|
|
15
29
|
})
|
|
30
|
+
|
|
31
|
+
const isLoading = computed(() => rootStore.loading || props.loading)
|
|
16
32
|
</script>
|
|
17
33
|
|
|
18
34
|
<style></style>
|
|
@@ -1,53 +1,60 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
<template v-else>
|
|
17
|
-
<v-skeleton-loader
|
|
18
|
-
v-if="rootStore.loading"
|
|
19
|
-
:type="
|
|
20
|
-
['chip', 'chip@2', 'chip@3', 'chip@4', 'chip@4', 'chip@4'][
|
|
21
|
-
['xs', 'sm', 'md', 'lg', 'xl', 'xxl'].indexOf(name || 'md')
|
|
22
|
-
]
|
|
2
|
+
<NuxtLink
|
|
3
|
+
v-if="pathPrefix"
|
|
4
|
+
:to="pathPrefix"
|
|
5
|
+
class="text-decoration-none text-black"
|
|
6
|
+
>
|
|
7
|
+
<v-row v-ripple no-gutters class="cursor-pointer highlight-on-hover my-2">
|
|
8
|
+
<v-col v-if="mdAndUp" align-self="center" cols="1">
|
|
9
|
+
<MiscAtomsImageContainer
|
|
10
|
+
cover
|
|
11
|
+
:loading="isLoading"
|
|
12
|
+
:src="
|
|
13
|
+
item && item.image && item.image.url
|
|
14
|
+
? item.image.url
|
|
15
|
+
: '/default.png'
|
|
23
16
|
"
|
|
17
|
+
:ratio="1 / 1"
|
|
18
|
+
width="80px"
|
|
24
19
|
/>
|
|
25
|
-
|
|
20
|
+
</v-col>
|
|
21
|
+
<v-col align-self="start" class="text-h5 dense px-2 paragraph">
|
|
22
|
+
<v-skeleton-loader v-if="isLoading" type="heading" />
|
|
26
23
|
<template v-else>
|
|
27
|
-
<v-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
24
|
+
<v-skeleton-loader
|
|
25
|
+
v-if="isLoading"
|
|
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
|
+
/>
|
|
32
|
+
|
|
33
|
+
<template v-else>
|
|
34
|
+
<v-chip
|
|
35
|
+
class="ma-2"
|
|
36
|
+
style="background-color: white; color: black"
|
|
37
|
+
size="small"
|
|
38
|
+
variant="outlined"
|
|
39
|
+
>
|
|
40
|
+
{{ $t(eventCategory) }}
|
|
41
|
+
</v-chip>
|
|
42
|
+
<MiscMoleculesChipContainer :items="item.tags || []" size="small" />
|
|
43
|
+
</template>
|
|
44
|
+
<div
|
|
45
|
+
v-html="
|
|
46
|
+
$rootStore.search.length
|
|
47
|
+
? highlightAndTruncate(
|
|
48
|
+
300,
|
|
49
|
+
item.name,
|
|
50
|
+
$rootStore.search.split(' '),
|
|
51
|
+
)
|
|
52
|
+
: item.name
|
|
53
|
+
"
|
|
54
|
+
/>
|
|
36
55
|
</template>
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
$rootStore.search.length
|
|
40
|
-
? highlightAndTruncate(
|
|
41
|
-
300,
|
|
42
|
-
item.name,
|
|
43
|
-
$rootStore.search.split(' '),
|
|
44
|
-
)
|
|
45
|
-
: item.name
|
|
46
|
-
"
|
|
47
|
-
/>
|
|
48
|
-
</template>
|
|
49
|
-
</v-col>
|
|
50
|
-
</v-row>
|
|
56
|
+
</v-col> </v-row
|
|
57
|
+
></NuxtLink>
|
|
51
58
|
</template>
|
|
52
59
|
|
|
53
60
|
<script setup>
|
|
@@ -73,6 +80,11 @@ const props = defineProps({
|
|
|
73
80
|
type: String,
|
|
74
81
|
required: true,
|
|
75
82
|
},
|
|
83
|
+
loading: {
|
|
84
|
+
type: Boolean,
|
|
85
|
+
required: false,
|
|
86
|
+
default: false,
|
|
87
|
+
},
|
|
76
88
|
})
|
|
77
89
|
const eventCategory = computed(() => {
|
|
78
90
|
if (props.item.category) {
|
|
@@ -81,4 +93,6 @@ const eventCategory = computed(() => {
|
|
|
81
93
|
return "list.filters.news.category.others"
|
|
82
94
|
}
|
|
83
95
|
})
|
|
96
|
+
|
|
97
|
+
const isLoading = computed(() => props.loading)
|
|
84
98
|
</script>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
cover
|
|
7
7
|
:src="item.image.url ? item.image : '/default.png'"
|
|
8
8
|
:ratio="1 / 1"
|
|
9
|
-
:loading="
|
|
9
|
+
:loading="isLoading"
|
|
10
10
|
>
|
|
11
11
|
<v-chip class="ma-2" style="background-color: white; color: black">
|
|
12
12
|
{{ $t(eventCategory) }}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
</v-col>
|
|
16
16
|
<v-col cols="12" md="8" lg="4" class="pl-md-6">
|
|
17
17
|
<v-skeleton-loader
|
|
18
|
-
v-if="
|
|
18
|
+
v-if="isLoading"
|
|
19
19
|
:type="
|
|
20
20
|
[
|
|
21
21
|
'heading, subtitle, text@5, ossein, button',
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
</div>
|
|
45
45
|
<MiscMoleculesChipContainer
|
|
46
46
|
v-if="item.tags && item.tags.length"
|
|
47
|
-
:items="item.tags"
|
|
47
|
+
:items="item.tags || []"
|
|
48
48
|
class="mt-4"
|
|
49
49
|
/>
|
|
50
50
|
<template v-if="mdAndDown">
|
|
@@ -74,10 +74,7 @@
|
|
|
74
74
|
</v-col>
|
|
75
75
|
|
|
76
76
|
<v-col v-if="lgAndUp" cols="12" lg="5">
|
|
77
|
-
<v-skeleton-loader
|
|
78
|
-
v-if="rootStore.loading || $stores.news.loading"
|
|
79
|
-
type="text@8, ossein, button"
|
|
80
|
-
/>
|
|
77
|
+
<v-skeleton-loader v-if="isLoading" type="text@8, ossein, button" />
|
|
81
78
|
|
|
82
79
|
<template v-else>
|
|
83
80
|
<div
|
|
@@ -140,6 +137,11 @@ const props = defineProps({
|
|
|
140
137
|
type: String,
|
|
141
138
|
required: true,
|
|
142
139
|
},
|
|
140
|
+
loading: {
|
|
141
|
+
type: Boolean,
|
|
142
|
+
required: false,
|
|
143
|
+
default: false,
|
|
144
|
+
},
|
|
143
145
|
})
|
|
144
146
|
|
|
145
147
|
const processedSummary = computed(() => {
|
|
@@ -155,6 +157,8 @@ function replaceMarkdownLinksWithSlug(markdownText, slugPath) {
|
|
|
155
157
|
return `[${text}](${slugPath}?redirect=${encodedUrl})`
|
|
156
158
|
})
|
|
157
159
|
}
|
|
160
|
+
|
|
161
|
+
const isLoading = computed(() => rootStore.loading || props.loading)
|
|
158
162
|
</script>
|
|
159
163
|
|
|
160
164
|
<style></style>
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-row
|
|
3
|
-
v-ripple
|
|
4
|
-
no-gutters
|
|
5
|
-
class="cursor-pointer highlight-on-hover my-2"
|
|
6
|
-
@click="$router.push(pathPrefix)"
|
|
7
|
-
>
|
|
2
|
+
<v-row v-ripple no-gutters class="cursor-pointer highlight-on-hover my-2">
|
|
8
3
|
<v-col v-if="mdAndUp" cols="1">
|
|
9
4
|
<MiscAtomsImageContainer
|
|
10
5
|
cover
|
|
11
|
-
:loading="
|
|
6
|
+
:loading="isLoading"
|
|
12
7
|
:src="
|
|
13
8
|
item && item.image && item.image.url ? item.image.url : '/default.png'
|
|
14
9
|
"
|
|
@@ -17,7 +12,7 @@
|
|
|
17
12
|
/>
|
|
18
13
|
</v-col>
|
|
19
14
|
<v-col align-self="start" class="text-h6 dense px-2">
|
|
20
|
-
<v-skeleton-loader v-if="
|
|
15
|
+
<v-skeleton-loader v-if="isLoading" type="heading" />
|
|
21
16
|
<div v-else class="d-flex text-h5 align-center">
|
|
22
17
|
<span
|
|
23
18
|
v-html="
|
|
@@ -72,7 +67,14 @@ const props = defineProps({
|
|
|
72
67
|
type: String,
|
|
73
68
|
required: true,
|
|
74
69
|
},
|
|
70
|
+
loading: {
|
|
71
|
+
type: Boolean,
|
|
72
|
+
required: false,
|
|
73
|
+
default: false,
|
|
74
|
+
},
|
|
75
75
|
})
|
|
76
|
+
|
|
77
|
+
const isLoading = computed(() => props.loading)
|
|
76
78
|
</script>
|
|
77
79
|
<style>
|
|
78
80
|
.paragraph{max-width:83ch!important}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<v-col v-if="mdAndUp" cols="12" md="3">
|
|
8
8
|
<MiscAtomsImageContainer
|
|
9
9
|
cover
|
|
10
|
-
:loading="
|
|
10
|
+
:loading="isLoading"
|
|
11
11
|
:src="item.image.url ? item.image : '/default.png'"
|
|
12
12
|
:ratio="1 / 1"
|
|
13
13
|
/>
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
<v-col cols="12" md="8">
|
|
17
17
|
<v-skeleton-loader
|
|
18
|
-
v-if="
|
|
18
|
+
v-if="isLoading"
|
|
19
19
|
:type="
|
|
20
20
|
[
|
|
21
21
|
'heading, subtitle, text@5',
|
|
@@ -53,9 +53,11 @@
|
|
|
53
53
|
<script setup>
|
|
54
54
|
import { useDisplay } from "vuetify"
|
|
55
55
|
import { useLocalePath, computed } from "#imports"
|
|
56
|
+
import { useRootStore } from "../../stores/root"
|
|
56
57
|
|
|
57
58
|
const { name, mdAndUp } = useDisplay()
|
|
58
59
|
const localePath = useLocalePath()
|
|
60
|
+
const rootStore = useRootStore()
|
|
59
61
|
const props = defineProps({
|
|
60
62
|
item: {
|
|
61
63
|
type: Object,
|
|
@@ -65,6 +67,11 @@ const props = defineProps({
|
|
|
65
67
|
type: Number,
|
|
66
68
|
required: true,
|
|
67
69
|
},
|
|
70
|
+
loading: {
|
|
71
|
+
type: Boolean,
|
|
72
|
+
required: false,
|
|
73
|
+
default: false,
|
|
74
|
+
},
|
|
68
75
|
})
|
|
69
76
|
const lineClamp = computed(() => {
|
|
70
77
|
let base = [5, 6, 3, 6, 8, 10][
|
|
@@ -80,4 +87,6 @@ const lineClamp = computed(() => {
|
|
|
80
87
|
|
|
81
88
|
return base
|
|
82
89
|
})
|
|
90
|
+
|
|
91
|
+
const isLoading = computed(() => rootStore.loading || props.loading)
|
|
83
92
|
</script>
|