@paris-ias/list 1.0.11 → 1.0.13
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/README.md +71 -51
- package/dist/module.d.mts +8 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +64 -0
- package/dist/runtime/components/events/Badges.vue +5 -7
- package/dist/runtime/components/events/DateTimePlace.vue +11 -13
- package/dist/runtime/components/events/DenseItem.vue +7 -6
- package/dist/runtime/components/events/ExpandedItem.vue +3 -5
- package/dist/runtime/components/events/ListContainer.vue +6 -6
- package/dist/runtime/components/events/RegisterModal.vue +4 -5
- package/dist/runtime/components/events/RelatedItem.vue +6 -7
- package/dist/runtime/components/events/RowsItem.vue +12 -11
- package/dist/runtime/components/events/View.vue +10 -13
- package/dist/runtime/components/fellowships/Badges.vue +12 -15
- package/dist/runtime/components/fellowships/DenseItem.vue +7 -7
- package/dist/runtime/components/fellowships/RegisterModal.vue +3 -2
- package/dist/runtime/components/fellowships/RowsItem.vue +19 -21
- package/dist/runtime/components/fellowships/View.vue +43 -49
- package/dist/runtime/components/list/atoms/FiltersMenu.vue +6 -8
- package/dist/runtime/components/list/atoms/SearchInput.vue +42 -50
- package/dist/runtime/components/list/atoms/SearchItem.vue +14 -14
- package/dist/runtime/components/list/atoms/SearchString.vue +6 -7
- package/dist/runtime/components/list/atoms/SortMenu.vue +23 -40
- package/dist/runtime/components/list/atoms/ViewMenu.vue +14 -22
- package/dist/runtime/components/list/inputs/AutoComplete.vue +9 -9
- package/dist/runtime/components/list/inputs/BooleanSwitch.vue +9 -9
- package/dist/runtime/components/list/inputs/Checkbox.vue +11 -11
- package/dist/runtime/components/list/inputs/Select.vue +11 -11
- package/dist/runtime/components/list/molecules/Filters.vue +27 -42
- package/dist/runtime/components/list/molecules/Header.vue +5 -7
- package/dist/runtime/components/list/molecules/Pagination.vue +60 -102
- package/dist/runtime/components/list/organisms/List.vue +28 -36
- package/dist/runtime/components/list/views/Dense.vue +1 -14
- package/dist/runtime/components/list/views/Grid.vue +3 -3
- package/dist/runtime/components/list/views/Rows.vue +3 -3
- package/dist/runtime/components/list/views/Table.vue +3 -3
- package/dist/runtime/components/misc/atoms/CountUp.vue +89 -144
- package/dist/runtime/components/misc/atoms/DateStamp.vue +42 -46
- package/dist/runtime/components/misc/atoms/ImageContainer.vue +14 -22
- package/dist/runtime/components/misc/atoms/ShareMenu.vue +9 -11
- package/dist/runtime/components/misc/atoms/Socials.vue +46 -52
- package/dist/runtime/components/misc/molecules/ChipContainer.vue +7 -11
- package/dist/runtime/components/misc/molecules/Related.vue +9 -11
- package/dist/runtime/components/misc/molecules/RelatedItems.vue +7 -9
- package/dist/runtime/components/misc/molecules/SearchItem.vue +2 -2
- package/dist/runtime/components/news/DenseItem.vue +15 -15
- package/dist/runtime/components/news/ExpandedItem.vue +40 -50
- package/dist/runtime/components/news/Header.vue +3 -5
- package/dist/runtime/components/news/RelatedItem.vue +6 -7
- package/dist/runtime/components/news/RowsItem.vue +14 -16
- package/dist/runtime/components/news/View.vue +9 -20
- package/dist/runtime/components/people/DenseItem.vue +9 -8
- package/dist/runtime/components/people/ExpandedItem.vue +4 -6
- package/dist/runtime/components/people/GroupBadges.vue +6 -8
- package/dist/runtime/components/people/RelatedItem.vue +6 -7
- package/dist/runtime/components/people/RowsItem.vue +12 -19
- package/dist/runtime/components/people/View.vue +7 -7
- package/dist/runtime/components/projects/ExpandedItem.vue +4 -6
- package/dist/runtime/components/projects/RelatedItem.vue +6 -7
- package/dist/runtime/components/projects/RowsItem.vue +21 -26
- package/dist/runtime/components/projects/View.vue +8 -8
- package/dist/runtime/components/publications/RelatedItem.vue +6 -7
- package/dist/runtime/components/publications/RowsItem.vue +20 -22
- package/dist/runtime/components/publications/View.vue +9 -15
- package/dist/runtime/composables/useFetchItem.d.ts +6 -0
- package/dist/runtime/composables/useFetchItem.js +49 -0
- package/dist/runtime/composables/useIcons.d.ts +1 -0
- package/dist/runtime/composables/useIcons.js +30 -0
- package/dist/runtime/composables/useUtils.d.ts +12 -0
- package/dist/runtime/composables/useUtils.js +47 -0
- package/dist/runtime/plugins/pinia.d.ts +2 -0
- package/dist/runtime/plugins/{pinia.ts → pinia.js} +29 -48
- package/dist/runtime/plugins/vuetify.d.ts +2 -0
- package/dist/runtime/server/tsconfig.json +3 -0
- package/dist/runtime/stores/factory.d.ts +1 -0
- package/dist/runtime/stores/{factory.ts → factory.js} +9 -9
- package/dist/runtime/stores/root.d.ts +34 -0
- package/dist/runtime/stores/root.js +227 -0
- package/dist/types.d.mts +3 -0
- package/package.json +55 -26
- package/dist/runtime/composables/useFetchItem.ts +0 -64
- package/dist/runtime/composables/useIcons.ts +0 -30
- package/dist/runtime/composables/useUtils.ts +0 -75
- package/dist/runtime/stores/root.ts +0 -353
- package/example/.env.example +0 -3
- package/example/nuxt.config.ts +0 -19
- package/example/pages/index.vue +0 -27
- package/index.ts +0 -119
package/package.json
CHANGED
|
@@ -1,40 +1,69 @@
|
|
|
1
1
|
{
|
|
2
|
+
"license": "AGPL-3.0-only",
|
|
3
|
+
"main": "./dist/module.mjs",
|
|
4
|
+
"version": "1.0.13",
|
|
2
5
|
"name": "@paris-ias/list",
|
|
3
|
-
"
|
|
4
|
-
"private": false,
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./index.ts",
|
|
7
|
-
"files": [
|
|
8
|
-
"example",
|
|
9
|
-
"index.ts",
|
|
10
|
-
"src",
|
|
11
|
-
"lib",
|
|
12
|
-
"dist"
|
|
13
|
-
],
|
|
14
|
-
"scripts": {},
|
|
6
|
+
"repository": "IEA-Paris/list",
|
|
15
7
|
"dependencies": {
|
|
16
|
-
"@
|
|
17
|
-
"@nuxt/content": "^2.9.0",
|
|
18
|
-
"@nuxt/image": "^1.10.0",
|
|
19
|
-
"@nuxtjs/mdc": "0.16.1",
|
|
20
|
-
"@pinia/nuxt": "^0.5.5",
|
|
21
|
-
"pinia": "^3.0.1",
|
|
22
|
-
"sass": "^1.78.0",
|
|
23
|
-
"vue": "^3.5.13",
|
|
24
|
-
"vuetify": "3.8.0"
|
|
8
|
+
"@nuxt/kit": "^3.16.2"
|
|
25
9
|
},
|
|
10
|
+
"description": "Paris IAS List Module",
|
|
26
11
|
"devDependencies": {
|
|
12
|
+
"@mdi/font": "^7.4.47",
|
|
13
|
+
"@nuxt/content": "^2.9.0",
|
|
14
|
+
"@nuxt/devtools": "^2.3.2",
|
|
15
|
+
"@nuxt/eslint": "1.3.0",
|
|
16
|
+
"@nuxt/eslint-config": "^1.3.0",
|
|
17
|
+
"@nuxt/image": "1.10.0",
|
|
18
|
+
"@nuxt/module-builder": "^1.0.0",
|
|
19
|
+
"@nuxt/schema": "^3.16.2",
|
|
20
|
+
"@nuxt/test-utils": "^3.17.2",
|
|
27
21
|
"@nuxtjs/apollo": "^5.0.0-alpha.14",
|
|
28
22
|
"@nuxtjs/i18n": "^9.5.2",
|
|
23
|
+
"@nuxtjs/mdc": "0.16.1",
|
|
29
24
|
"@paris-ias/data": "^1.8.0",
|
|
30
|
-
"@
|
|
25
|
+
"@pinia/nuxt": "^0.10.1",
|
|
26
|
+
"@types/node": "latest",
|
|
31
27
|
"@vueuse/core": "^13.0.0",
|
|
28
|
+
"changelogen": "^0.6.1",
|
|
29
|
+
"eslint": "^9.24.0",
|
|
32
30
|
"graphql-tag": "^2.12.6",
|
|
33
31
|
"nuxt": "^3.16.2",
|
|
34
|
-
"
|
|
35
|
-
"
|
|
32
|
+
"pinia": "^3.0.1",
|
|
33
|
+
"sass": "^1.78.0",
|
|
34
|
+
"typescript": "~5.8.3",
|
|
35
|
+
"vite-plugin-graphql-loader": "^4.0.4",
|
|
36
|
+
"vitest": "^3.1.1",
|
|
37
|
+
"vue": "^3.5.13",
|
|
38
|
+
"vue-tsc": "^2.2.8",
|
|
39
|
+
"vuetify": "3.8.0"
|
|
36
40
|
},
|
|
37
|
-
"
|
|
38
|
-
"
|
|
41
|
+
"exports": {
|
|
42
|
+
".": {
|
|
43
|
+
"import": "./dist/module.mjs",
|
|
44
|
+
"types": "./dist/types.d.mts"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist"
|
|
49
|
+
],
|
|
50
|
+
"scripts": {
|
|
51
|
+
"dev": "nuxi dev playground",
|
|
52
|
+
"dev:build": "nuxi build playground",
|
|
53
|
+
"dev:prepare": "nuxt-module-build build --stub && nuxt-module-build prepare && nuxi prepare playground",
|
|
54
|
+
"lint": "eslint .",
|
|
55
|
+
"prepack": "nuxt-module-build build",
|
|
56
|
+
"release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
|
|
57
|
+
"test": "vitest run",
|
|
58
|
+
"test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
|
|
59
|
+
"test:watch": "vitest watch"
|
|
60
|
+
},
|
|
61
|
+
"type": "module",
|
|
62
|
+
"typesVersions": {
|
|
63
|
+
"*": {
|
|
64
|
+
".": [
|
|
65
|
+
"./dist/types.d.mts"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
39
68
|
}
|
|
40
69
|
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { useRoute } from "vue-router"
|
|
2
|
-
export const useFetchItem = () => {
|
|
3
|
-
const fetchItem = async <T>(payload: {
|
|
4
|
-
query: string
|
|
5
|
-
key: string
|
|
6
|
-
}): Promise<T> => {
|
|
7
|
-
try {
|
|
8
|
-
const { locale } = useI18n()
|
|
9
|
-
const route = useRoute()
|
|
10
|
-
|
|
11
|
-
const variables = {
|
|
12
|
-
itemId: route.params.slug?.toString().trim(),
|
|
13
|
-
appId: "iea",
|
|
14
|
-
lang: locale.value,
|
|
15
|
-
}
|
|
16
|
-
const { data, error } = await useAsyncQuery(payload.query, variables)
|
|
17
|
-
/* console.log("variables: ", variables) */
|
|
18
|
-
|
|
19
|
-
if (error.value) {
|
|
20
|
-
console.error("GraphQL error:", error.value)
|
|
21
|
-
throw error.value
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const item = data?.value[payload.key]
|
|
25
|
-
/* console.log("item: ", item) */
|
|
26
|
-
|
|
27
|
-
if (!item) {
|
|
28
|
-
throw createError({
|
|
29
|
-
statusCode: 404,
|
|
30
|
-
message: "Item not found in response",
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
// Update the slug in the i18n params
|
|
34
|
-
// for people, the slug is the same in both languages
|
|
35
|
-
// for other items, the slug is different in each language
|
|
36
|
-
const setI18nParams = useSetI18nParams()
|
|
37
|
-
if (!route.name.includes("people")) {
|
|
38
|
-
/* console.log("update params") */
|
|
39
|
-
setI18nParams({
|
|
40
|
-
en: { slug: item.slug.en },
|
|
41
|
-
fr: { slug: item.slug.fr },
|
|
42
|
-
})
|
|
43
|
-
} else {
|
|
44
|
-
// for people, the slug is the same in both languages
|
|
45
|
-
setI18nParams({
|
|
46
|
-
en: { slug: item.slug },
|
|
47
|
-
fr: { slug: item.slug },
|
|
48
|
-
})
|
|
49
|
-
}
|
|
50
|
-
return item as T
|
|
51
|
-
} catch (error) {
|
|
52
|
-
console.error("Error fetching item:", error)
|
|
53
|
-
throw createError({
|
|
54
|
-
statusCode: 404,
|
|
55
|
-
message: "Item not found",
|
|
56
|
-
cause: error,
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
fetchItem,
|
|
63
|
-
}
|
|
64
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
export default function getFileIcon(fileName: string): string {
|
|
2
|
-
console.log("fileName: ", fileName)
|
|
3
|
-
const fileExtension = fileName.split(".").pop()
|
|
4
|
-
console.log("fileExtension: ", fileExtension)
|
|
5
|
-
switch (fileExtension) {
|
|
6
|
-
case "pdf":
|
|
7
|
-
return "mdi-file-pdf-box"
|
|
8
|
-
case "doc":
|
|
9
|
-
case "docx":
|
|
10
|
-
return "mdi-file-word"
|
|
11
|
-
case "xls":
|
|
12
|
-
case "xlsx":
|
|
13
|
-
return "mdi-file-excel"
|
|
14
|
-
case "ppt":
|
|
15
|
-
case "pptx":
|
|
16
|
-
return "mdi-file-powerpoint"
|
|
17
|
-
case "jpg":
|
|
18
|
-
case "jpeg":
|
|
19
|
-
case "png":
|
|
20
|
-
case "gif":
|
|
21
|
-
return "mdi-file-image"
|
|
22
|
-
case "zip":
|
|
23
|
-
case "rar":
|
|
24
|
-
return "mdi-folder-zip"
|
|
25
|
-
case "txt":
|
|
26
|
-
return "mdi-file-document"
|
|
27
|
-
default:
|
|
28
|
-
return "mdi-file"
|
|
29
|
-
}
|
|
30
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
export const formatDate = (dateStr: string, locale: string): string => {
|
|
2
|
-
const date = new Date(dateStr)
|
|
3
|
-
return date.toLocaleDateString(locale, {
|
|
4
|
-
weekday: "long",
|
|
5
|
-
year: "numeric",
|
|
6
|
-
month: "long",
|
|
7
|
-
day: "numeric",
|
|
8
|
-
})
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const getLocalizedDate = (dateIso: string): string => {
|
|
12
|
-
const { $i18n } = useNuxtApp()
|
|
13
|
-
return new Date(dateIso).toLocaleDateString(
|
|
14
|
-
$i18n.localeProperties.value.language,
|
|
15
|
-
{
|
|
16
|
-
weekday: "long",
|
|
17
|
-
year: "numeric",
|
|
18
|
-
month: "long",
|
|
19
|
-
day: "numeric",
|
|
20
|
-
}
|
|
21
|
-
)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const getDetailedFormatedDate = (
|
|
25
|
-
dateStr: string,
|
|
26
|
-
locale: string
|
|
27
|
-
): {
|
|
28
|
-
day: number
|
|
29
|
-
month: string
|
|
30
|
-
year: number
|
|
31
|
-
hours: number
|
|
32
|
-
minutes: number
|
|
33
|
-
} => {
|
|
34
|
-
const date = new Date(dateStr)
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
day: date.getDate(),
|
|
38
|
-
month: date.toLocaleString(locale, { month: "long" }),
|
|
39
|
-
year: date.getFullYear(),
|
|
40
|
-
hours: date.getUTCHours(),
|
|
41
|
-
minutes: date.getMinutes(),
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const capitalize = (value: string, multiple?: boolean) =>
|
|
46
|
-
multiple
|
|
47
|
-
? value.replace(/(?:^|[\s'-])\S/g, (a) => a.toUpperCase())
|
|
48
|
-
: value && value.charAt(0).toUpperCase() + value.slice(1)
|
|
49
|
-
|
|
50
|
-
export const slugify = (str: string) => {
|
|
51
|
-
str = str.replace(/^\s+|\s+$/g, "").trim() // trim
|
|
52
|
-
str = str.toLowerCase()
|
|
53
|
-
|
|
54
|
-
// remove accents, swap ñ for n, etc
|
|
55
|
-
const from = "àáäâèéëêìíïîòóöôùúüûñç·/_,:;"
|
|
56
|
-
const to = "aaaaeeeeiiiioooouuuunc------"
|
|
57
|
-
for (let i = 0, l = from.length; i < l; i++) {
|
|
58
|
-
str = str.replace(new RegExp(from.charAt(i), "g"), to.charAt(i))
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
str = str
|
|
62
|
-
.replace(/[^a-z0-9 -]/g, "") // remove invalid chars
|
|
63
|
-
.replace(/\s+/g, "-") // collapse whitespace and replace by -
|
|
64
|
-
.replace(/-+/g, "-") // collapse dashes
|
|
65
|
-
|
|
66
|
-
return str
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export const formatDateValue = (
|
|
70
|
-
date: string | Date,
|
|
71
|
-
locale: string
|
|
72
|
-
): string => {
|
|
73
|
-
const formattedDate = new Date(date)
|
|
74
|
-
return formattedDate.toLocaleDateString(locale)
|
|
75
|
-
}
|
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
/* import filtersRaw from '~/assets/data/filters'
|
|
2
|
-
import lists from '~/assets/data/lists' */
|
|
3
|
-
|
|
4
|
-
/* import api from "~/server/api/github" */
|
|
5
|
-
import { defineStore } from "pinia"
|
|
6
|
-
import type { Views, ModuleType } from "@paris-ias/data"
|
|
7
|
-
|
|
8
|
-
import SEARCH from "../graphql/queries/list/search.gql"
|
|
9
|
-
export const useRootStore = defineStore("rootStore", {
|
|
10
|
-
state: (): Record<
|
|
11
|
-
string,
|
|
12
|
-
boolean | number | string | ModuleType | searchResults
|
|
13
|
-
> => ({
|
|
14
|
-
scrolled: import.meta.browser ? window.scrollY > 0 : false,
|
|
15
|
-
loading: false,
|
|
16
|
-
total: 0,
|
|
17
|
-
skip: 0,
|
|
18
|
-
page: 1,
|
|
19
|
-
numberOfPages: 0,
|
|
20
|
-
search: "",
|
|
21
|
-
results: {
|
|
22
|
-
events: {},
|
|
23
|
-
news: {},
|
|
24
|
-
people: {},
|
|
25
|
-
projects: {},
|
|
26
|
-
fellowships: {},
|
|
27
|
-
publications: {},
|
|
28
|
-
},
|
|
29
|
-
}),
|
|
30
|
-
|
|
31
|
-
actions: {
|
|
32
|
-
setLoading(value: boolean, type: string = "") {
|
|
33
|
-
const { $stores } = useNuxtApp()
|
|
34
|
-
this.loading = value
|
|
35
|
-
if (type.length) $stores[type].loading = value
|
|
36
|
-
},
|
|
37
|
-
setScrolled() {
|
|
38
|
-
if (import.meta.browser) {
|
|
39
|
-
this.scrolled = window.scrollY > 0
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
loadRouteQuery(type: string) {
|
|
43
|
-
const { currentRoute } = useRouter()
|
|
44
|
-
const { $stores } = useNuxtApp()
|
|
45
|
-
const query = currentRoute.value.query
|
|
46
|
-
if (Object.keys(query)?.length) {
|
|
47
|
-
Object.keys(query).forEach((filter) => {
|
|
48
|
-
if (Object.keys($stores[type].filters).includes(filter))
|
|
49
|
-
$stores[type].filters[filter].value = (this[type] as ModuleType)
|
|
50
|
-
.list.filters[filter].multiple
|
|
51
|
-
? JSON.parse(query[filter] as string)
|
|
52
|
-
: query[filter]
|
|
53
|
-
})
|
|
54
|
-
/* if (query.view) {
|
|
55
|
-
;$stores[type].view = query.view as
|
|
56
|
-
| string
|
|
57
|
-
| Views
|
|
58
|
-
| undefined
|
|
59
|
-
}
|
|
60
|
-
if (query.page) {
|
|
61
|
-
this.page = +query.page
|
|
62
|
-
} else {
|
|
63
|
-
this.page = 1
|
|
64
|
-
} */
|
|
65
|
-
|
|
66
|
-
/* const sortObj = $stores[type].sort
|
|
67
|
-
const defaultSortKey = Object.keys(sortObj).find(
|
|
68
|
-
(item) => sortObj[item].default === true,
|
|
69
|
-
)
|
|
70
|
-
const defaultSort = [sortObj[defaultSortKey as string]]
|
|
71
|
-
|
|
72
|
-
const sortDesc = $stores[type].sortDesc
|
|
73
|
-
let sortDescItem
|
|
74
|
-
sortDescItem = (sortDesc as number[] | boolean[])[0]
|
|
75
|
-
|
|
76
|
-
if (query.sortBy) {
|
|
77
|
-
;$stores[type].sortBy = [query.sortBy] as string[]
|
|
78
|
-
}
|
|
79
|
-
if (typeof query.sortDesc !== "undefined") {
|
|
80
|
-
sortDescItem = !!(query.sortDesc === "true")
|
|
81
|
-
} else {
|
|
82
|
-
sortDescItem = defaultSort[0].value[1]
|
|
83
|
-
} */
|
|
84
|
-
}
|
|
85
|
-
console.log("query loaded")
|
|
86
|
-
},
|
|
87
|
-
|
|
88
|
-
setFiltersCount(type: string) {
|
|
89
|
-
const { $stores } = useNuxtApp()
|
|
90
|
-
let filtersCount = 0 as number
|
|
91
|
-
Object.keys($stores[type].filters)
|
|
92
|
-
// remove empty values
|
|
93
|
-
.forEach((filter) => {
|
|
94
|
-
/*console.log("filter: ", filter)
|
|
95
|
-
console.log("filters[filter]?.value: ", filters[filter].value)
|
|
96
|
-
*/ /* console.log(
|
|
97
|
-
'typeof filters[filter]?.value !== "undefined": ',
|
|
98
|
-
typeof filters[filter]?.value !== "undefined",
|
|
99
|
-
) */
|
|
100
|
-
if (
|
|
101
|
-
$stores[type].filters[filter]?.value?.length &&
|
|
102
|
-
typeof $stores[type].filters[filter]?.value !== "undefined"
|
|
103
|
-
) {
|
|
104
|
-
filtersCount++
|
|
105
|
-
}
|
|
106
|
-
return filtersCount
|
|
107
|
-
})
|
|
108
|
-
|
|
109
|
-
$stores[type].filtersCount = filtersCount
|
|
110
|
-
},
|
|
111
|
-
setBlankFilterLoad(type: string) {
|
|
112
|
-
/* ;(this[type] as ModuleType).loading = false */
|
|
113
|
-
},
|
|
114
|
-
setDefaults() {
|
|
115
|
-
// lang
|
|
116
|
-
const lang = localStorage.getItem("lang")
|
|
117
|
-
/* if(lang)i18n.global.locale = lang; */
|
|
118
|
-
// dark mode
|
|
119
|
-
|
|
120
|
-
// event
|
|
121
|
-
// people
|
|
122
|
-
// news
|
|
123
|
-
// project
|
|
124
|
-
// fellowships
|
|
125
|
-
},
|
|
126
|
-
updateRouteQuery(type: string) {
|
|
127
|
-
const router = useRouter()
|
|
128
|
-
const { $stores } = useNuxtApp()
|
|
129
|
-
// update route
|
|
130
|
-
const routeQuery: Record<string, string> = {
|
|
131
|
-
// Add search if it exists and is defined
|
|
132
|
-
...(this.search ? { search: this.search } : {}),
|
|
133
|
-
|
|
134
|
-
// Add page if it's greater than 1
|
|
135
|
-
...(this.page > 1 ? { page: this.page.toString() } : {}),
|
|
136
|
-
|
|
137
|
-
// Add filters with defined values
|
|
138
|
-
...Object.entries($stores[type].filters).reduce(
|
|
139
|
-
(acc, [filterKey, filter]) => {
|
|
140
|
-
if (!$stores[type].filters[filterKey]?.value) {
|
|
141
|
-
return acc
|
|
142
|
-
}
|
|
143
|
-
return {
|
|
144
|
-
...acc,
|
|
145
|
-
...{
|
|
146
|
-
[filterKey]: $stores[type].filters[filterKey]?.value,
|
|
147
|
-
},
|
|
148
|
-
}
|
|
149
|
-
},
|
|
150
|
-
{} as Record<string, string>
|
|
151
|
-
),
|
|
152
|
-
}
|
|
153
|
-
router.replace({ query: routeQuery })
|
|
154
|
-
},
|
|
155
|
-
resetState() {
|
|
156
|
-
const { $stores } = useNuxtApp()
|
|
157
|
-
console.log("resetState")
|
|
158
|
-
this.search = ""
|
|
159
|
-
this.page = 1
|
|
160
|
-
this.scrolled = false
|
|
161
|
-
this.loading = false
|
|
162
|
-
this.total = 0
|
|
163
|
-
this.skip = 0
|
|
164
|
-
this.numberOfPages = 0
|
|
165
|
-
const modules = [
|
|
166
|
-
"events",
|
|
167
|
-
"news",
|
|
168
|
-
"people",
|
|
169
|
-
"projects",
|
|
170
|
-
"fellowships",
|
|
171
|
-
"publications",
|
|
172
|
-
]
|
|
173
|
-
/* this.events.list.filters = events.list.filters
|
|
174
|
-
this.news.list.filters = news.list.filters
|
|
175
|
-
this.people.list.filters = people.list.filters
|
|
176
|
-
this.projects.list.filters = projects.list.filters
|
|
177
|
-
this.fellowships.list.filters = fellowships.list.filters
|
|
178
|
-
this.publications.list.filters = publications.list.filters */
|
|
179
|
-
modules.forEach((type) => {
|
|
180
|
-
/* const viewsObj = $stores[type].views as Record<
|
|
181
|
-
string,
|
|
182
|
-
Views
|
|
183
|
-
>
|
|
184
|
-
const defaultViewsKey = Object.keys(viewsObj).find(
|
|
185
|
-
(item) => viewsObj[item].default === true
|
|
186
|
-
)
|
|
187
|
-
const defaultView = viewsObj[defaultViewsKey as string]
|
|
188
|
-
|
|
189
|
-
const sortObj = $stores[type].sort
|
|
190
|
-
const defaultSortKey = Object.keys(sortObj).find(
|
|
191
|
-
(item) => sortObj[item].default === true
|
|
192
|
-
)
|
|
193
|
-
const defaultSort = sortObj[defaultSortKey as string] */
|
|
194
|
-
/*
|
|
195
|
-
// TODO make dynamic based on an ~/assets located file
|
|
196
|
-
;$stores[type].view = defaultView
|
|
197
|
-
;$stores[type].sortBy = [defaultSort.value[0]]
|
|
198
|
-
;$stores[type].sortDesc = [defaultSort.value[1]] */
|
|
199
|
-
})
|
|
200
|
-
},
|
|
201
|
-
updateSort({ value, type }: { value: number[] | string[]; type: string }) {
|
|
202
|
-
const { $stores } = useNuxtApp()
|
|
203
|
-
$stores[type].sortBy = [value[0]] as string[]
|
|
204
|
-
$stores[type].sortDesc = [value[1]] as number[]
|
|
205
|
-
this.page = 1
|
|
206
|
-
this.updateLocalStorage(type + "_sort", value.join("_"))
|
|
207
|
-
this.update(type)
|
|
208
|
-
},
|
|
209
|
-
updateView({ value, type }: { value: string; type: string }) {
|
|
210
|
-
const { $stores } = useNuxtApp()
|
|
211
|
-
$stores[type].view = {
|
|
212
|
-
...($stores[type].views[value] as Views),
|
|
213
|
-
name: value,
|
|
214
|
-
}
|
|
215
|
-
this.updateLocalStorage(type + "_view", value)
|
|
216
|
-
this.update(type)
|
|
217
|
-
},
|
|
218
|
-
updateLocalStorage(key: string, value: string) {
|
|
219
|
-
const local = JSON.parse(localStorage.getItem("PARIS_IAS") as any) || {}
|
|
220
|
-
local[key] = value
|
|
221
|
-
localStorage.setItem("PARIS_IAS", JSON.stringify(local))
|
|
222
|
-
},
|
|
223
|
-
updateFilter(key: string, val: any, type: string) {
|
|
224
|
-
const { $stores } = useNuxtApp()
|
|
225
|
-
console.log("update filter: ", { key, val, type })
|
|
226
|
-
|
|
227
|
-
if (["online", "outside", "past"].includes(key) && val === false) {
|
|
228
|
-
$stores[type].filters[key].value = null
|
|
229
|
-
} else {
|
|
230
|
-
$stores[type].filters[key].value = val
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
this.updatePage({ page: 1, type })
|
|
234
|
-
},
|
|
235
|
-
updateItemsPerPage({ value, type }: { value: number; type: string }) {
|
|
236
|
-
const { $stores } = useNuxtApp()
|
|
237
|
-
this.page = 1
|
|
238
|
-
$stores[types].itemsPerPage = value
|
|
239
|
-
|
|
240
|
-
this.update(type)
|
|
241
|
-
},
|
|
242
|
-
updatePage({ page, type }: { page: number; type: string }) {
|
|
243
|
-
this.page = page
|
|
244
|
-
this.update(type)
|
|
245
|
-
},
|
|
246
|
-
async updateSearch({
|
|
247
|
-
type = "all",
|
|
248
|
-
search = "",
|
|
249
|
-
lang = "en",
|
|
250
|
-
}: {
|
|
251
|
-
type: string
|
|
252
|
-
search: string
|
|
253
|
-
lang: string
|
|
254
|
-
}) {
|
|
255
|
-
this.search = search
|
|
256
|
-
/* console.log("updateSearch: ", search + " " + lang) */
|
|
257
|
-
this.setLoading(true)
|
|
258
|
-
|
|
259
|
-
await this.update(type, lang)
|
|
260
|
-
},
|
|
261
|
-
|
|
262
|
-
async update(type: string, lang: string = "en") {
|
|
263
|
-
const { $stores } = useNuxtApp()
|
|
264
|
-
this.setLoading(true)
|
|
265
|
-
if (type !== "all") {
|
|
266
|
-
$stores[type].loading = true
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
// fetch the item categories
|
|
270
|
-
|
|
271
|
-
const itemsPerPage =
|
|
272
|
-
type === "all" ? 3 : ($stores[type]?.itemsPerPage as number)
|
|
273
|
-
const filters: Record<string, any> = {}
|
|
274
|
-
|
|
275
|
-
if (type !== "all") {
|
|
276
|
-
for (const filter in $stores[type].filters) {
|
|
277
|
-
const filterValue = $stores[type].filters[filter]?.value
|
|
278
|
-
|
|
279
|
-
// Prune empty values
|
|
280
|
-
if (typeof filterValue !== "undefined" && filterValue?.length) {
|
|
281
|
-
filters[filter] = filterValue
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const args = JSON.parse(
|
|
287
|
-
JSON.stringify({
|
|
288
|
-
options: {
|
|
289
|
-
// skip
|
|
290
|
-
skip: +this.page === 1 ? 0 : (+this.page - 1) * itemsPerPage,
|
|
291
|
-
// limit
|
|
292
|
-
limit: itemsPerPage,
|
|
293
|
-
// sort, array of keys and array of directions - to have x tie breakers if necessary
|
|
294
|
-
sortBy: type === "all" ? "searchScore" : $stores[type].sortBy,
|
|
295
|
-
sortDesc:
|
|
296
|
-
type === "all" ? -1 : $stores[type].sortDesc > 0 ? true : false,
|
|
297
|
-
// search (if set)
|
|
298
|
-
...((this.search as string)?.length &&
|
|
299
|
-
type !== "all" && { search: this.search }),
|
|
300
|
-
// add the store module filters
|
|
301
|
-
filters,
|
|
302
|
-
},
|
|
303
|
-
...((this.search as string)?.length &&
|
|
304
|
-
type === "all" && { search: this.search }),
|
|
305
|
-
appId: "iea",
|
|
306
|
-
lang,
|
|
307
|
-
})
|
|
308
|
-
)
|
|
309
|
-
args.options.filters = JSON.stringify(args.options.filters)
|
|
310
|
-
let result: any = {}
|
|
311
|
-
console.log("args: ", args)
|
|
312
|
-
|
|
313
|
-
console.log(`Fetching ${type}`)
|
|
314
|
-
const { $queries } = useNuxtApp()
|
|
315
|
-
const { data, error } = await useAsyncQuery(
|
|
316
|
-
type === "all" ? SEARCH : $queries[type].list,
|
|
317
|
-
args
|
|
318
|
-
)
|
|
319
|
-
/* console.log("data: ", data) */
|
|
320
|
-
if (error.value) console.log(error.value)
|
|
321
|
-
const key =
|
|
322
|
-
type === "all"
|
|
323
|
-
? "search"
|
|
324
|
-
: "list" + type.charAt(0).toUpperCase() + type.slice(1)
|
|
325
|
-
|
|
326
|
-
if (type === "all") {
|
|
327
|
-
this.results = data?.value?.[key]
|
|
328
|
-
} else {
|
|
329
|
-
const items = data?.value?.[key]?.items ?? []
|
|
330
|
-
this.total = data?.value?.[key]?.total
|
|
331
|
-
result = {
|
|
332
|
-
...data?.value?.[key],
|
|
333
|
-
items: items.map(({ id, ...rest }) => ({
|
|
334
|
-
...rest,
|
|
335
|
-
_path: `/${id}`,
|
|
336
|
-
})),
|
|
337
|
-
}
|
|
338
|
-
$stores[type].items = result["items"]
|
|
339
|
-
|
|
340
|
-
const lastPage = Math.ceil(result.total / itemsPerPage)
|
|
341
|
-
/* this.updateRouteQuery(type) */
|
|
342
|
-
this.setFiltersCount(type)
|
|
343
|
-
this.setBlankFilterLoad(type)
|
|
344
|
-
/* console.log("type2: ", type) */
|
|
345
|
-
$stores[type].numberOfPages = lastPage
|
|
346
|
-
}
|
|
347
|
-
/* console.log("this.total: ", this.total)
|
|
348
|
-
*/
|
|
349
|
-
this.setLoading(false, type)
|
|
350
|
-
return true
|
|
351
|
-
},
|
|
352
|
-
},
|
|
353
|
-
})
|
package/example/.env.example
DELETED
package/example/nuxt.config.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export default defineNuxtConfig({
|
|
2
|
-
modules: ["@paris-ias/list"],
|
|
3
|
-
list: {
|
|
4
|
-
modules: [
|
|
5
|
-
"events",
|
|
6
|
-
"news",
|
|
7
|
-
"people",
|
|
8
|
-
"projects",
|
|
9
|
-
"fellowships",
|
|
10
|
-
"publications",
|
|
11
|
-
],
|
|
12
|
-
},
|
|
13
|
-
runtimeConfig: {
|
|
14
|
-
public: {
|
|
15
|
-
graphqlEndpoint: process.env.GRAPHQL_ENDPOINT,
|
|
16
|
-
graphqlApiKey: process.env.GRAPHQL_API_KEY,
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
})
|
package/example/pages/index.vue
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div>
|
|
3
|
-
<h1>List Module Example</h1>
|
|
4
|
-
|
|
5
|
-
<h2>Events</h2>
|
|
6
|
-
<ListOrganismsList type="events" />
|
|
7
|
-
|
|
8
|
-
<h2>News</h2>
|
|
9
|
-
<ListOrganismsList type="news" />
|
|
10
|
-
|
|
11
|
-
<h2>People</h2>
|
|
12
|
-
<ListOrganismsList type="people" />
|
|
13
|
-
|
|
14
|
-
<h2>Publications</h2>
|
|
15
|
-
<ListOrganismsList type="publications" />
|
|
16
|
-
|
|
17
|
-
<h2>Fellowships</h2>
|
|
18
|
-
<ListOrganismsList type="fellowships" />
|
|
19
|
-
|
|
20
|
-
<h2>Projects</h2>
|
|
21
|
-
<ListOrganismsList type="projects" />
|
|
22
|
-
</div>
|
|
23
|
-
</template>
|
|
24
|
-
|
|
25
|
-
<script setup lang="ts">
|
|
26
|
-
// The components are automatically imported by the module
|
|
27
|
-
</script>
|