mirror of
				https://github.com/ae-utbm/sith.git
				synced 2025-11-04 02:53:06 +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;
 | 
			
		||||
    },
 | 
			
		||||
  }));
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -39,9 +39,19 @@
 | 
			
		||||
    </form>
 | 
			
		||||
    <h3 @click="console.log(totalCount, nbPages())">{% trans %}Product list{% endtrans %}</h3>
 | 
			
		||||
 | 
			
		||||
    <a href="{{ url('counter:new_product') }}" class="btn btn-blue">
 | 
			
		||||
      {% trans %}New product{% endtrans %} <i class="fa fa-plus"></i>
 | 
			
		||||
    </a>
 | 
			
		||||
    <div class="row">
 | 
			
		||||
      <a href="{{ url('counter:new_product') }}" class="btn btn-blue">
 | 
			
		||||
        {% 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">
 | 
			
		||||
      <section :aria-busy="loading"></section>
 | 
			
		||||
    </template>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user