mirror of
https://github.com/ae-utbm/sith.git
synced 2025-01-03 13:41:15 +00:00
add a button to download products as csv
This commit is contained in:
parent
39b36aa509
commit
1a9556f811
@ -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 { History, getCurrentUrlParams, updateQueryString } from "#core:utils/history";
|
||||||
|
import type { NestedKeyOf } from "#core:utils/types";
|
||||||
|
import { showSaveFilePicker } from "native-file-system-adapter";
|
||||||
import {
|
import {
|
||||||
type ProductSchema,
|
type ProductSchema,
|
||||||
productSearchProductsDetailed,
|
|
||||||
type ProductSearchProductsDetailedData,
|
type ProductSearchProductsDetailedData,
|
||||||
|
productSearchProductsDetailed,
|
||||||
} from "#openapi";
|
} from "#openapi";
|
||||||
|
|
||||||
type ProductType = string;
|
type ProductType = string;
|
||||||
@ -11,6 +15,38 @@ type GroupedProducts = Record<ProductType, ProductSchema[]>;
|
|||||||
const defaultPageSize = 100;
|
const defaultPageSize = 100;
|
||||||
const defaultPage = 1;
|
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", () => {
|
document.addEventListener("alpine:init", () => {
|
||||||
Alpine.data("productList", () => ({
|
Alpine.data("productList", () => ({
|
||||||
loading: false,
|
loading: false,
|
||||||
@ -84,5 +120,33 @@ document.addEventListener("alpine:init", () => {
|
|||||||
}, {});
|
}, {});
|
||||||
this.loading = false;
|
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;
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
@ -39,9 +39,19 @@
|
|||||||
</form>
|
</form>
|
||||||
<h3 @click="console.log(totalCount, nbPages())">{% trans %}Product list{% endtrans %}</h3>
|
<h3 @click="console.log(totalCount, nbPages())">{% trans %}Product list{% endtrans %}</h3>
|
||||||
|
|
||||||
<a href="{{ url('counter:new_product') }}" class="btn btn-blue">
|
<div class="row">
|
||||||
{% trans %}New product{% endtrans %} <i class="fa fa-plus"></i>
|
<a href="{{ url('counter:new_product') }}" class="btn btn-blue">
|
||||||
</a>
|
{% trans %}New product{% endtrans %} <i class="fa fa-plus"></i>
|
||||||
|
</a>
|
||||||
|
<button
|
||||||
|
class="btn btn-blue"
|
||||||
|
@click="downloadCsv()"
|
||||||
|
:disabled="csvLoading"
|
||||||
|
:aria-busy="csvLoading"
|
||||||
|
>
|
||||||
|
{% trans %}Download as cvs{% endtrans %} <i class="fa fa-file-arrow-down"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
<template x-if="loading">
|
<template x-if="loading">
|
||||||
<section :aria-busy="loading"></section>
|
<section :aria-busy="loading"></section>
|
||||||
</template>
|
</template>
|
||||||
|
Loading…
Reference in New Issue
Block a user