mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-10-31 00:53:08 +00:00 
			
		
		
		
	add a button to download products as csv
This commit is contained in:
		| @@ -1,8 +1,12 @@ | ||||
| import { paginated } from "#core:utils/api"; | ||||
| import { csv } from "#core:utils/csv"; | ||||
| import { History, getCurrentUrlParams, updateQueryString } from "#core:utils/history"; | ||||
| import type { NestedKeyOf } from "#core:utils/types"; | ||||
| import { showSaveFilePicker } from "native-file-system-adapter"; | ||||
| import { | ||||
|   type ProductSchema, | ||||
|   productSearchProductsDetailed, | ||||
|   type ProductSearchProductsDetailedData, | ||||
|   productSearchProductsDetailed, | ||||
| } from "#openapi"; | ||||
|  | ||||
| type ProductType = string; | ||||
| @@ -11,6 +15,38 @@ type GroupedProducts = Record<ProductType, ProductSchema[]>; | ||||
| const defaultPageSize = 100; | ||||
| const defaultPage = 1; | ||||
|  | ||||
| /** | ||||
|  * Keys of the properties to include in the CSV. | ||||
|  */ | ||||
| const csvColumns = [ | ||||
|   "id", | ||||
|   "name", | ||||
|   "code", | ||||
|   "description", | ||||
|   "product_type.name", | ||||
|   "club.name", | ||||
|   "limit_age", | ||||
|   "purchase_price", | ||||
|   "selling_price", | ||||
|   "archived", | ||||
| ] as NestedKeyOf<ProductSchema>[]; | ||||
|  | ||||
| /** | ||||
|  * Title of the csv columns. | ||||
|  */ | ||||
| const csvColumnTitles = [ | ||||
|   "id", | ||||
|   gettext("name"), | ||||
|   "code", | ||||
|   "description", | ||||
|   gettext("product type"), | ||||
|   "club", | ||||
|   gettext("limit age"), | ||||
|   gettext("purchase price"), | ||||
|   gettext("selling price"), | ||||
|   gettext("archived"), | ||||
| ]; | ||||
|  | ||||
| document.addEventListener("alpine:init", () => { | ||||
|   Alpine.data("productList", () => ({ | ||||
|     loading: false, | ||||
| @@ -84,5 +120,33 @@ document.addEventListener("alpine:init", () => { | ||||
|       }, {}); | ||||
|       this.loading = false; | ||||
|     }, | ||||
|  | ||||
|     /** | ||||
|      * Download products corresponding to the current filters as a CSV file. | ||||
|      * If the pagination has multiple pages, all pages are downloaded. | ||||
|      */ | ||||
|     async downloadCsv() { | ||||
|       this.csvLoading = true; | ||||
|       const fileHandle = await showSaveFilePicker({ | ||||
|         _preferPolyfill: false, | ||||
|         suggestedName: gettext("products.csv"), | ||||
|         types: [], | ||||
|         excludeAcceptAllOption: false, | ||||
|       }); | ||||
|       // if products to download are already in-memory, directly take them. | ||||
|       // If not, fetch them. | ||||
|       const products = | ||||
|         this.nbPages > 1 | ||||
|           ? await paginated(productSearchProductsDetailed, this.getQueryParams()) | ||||
|           : Object.values<ProductSchema[]>(this.products).flat(); | ||||
|       const content = csv.stringify(products, { | ||||
|         columns: csvColumns, | ||||
|         titleRow: csvColumnTitles, | ||||
|       }); | ||||
|       const file = await fileHandle.createWritable(); | ||||
|       await file.write(content); | ||||
|       await file.close(); | ||||
|       this.csvLoading = false; | ||||
|     }, | ||||
|   })); | ||||
| }); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user