@paris-ias/list 1.2.2 → 1.3.2
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/events/DenseItem.vue +14 -11
- package/dist/runtime/components/fellowships/View.vue +29 -41
- package/dist/runtime/components/list/molecules/Filters.vue +61 -23
- package/dist/runtime/components/list/organisms/List.vue +4 -0
- package/dist/runtime/components/misc/molecules/DisciplinesTags.vue +89 -0
- package/dist/runtime/components/news/DenseItem.vue +6 -0
- package/dist/runtime/components/people/View.vue +25 -32
- package/dist/runtime/components/projects/View.vue +10 -2
- package/dist/runtime/components/publications/DenseItem.vue +8 -2
- package/dist/runtime/components/publications/View.vue +8 -2
- package/dist/runtime/stores/root.d.ts +1 -0
- package/dist/runtime/stores/root.js +7 -0
- package/dist/runtime/translations/en.json +1 -1
- package/dist/runtime/translations/fr.json +1 -1
- package/package.json +2 -2
package/dist/module.json
CHANGED
|
@@ -23,17 +23,20 @@
|
|
|
23
23
|
|
|
24
24
|
<v-col align-self="start" class="pl-md-4">
|
|
25
25
|
<v-skeleton-loader v-if="loading" type="chip" class="mr-3" width="120" />
|
|
26
|
-
<v-
|
|
27
|
-
v-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
26
|
+
<span v-else>
|
|
27
|
+
<v-chip
|
|
28
|
+
class="mr-3"
|
|
29
|
+
color="black"
|
|
30
|
+
size="small"
|
|
31
|
+
style="background-color: white; color: black"
|
|
32
|
+
tile
|
|
33
|
+
variant="outlined"
|
|
34
|
+
>
|
|
35
|
+
{{ $t("list.filters.events.category." + item.category) }}
|
|
36
|
+
</v-chip>
|
|
37
|
+
<!-- DISCIPLINES -->
|
|
38
|
+
<MiscMoleculesDisciplinesTags :disciplines="item.disciplines" inline />
|
|
39
|
+
</span>
|
|
37
40
|
<v-skeleton-loader
|
|
38
41
|
v-if="loading && smAndDown"
|
|
39
42
|
type="text"
|
|
@@ -49,12 +49,15 @@
|
|
|
49
49
|
'list.filters.fellowships.fellowshipType.' +
|
|
50
50
|
item.fellowshipType,
|
|
51
51
|
),
|
|
52
|
-
...(props.item && props.item.disciplines
|
|
53
|
-
? props.item.disciplines.map((discipline) => discipline.name)
|
|
54
|
-
: []),
|
|
55
52
|
]"
|
|
56
53
|
class="mt-2"
|
|
57
54
|
/>
|
|
55
|
+
<!-- DISCIPLINES -->
|
|
56
|
+
<MiscMoleculesDisciplinesTags
|
|
57
|
+
:disciplines="item.disciplines"
|
|
58
|
+
justify="center"
|
|
59
|
+
class="mt-4"
|
|
60
|
+
/>
|
|
58
61
|
<div class="mt-5">
|
|
59
62
|
<FellowshipsBadges :item="item" :view="view" :loading="loading" />
|
|
60
63
|
</div>
|
|
@@ -152,58 +155,43 @@
|
|
|
152
155
|
|
|
153
156
|
<script setup>
|
|
154
157
|
import { useDisplay } from "vuetify"
|
|
155
|
-
import { ref } from "#imports"
|
|
158
|
+
import { computed, ref } from "#imports"
|
|
156
159
|
const { name } = useDisplay()
|
|
157
160
|
const accordeon = ref(-1)
|
|
158
161
|
const props = defineProps({
|
|
162
|
+
// null while the resource item is loading (see useI18nResourceItem)
|
|
159
163
|
item: {
|
|
160
164
|
type: Object,
|
|
161
|
-
|
|
165
|
+
default: null,
|
|
162
166
|
},
|
|
163
167
|
loading: {
|
|
164
168
|
type: Boolean,
|
|
165
169
|
default: false,
|
|
166
|
-
required: true,
|
|
167
170
|
},
|
|
168
171
|
})
|
|
169
172
|
|
|
170
173
|
const view = ref(true)
|
|
171
174
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
housing: props.item?.fellowshipDetails?.housing,
|
|
193
|
-
}),
|
|
194
|
-
...(props.item?.fellowshipDetails?.meals && {
|
|
195
|
-
meals: props.item?.fellowshipDetails?.meals,
|
|
196
|
-
}),
|
|
197
|
-
...(props.item?.fellowshipDetails?.applicationMaterials && {
|
|
198
|
-
applicationMaterials: props.item?.fellowshipDetails?.applicationMaterials,
|
|
199
|
-
}),
|
|
200
|
-
...(props.item?.fellowshipDetails?.selectionProcess && {
|
|
201
|
-
selectionProcess: props.item?.fellowshipDetails?.selectionProcess,
|
|
202
|
-
}),
|
|
203
|
-
...(props.item?.fellowshipDetails?.researchProcess && {
|
|
204
|
-
researchProcess: props.item?.fellowshipDetails?.researchProcess,
|
|
205
|
-
}),
|
|
206
|
-
}
|
|
175
|
+
// computed (not a one-shot setup value) so it picks up `item` once it loads in
|
|
176
|
+
const renderedDetails = computed(() => {
|
|
177
|
+
const d = props.item?.fellowshipDetails
|
|
178
|
+
if (!d) return {}
|
|
179
|
+
return {
|
|
180
|
+
...(d.type && { type: d.type }),
|
|
181
|
+
...(d.fundingPeriod && { fundingPeriod: d.fundingPeriod }),
|
|
182
|
+
...(d.profile && { profile: d.profile }),
|
|
183
|
+
...(d.tasks && { tasks: d.tasks }),
|
|
184
|
+
...(d.location && { location: d.location }),
|
|
185
|
+
...(d.funding && { funding: d.funding }),
|
|
186
|
+
...(d.housing && { housing: d.housing }),
|
|
187
|
+
...(d.meals && { meals: d.meals }),
|
|
188
|
+
...(d.applicationMaterials && {
|
|
189
|
+
applicationMaterials: d.applicationMaterials,
|
|
190
|
+
}),
|
|
191
|
+
...(d.selectionProcess && { selectionProcess: d.selectionProcess }),
|
|
192
|
+
...(d.researchProcess && { researchProcess: d.researchProcess }),
|
|
193
|
+
}
|
|
194
|
+
})
|
|
207
195
|
</script>
|
|
208
196
|
|
|
209
197
|
<style lang="scss" scoped></style>
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
<v-row>
|
|
3
3
|
<template v-for="(filterItem, index) in Object.keys($stores[type].filters)">
|
|
4
4
|
<v-col
|
|
5
|
-
v-if="computeVisibility(filterItem)"
|
|
5
|
+
v-if="appAllowed(filterItem) && computeVisibility(filterItem)"
|
|
6
6
|
:key="type + index + filterItem"
|
|
7
7
|
cols="12"
|
|
8
8
|
sm="6"
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
<script setup>
|
|
45
45
|
import { useDisplay } from "vuetify"
|
|
46
46
|
import { capitalize } from "../../../composables/useUtils"
|
|
47
|
-
import { useNuxtApp, resolveComponent, useI18n } from "#imports"
|
|
47
|
+
import { useNuxtApp, resolveComponent, useI18n, useAppConfig } from "#imports"
|
|
48
48
|
|
|
49
49
|
const { smAndDown } = useDisplay()
|
|
50
50
|
const i18n = useI18n()
|
|
@@ -52,6 +52,18 @@ const { locale, messages } = useI18n()
|
|
|
52
52
|
const { $stores, $filters } = useNuxtApp()
|
|
53
53
|
const props = defineProps(["type", "expanded"])
|
|
54
54
|
|
|
55
|
+
// Consuming app id. Filters may declare an `appId` array of the consumers
|
|
56
|
+
// allowed to render them; this is the id we match against. "all" is a wildcard.
|
|
57
|
+
const appId = useAppConfig().list?.appId ?? "iea"
|
|
58
|
+
|
|
59
|
+
// A filter is shown only on the consumers it opts into. No appId -> shown
|
|
60
|
+
// everywhere (backward compatible). "all" in the list matches any consumer.
|
|
61
|
+
const appAllowed = (filterKey) => {
|
|
62
|
+
const allowed = $stores[props.type].filters[filterKey].appId
|
|
63
|
+
if (!Array.isArray(allowed) || allowed.length === 0) return true
|
|
64
|
+
return allowed.includes("all") || allowed.includes(appId)
|
|
65
|
+
}
|
|
66
|
+
|
|
55
67
|
const ComponentName = (name) => {
|
|
56
68
|
return resolveComponent(
|
|
57
69
|
"ListInputs" + capitalize($stores[props.type].filters[name].type),
|
|
@@ -62,28 +74,44 @@ const getItems = (name) => {
|
|
|
62
74
|
return []
|
|
63
75
|
}
|
|
64
76
|
|
|
77
|
+
// Disciplines and thematics are shared enums used across most list types.
|
|
78
|
+
// They live in their own top-level i18n namespace (list.filters.disciplines
|
|
79
|
+
// / list.filters.thematics) and are resolved from there for every type,
|
|
80
|
+
// independently of filters.json, to avoid duplicating them per type.
|
|
81
|
+
if (["disciplines", "thematics"].includes(name)) {
|
|
82
|
+
return Object.keys(messages.value[locale.value].list.filters?.[name])
|
|
83
|
+
.filter((key) => key !== "label")
|
|
84
|
+
.map((item) => ({
|
|
85
|
+
title: i18n.t(`list.filters.${name}.${item}`),
|
|
86
|
+
value: item,
|
|
87
|
+
}))
|
|
88
|
+
.sort((a, b) => a.title.localeCompare(b.title))
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Prefer the enum declared on the model filter (filters[name].items) over the
|
|
92
|
+
// values baked into filters.json. The model is the source of truth for enum
|
|
93
|
+
// options (e.g. publicationType), so filters.json never has to stay in sync.
|
|
94
|
+
const modelItems = $stores[props.type].filters[name].items
|
|
95
|
+
if (modelItems && typeof modelItems === "object") {
|
|
96
|
+
return Object.values(modelItems)
|
|
97
|
+
.filter((item) => item !== "label")
|
|
98
|
+
.map((item) => ({
|
|
99
|
+
title: i18n.t(`list.filters.${props.type}.${name}.${item}`),
|
|
100
|
+
value: item,
|
|
101
|
+
}))
|
|
102
|
+
}
|
|
103
|
+
|
|
65
104
|
if ($filters?.[props.type]?.[name]) {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
return $filters[props.type][name]
|
|
77
|
-
.filter((key) => key !== "label")
|
|
78
|
-
.map((item) => ({
|
|
79
|
-
title: i18n.t(
|
|
80
|
-
props.type === "people" && name === "vintage"
|
|
81
|
-
? item
|
|
82
|
-
: `list.filters.${props.type}.${name}.${item}`,
|
|
83
|
-
),
|
|
84
|
-
value: item,
|
|
85
|
-
}))
|
|
86
|
-
}
|
|
105
|
+
return $filters[props.type][name]
|
|
106
|
+
.filter((key) => key !== "label")
|
|
107
|
+
.map((item) => ({
|
|
108
|
+
title: i18n.t(
|
|
109
|
+
props.type === "people" && name === "vintage"
|
|
110
|
+
? item
|
|
111
|
+
: `list.filters.${props.type}.${name}.${item}`,
|
|
112
|
+
),
|
|
113
|
+
value: item,
|
|
114
|
+
}))
|
|
87
115
|
}
|
|
88
116
|
|
|
89
117
|
if (!messages.value[locale.value].list.filters[props.type]?.[name]) {
|
|
@@ -137,6 +165,16 @@ const computeVisibility = (filterKey) => {
|
|
|
137
165
|
|
|
138
166
|
const checkRule = (rule) =>
|
|
139
167
|
Object.entries(rule).every(([depKey, expected]) => {
|
|
168
|
+
// Reserved key: match against the active view modifier rather than a
|
|
169
|
+
// sibling filter's value. On routes like /resources/media the `type` is
|
|
170
|
+
// narrowed server-side via the modifier, so the modifier is what changes.
|
|
171
|
+
if (depKey === "modifier") {
|
|
172
|
+
const cur = $stores[props.type].modifier
|
|
173
|
+
return Array.isArray(expected)
|
|
174
|
+
? expected.includes(cur)
|
|
175
|
+
: cur === expected
|
|
176
|
+
}
|
|
177
|
+
|
|
140
178
|
const dep = filters?.[depKey]
|
|
141
179
|
if (!dep) return false
|
|
142
180
|
const cur = dep.value
|
|
@@ -117,6 +117,10 @@ const props = defineProps({
|
|
|
117
117
|
/* console.log("start llocal loading from setup") */
|
|
118
118
|
rootStore.setLoading(true, props.type)
|
|
119
119
|
|
|
120
|
+
// Mirror the route's fixed modifier into the store so the filter UI can branch
|
|
121
|
+
// its conditional visibility on it (the query still reads props.modifier directly).
|
|
122
|
+
rootStore.setModifier(props.type, props.modifier)
|
|
123
|
+
|
|
120
124
|
// Initial route -> store (single source-of-truth on first load)
|
|
121
125
|
rootStore.loadRouteQuery(props.type)
|
|
122
126
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-skeleton-loader
|
|
3
|
+
v-if="loading"
|
|
4
|
+
type="chip@3"
|
|
5
|
+
class="discipline-skeleton mt-2"
|
|
6
|
+
/>
|
|
7
|
+
<div
|
|
8
|
+
v-else-if="disciplines.length"
|
|
9
|
+
class="flex-wrap"
|
|
10
|
+
:class="[
|
|
11
|
+
inline ? 'd-inline-flex align-center' : 'd-flex',
|
|
12
|
+
justify === 'center' ? 'justify-center' : '',
|
|
13
|
+
]"
|
|
14
|
+
style="gap: 6px"
|
|
15
|
+
>
|
|
16
|
+
<v-chip
|
|
17
|
+
v-for="(d, i) in shownDisciplines"
|
|
18
|
+
:key="d + i"
|
|
19
|
+
size="small"
|
|
20
|
+
tile
|
|
21
|
+
variant="flat"
|
|
22
|
+
color="grey-lighten-3"
|
|
23
|
+
class="discipline-chip"
|
|
24
|
+
>
|
|
25
|
+
{{ disciplineLabel(d) }}
|
|
26
|
+
</v-chip>
|
|
27
|
+
<v-chip
|
|
28
|
+
v-if="extraDisciplines"
|
|
29
|
+
size="small"
|
|
30
|
+
variant="flat"
|
|
31
|
+
tile
|
|
32
|
+
color="grey-lighten-3"
|
|
33
|
+
class="discipline-chip"
|
|
34
|
+
>
|
|
35
|
+
+{{ extraDisciplines }}
|
|
36
|
+
</v-chip>
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<script setup>
|
|
41
|
+
import { computed, useI18n } from "#imports"
|
|
42
|
+
|
|
43
|
+
const { t } = useI18n()
|
|
44
|
+
|
|
45
|
+
const props = defineProps({
|
|
46
|
+
// scalar enum array (e.g. item.disciplines)
|
|
47
|
+
disciplines: {
|
|
48
|
+
type: Array,
|
|
49
|
+
default: () => [],
|
|
50
|
+
},
|
|
51
|
+
loading: {
|
|
52
|
+
type: Boolean,
|
|
53
|
+
default: false,
|
|
54
|
+
},
|
|
55
|
+
// cap the number of chips; 0 = show all (used by detail views)
|
|
56
|
+
max: {
|
|
57
|
+
type: Number,
|
|
58
|
+
default: 0,
|
|
59
|
+
},
|
|
60
|
+
// 'start' (dense list) | 'center' (detail views)
|
|
61
|
+
justify: {
|
|
62
|
+
type: String,
|
|
63
|
+
default: "start",
|
|
64
|
+
},
|
|
65
|
+
// render as inline-flex so the chips flow on the same line as preceding
|
|
66
|
+
// content (e.g. the category chip in the events dense item) instead of
|
|
67
|
+
// forcing a block-level line break
|
|
68
|
+
inline: {
|
|
69
|
+
type: Boolean,
|
|
70
|
+
default: false,
|
|
71
|
+
},
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
// normalise to an array regardless of what the caller passes
|
|
75
|
+
const disciplines = computed(() =>
|
|
76
|
+
Array.isArray(props.disciplines) ? props.disciplines : [],
|
|
77
|
+
)
|
|
78
|
+
const shownDisciplines = computed(() =>
|
|
79
|
+
props.max > 0 ? disciplines.value.slice(0, props.max) : disciplines.value,
|
|
80
|
+
)
|
|
81
|
+
const extraDisciplines = computed(() =>
|
|
82
|
+
props.max > 0 ? Math.max(0, disciplines.value.length - props.max) : 0,
|
|
83
|
+
)
|
|
84
|
+
const disciplineLabel = (d) => t("list.filters.disciplines." + d)
|
|
85
|
+
</script>
|
|
86
|
+
|
|
87
|
+
<style scoped>
|
|
88
|
+
.discipline-chip{border-radius:6px;color:rgba(0,0,0,.78);font-weight:500}.discipline-skeleton :deep(.v-skeleton-loader__chip){margin:0 6px 0 0}
|
|
89
|
+
</style>
|
|
@@ -41,6 +41,12 @@
|
|
|
41
41
|
{{ $t(eventCategory) }}
|
|
42
42
|
</v-chip>
|
|
43
43
|
<MiscMoleculesChipContainer :items="item.tags || []" size="small" />
|
|
44
|
+
<MiscMoleculesDisciplinesTags
|
|
45
|
+
v-if="item.disciplines && item.disciplines.length"
|
|
46
|
+
:disciplines="item.disciplines"
|
|
47
|
+
inline
|
|
48
|
+
class="mt-2"
|
|
49
|
+
/>
|
|
44
50
|
</template>
|
|
45
51
|
<div
|
|
46
52
|
v-html="
|
|
@@ -73,37 +73,35 @@
|
|
|
73
73
|
<div class="mt-6 align-self-center">
|
|
74
74
|
<PeopleBadges v-if="item && item.groups" :item="item" />
|
|
75
75
|
</div>
|
|
76
|
-
|
|
76
|
+
<!-- DIVIDERS -->
|
|
77
|
+
<v-responsive class="mx-auto my-6" width="120">
|
|
78
|
+
<v-divider class="mb-1" />
|
|
79
|
+
<v-divider />
|
|
80
|
+
</v-responsive>
|
|
77
81
|
<!-- FELLOWSHIP -->
|
|
78
|
-
<div
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
<!-- DISCIPLINES -->
|
|
82
|
+
<div
|
|
83
|
+
v-if="fellowshipProjectName || fellowTheme || fellowDates"
|
|
84
|
+
class=""
|
|
85
|
+
>
|
|
84
86
|
<div
|
|
85
|
-
v-if="
|
|
86
|
-
class="
|
|
87
|
-
style="gap: 6px"
|
|
87
|
+
v-if="fellowshipProjectName"
|
|
88
|
+
class="text-h6 font-weight-regular"
|
|
88
89
|
>
|
|
89
|
-
|
|
90
|
-
v-for="(d, i) in disciplines"
|
|
91
|
-
:key="d + i"
|
|
92
|
-
size="small"
|
|
93
|
-
variant="flat"
|
|
94
|
-
tile
|
|
95
|
-
color="grey-lighten-3"
|
|
96
|
-
class="discipline-chip"
|
|
97
|
-
>
|
|
98
|
-
{{ disciplineLabel(d) }}
|
|
99
|
-
</v-chip>
|
|
90
|
+
{{ fellowshipProjectName }}
|
|
100
91
|
</div>
|
|
101
|
-
|
|
92
|
+
|
|
93
|
+
<!-- DISCIPLINES -->
|
|
94
|
+
<MiscMoleculesDisciplinesTags
|
|
95
|
+
:disciplines="item.disciplines"
|
|
96
|
+
justify="center"
|
|
97
|
+
class="mt-4"
|
|
98
|
+
/>
|
|
99
|
+
<div v-if="fellowTheme" class="text-body-1 my-3 font-italic">
|
|
102
100
|
{{ fellowTheme }}
|
|
103
101
|
</div>
|
|
104
102
|
<div
|
|
105
103
|
v-if="fellowDates"
|
|
106
|
-
class="text-body-2
|
|
104
|
+
class="text-body-2 my-3 text-medium-emphasis"
|
|
107
105
|
>
|
|
108
106
|
{{ fellowDates }}
|
|
109
107
|
</div>
|
|
@@ -217,22 +215,17 @@ const { t, locale } = useI18n()
|
|
|
217
215
|
const { $stores } = useNuxtApp()
|
|
218
216
|
const { name, mdAndUp } = useDisplay()
|
|
219
217
|
const props = defineProps({
|
|
220
|
-
|
|
218
|
+
// null while the resource item is loading (see useI18nResourceItem)
|
|
219
|
+
item: { type: Object, default: null },
|
|
221
220
|
loading: { type: Boolean, default: false },
|
|
222
221
|
})
|
|
223
222
|
$stores.people.loading = false
|
|
224
223
|
|
|
225
|
-
// disciplines: scalar enum array → translated labels
|
|
226
|
-
const disciplines = computed(() =>
|
|
227
|
-
Array.isArray(props.item?.disciplines) ? props.item.disciplines : [],
|
|
228
|
-
)
|
|
229
|
-
const disciplineLabel = (d) => t("list.filters.disciplines." + d)
|
|
230
|
-
|
|
231
224
|
// latest is a union Vintage | Position; the fellowship program lives on the
|
|
232
225
|
// Vintage branch (name = program name, theme = fellowship theme) and carries the
|
|
233
226
|
// arrival/departure dates (start/stop). Guard by field presence.
|
|
234
227
|
const latest = computed(() => props.item?.latest ?? null)
|
|
235
|
-
const
|
|
228
|
+
const fellowshipProjectName = computed(() => latest.value?.name ?? null)
|
|
236
229
|
const fellowTheme = computed(() => latest.value?.theme ?? null)
|
|
237
230
|
|
|
238
231
|
// "present" = currently in residence/post: started on or before today and not
|
|
@@ -259,5 +252,5 @@ const fellowDates = computed(() => {
|
|
|
259
252
|
</script>
|
|
260
253
|
|
|
261
254
|
<style scoped>
|
|
262
|
-
.
|
|
255
|
+
.present-pill{align-items:center;background-color:rgba(0,0,0,.06);border-radius:999px;color:rgba(0,0,0,.7);display:inline-flex;font-size:.6875rem;font-weight:500;gap:5px;letter-spacing:.04em;line-height:1;padding:4px 10px;text-transform:uppercase}.present-dot{background-color:#4caf50;border-radius:50%;height:6px;width:6px}
|
|
263
256
|
</style>
|
|
@@ -45,6 +45,13 @@
|
|
|
45
45
|
>
|
|
46
46
|
<MDC v-if="item && item.subtitle" :value="item.subtitle" />
|
|
47
47
|
</div>
|
|
48
|
+
<!-- DISCIPLINES -->
|
|
49
|
+
<MiscMoleculesDisciplinesTags
|
|
50
|
+
v-if="item"
|
|
51
|
+
:disciplines="item.disciplines"
|
|
52
|
+
justify="center"
|
|
53
|
+
class="mt-4"
|
|
54
|
+
/>
|
|
48
55
|
<MiscMoleculesChipContainer
|
|
49
56
|
v-if="item && item.tags"
|
|
50
57
|
:items="item.tags"
|
|
@@ -120,13 +127,14 @@ import { useNuxtApp } from "#imports"
|
|
|
120
127
|
const { $stores } = useNuxtApp()
|
|
121
128
|
const { name } = useDisplay()
|
|
122
129
|
const props = defineProps({
|
|
130
|
+
// null while the resource item is loading (see useI18nResourceItem)
|
|
123
131
|
item: {
|
|
124
132
|
type: Object,
|
|
125
|
-
|
|
133
|
+
default: null,
|
|
126
134
|
},
|
|
127
135
|
loading: {
|
|
128
136
|
type: Boolean,
|
|
129
|
-
|
|
137
|
+
default: false,
|
|
130
138
|
},
|
|
131
139
|
})
|
|
132
140
|
</script>
|
|
@@ -46,11 +46,17 @@
|
|
|
46
46
|
:items="item.tags || []"
|
|
47
47
|
size="small"
|
|
48
48
|
/>
|
|
49
|
+
<MiscMoleculesDisciplinesTags
|
|
50
|
+
v-if="item.disciplines && item.disciplines.length"
|
|
51
|
+
:disciplines="item.disciplines"
|
|
52
|
+
inline
|
|
53
|
+
class="mt-2"
|
|
54
|
+
/>
|
|
49
55
|
</template>
|
|
50
56
|
<v-skeleton-loader v-if="loading" type="heading" />
|
|
51
|
-
<
|
|
57
|
+
<div
|
|
52
58
|
v-else
|
|
53
|
-
class="text-h5 dense paragraph"
|
|
59
|
+
class="text-h5 dense paragraph mt-2"
|
|
54
60
|
v-html="
|
|
55
61
|
searchQuery.length
|
|
56
62
|
? highlightAndTruncate(300, item.name, searchQuery.split(' '))
|
|
@@ -40,6 +40,12 @@
|
|
|
40
40
|
<div class="overline my-2">
|
|
41
41
|
{{ formatDateValue(item.date, locale) }}
|
|
42
42
|
</div>
|
|
43
|
+
<!-- DISCIPLINES -->
|
|
44
|
+
<MiscMoleculesDisciplinesTags
|
|
45
|
+
:disciplines="item.disciplines"
|
|
46
|
+
justify="center"
|
|
47
|
+
class="mt-4"
|
|
48
|
+
/>
|
|
43
49
|
<MiscMoleculesChipContainer
|
|
44
50
|
v-if="item.tags && item.tags.length"
|
|
45
51
|
:items="item.tags"
|
|
@@ -119,13 +125,13 @@ const { $stores } = useNuxtApp()
|
|
|
119
125
|
const { name } = useDisplay()
|
|
120
126
|
const { locale } = useI18n()
|
|
121
127
|
const props = defineProps({
|
|
128
|
+
// null while the resource item is loading (see useI18nResourceItem)
|
|
122
129
|
item: {
|
|
123
130
|
type: Object,
|
|
124
|
-
|
|
131
|
+
default: null,
|
|
125
132
|
},
|
|
126
133
|
loading: {
|
|
127
134
|
type: Boolean,
|
|
128
|
-
required: false,
|
|
129
135
|
default: false,
|
|
130
136
|
},
|
|
131
137
|
})
|
|
@@ -37,6 +37,7 @@ export declare const useRootStore: import("pinia").StoreDefinition<"rootStore",
|
|
|
37
37
|
loadRouteQuery(type: string): void;
|
|
38
38
|
setFiltersCount(type: string): void;
|
|
39
39
|
updateRouteQuery(type: string): void;
|
|
40
|
+
setModifier(type: string, modifier?: string): void;
|
|
40
41
|
resetState(type: string, lang?: string): void;
|
|
41
42
|
updateSort({ type, sortKey }: {
|
|
42
43
|
type: string;
|
|
@@ -113,12 +113,19 @@ export const useRootStore = defineStore("rootStore", {
|
|
|
113
113
|
};
|
|
114
114
|
router.replace({ query: routeQuery });
|
|
115
115
|
},
|
|
116
|
+
setModifier(type, modifier) {
|
|
117
|
+
const { $stores } = useNuxtApp();
|
|
118
|
+
if ($stores[type]) {
|
|
119
|
+
$stores[type].modifier = modifier;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
116
122
|
resetState(type, lang = "en") {
|
|
117
123
|
const { $stores, $models } = useNuxtApp();
|
|
118
124
|
const model = structuredClone($models[type]);
|
|
119
125
|
$stores[type].filters = model?.filters;
|
|
120
126
|
$stores[type].search = "";
|
|
121
127
|
$stores[type].page = 1;
|
|
128
|
+
$stores[type].modifier = void 0;
|
|
122
129
|
$stores[type].sortKey = null;
|
|
123
130
|
},
|
|
124
131
|
updateSort({ type, sortKey }) {
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"license": "AGPL-3.0-only",
|
|
3
3
|
"main": "./dist/module.mjs",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.2",
|
|
5
5
|
"name": "@paris-ias/list",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "git+https://github.com/IEA-Paris/list.git",
|
|
8
8
|
"type": "git"
|
|
9
9
|
},
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@paris-ias/trees": "^2.2.
|
|
11
|
+
"@paris-ias/trees": "^2.2.18"
|
|
12
12
|
},
|
|
13
13
|
"description": "Paris IAS List Module",
|
|
14
14
|
"peerDependencies": {
|