diff --git a/core/static/webpack/user/pictures-index.js b/core/static/webpack/user/pictures-index.js index d0be8d55..acdb9042 100644 --- a/core/static/webpack/user/pictures-index.js +++ b/core/static/webpack/user/pictures-index.js @@ -1,5 +1,7 @@ +import { paginated } from "#core:utils/api"; import { HttpReader, ZipWriter } from "@zip.js/zip.js"; import { showSaveFilePicker } from "native-file-system-adapter"; +import { picturesFetchPictures } from "#openapi"; /** * @typedef UserProfile @@ -28,14 +30,14 @@ import { showSaveFilePicker } from "native-file-system-adapter"; /** * @typedef PicturePageConfig - * @param {string} apiUrl Url of the api endpoint to fetch pictures from the user + * @param {number} userId Id of the user to get the pictures from **/ /** * Load user picture page with a nice download bar * @param {PicturePageConfig} Configuration **/ -window.loadPicturePage = (config) => { +window.window.loadPicturePage = (config) => { document.addEventListener("alpine:init", () => { Alpine.data("user_pictures", () => ({ isDownloading: false, @@ -44,8 +46,10 @@ window.loadPicturePage = (config) => { albums: {}, async init() { - // biome-ignore lint/correctness/noUndeclaredVariables: imported from script.json - this.pictures = await fetchPaginated(config.apiUrl); + this.pictures = await paginated(picturesFetchPictures, { + // biome-ignore lint/style/useNamingConvention: api is in snake_case + query: { users_identified: [config.userId] }, + }); this.albums = this.pictures.reduce((acc, picture) => { if (!acc[picture.album]) { acc[picture.album] = []; diff --git a/core/static/webpack/utils/api.ts b/core/static/webpack/utils/api.ts new file mode 100644 index 00000000..7951556b --- /dev/null +++ b/core/static/webpack/utils/api.ts @@ -0,0 +1,46 @@ +import type { Options, RequestResult } from "@hey-api/client-fetch"; + +interface PaginatedResponse { + count: number; + next: string | null; + previous: string | null; + results: T[]; +} + +interface PaginatedRequest { + query?: { + page?: number; + // biome-ignore lint/style/useNamingConvention: api is in snake_case + page_size?: number; + }; +} + +type PaginatedEndpoint = ( + options?: Options, +) => RequestResult, unknown, ThrowOnError>; + +export const paginated = async ( + endpoint: PaginatedEndpoint, + options?: PaginatedRequest, +) => { + const maxPerPage = 199; + options.query.page_size = maxPerPage; + options.query.page = 1; + + const firstPage = (await endpoint(options)).data; + const results = firstPage.results; + + const nbElements = firstPage.count; + const nbPages = Math.ceil(nbElements / maxPerPage); + + if (nbPages > 1) { + const promises: Promise[] = []; + for (let i = 2; i <= nbPages; i++) { + const nextPage = structuredClone(options); + nextPage.query.page = i; + promises.push(endpoint(nextPage).then((res) => res.data.results)); + } + results.push(...(await Promise.all(promises)).flat()); + } + return results; +}; diff --git a/core/templates/core/user_pictures.jinja b/core/templates/core/user_pictures.jinja index c67df69b..73479849 100644 --- a/core/templates/core/user_pictures.jinja +++ b/core/templates/core/user_pictures.jinja @@ -62,9 +62,7 @@ {{ super() }} {% endblock script %} diff --git a/docs/howto/js-import-paths.md b/docs/howto/js-import-paths.md new file mode 100644 index 00000000..e24b5a35 --- /dev/null +++ b/docs/howto/js-import-paths.md @@ -0,0 +1,39 @@ +Vous avez ajouté une application et vous voulez y mettre du javascript ? + +Vous voulez importer depuis cette nouvelle application dans votre script géré par webpack ? + +Eh bien il faut manuellement enregistrer dans node où les trouver et c'est très simple. + +D'abord, il faut ajouter dans node via `package.json`: + +```json +{ + // ... + "imports": { + // ... + "#mon_app:*": "./mon_app/static/webpack/*" + } + // ... +} +``` + +Ensuite, pour faire fonctionne l'auto-complétion, il faut configurer `tsconfig.json`: + +```json +{ + "compilerOptions": { + // ... + "paths": { + // ... + "#mon_app:*": ["./mon_app/static/webpack/*"] + } + } +} +``` + +Et c'est tout ! + +!!!note + + Il se peut qu'il soit nécessaire de redémarrer `./manage.py runserver` pour + que les changements prennent effet. \ No newline at end of file diff --git a/docs/howto/statics.md b/docs/howto/statics.md index 470e5e2a..5c9dfdc4 100644 --- a/docs/howto/statics.md +++ b/docs/howto/statics.md @@ -35,8 +35,9 @@ les fichiers sont à mettre dans un dossier `static/webpack` de l'application à Pour accéder au fichier, il faut utiliser `static` comme pour le reste mais en ajouter `webpack/` comme prefix. ```jinja - {# Exemple pour ajouter sith/core/webpack/alpine-index.js #} + {# Example pour ajouter sith/core/webpack/alpine-index.js #} + ``` !!!note @@ -45,6 +46,16 @@ Pour accéder au fichier, il faut utiliser `static` comme pour le reste mais en Les autres fichiers sont disponibles à l'import dans le JavaScript comme si ils étaient tous au même niveau. +### Les imports au sein des fichiers de webpack + +Pour importer au sein de webpack, faut préfixer ses imports de `#app:`. + +Example: + +```js +import { paginated } from "#core:utils/api"; +``` + ## Comment ça fonctionne le post processing ? Le post processing est géré par le module `staticfiles`. Les fichiers sont diff --git a/mkdocs.yml b/mkdocs.yml index 10569c61..86d5fab9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -72,6 +72,7 @@ nav: - Gérer les migrations: howto/migrations.md - Gérer les traductions: howto/translation.md - Gérer les statics: howto/statics.md + - Ajouter un chemin d'import javascript: howto/js-import-paths.md - Configurer pour la production: howto/prod.md - Ajouter un logo de promo: howto/logo.md - Ajouter une cotisation: howto/subscriptions.md diff --git a/package.json b/package.json index b151f101..ec4ab6a1 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "license": "GPL-3.0-only", "sideEffects": [".css"], "imports": { - "#openapi": "./staticfiles/generated/openapi/index.ts" + "#openapi": "./staticfiles/generated/openapi/index.ts", + "#core:*": "./core/static/webpack/*" }, "devDependencies": { "@babel/core": "^7.25.2", diff --git a/tsconfig.json b/tsconfig.json index cbf4dbc5..ab03d0bb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,8 @@ "allowJs": true, "moduleResolution": "node", "paths": { - "#openapi": ["./staticfiles/generated/openapi/index.ts"] + "#openapi": ["./staticfiles/generated/openapi/index.ts"], + "#core:*": ["./core/static/webpack/*"] } } }