mirror of
https://github.com/ae-utbm/sith.git
synced 2025-03-10 07:17:11 +00:00
Merge pull request #1029 from ae-utbm/product-filter
add club and counter filters on product list page
This commit is contained in:
commit
6a17e4480e
@ -464,7 +464,7 @@ body {
|
|||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
$col-gap: 1rem;
|
$col-gap: 1rem;
|
||||||
$row-gap: 0.5rem;
|
$row-gap: $col-gap / 3;
|
||||||
|
|
||||||
&.gap {
|
&.gap {
|
||||||
column-gap: $col-gap;
|
column-gap: $col-gap;
|
||||||
|
@ -98,3 +98,5 @@ class ProductFilterSchema(FilterSchema):
|
|||||||
is_archived: bool | None = Field(None, q="archived")
|
is_archived: bool | None = Field(None, q="archived")
|
||||||
buying_groups: set[int] | None = Field(None, q="buying_groups__in")
|
buying_groups: set[int] | None = Field(None, q="buying_groups__in")
|
||||||
product_type: set[int] | None = Field(None, q="product_type__in")
|
product_type: set[int] | None = Field(None, q="product_type__in")
|
||||||
|
club: set[int] | None = Field(None, q="club__in")
|
||||||
|
counter: set[int] | None = Field(None, q="counters__in")
|
||||||
|
@ -60,6 +60,8 @@ document.addEventListener("alpine:init", () => {
|
|||||||
productStatus: "" as "active" | "archived" | "both",
|
productStatus: "" as "active" | "archived" | "both",
|
||||||
search: "",
|
search: "",
|
||||||
productTypes: [] as string[],
|
productTypes: [] as string[],
|
||||||
|
clubs: [] as string[],
|
||||||
|
counters: [] as string[],
|
||||||
pageSize: defaultPageSize,
|
pageSize: defaultPageSize,
|
||||||
page: defaultPage,
|
page: defaultPage,
|
||||||
|
|
||||||
@ -67,13 +69,27 @@ document.addEventListener("alpine:init", () => {
|
|||||||
const url = getCurrentUrlParams();
|
const url = getCurrentUrlParams();
|
||||||
this.search = url.get("search") || "";
|
this.search = url.get("search") || "";
|
||||||
this.productStatus = url.get("productStatus") ?? "active";
|
this.productStatus = url.get("productStatus") ?? "active";
|
||||||
const widget = this.$refs.productTypesInput.widget as TomSelect;
|
const productTypesWidget = this.$refs.productTypesInput.widget as TomSelect;
|
||||||
widget.on("change", (items: string[]) => {
|
productTypesWidget.on("change", (items: string[]) => {
|
||||||
this.productTypes = [...items];
|
this.productTypes = [...items];
|
||||||
});
|
});
|
||||||
|
const clubsWidget = this.$refs.clubsInput.widget as TomSelect;
|
||||||
|
clubsWidget.on("change", (items: string[]) => {
|
||||||
|
this.clubs = [...items];
|
||||||
|
});
|
||||||
|
const countersWidget = this.$refs.countersInput.widget as TomSelect;
|
||||||
|
countersWidget.on("change", (items: string[]) => {
|
||||||
|
this.counters = [...items];
|
||||||
|
});
|
||||||
|
|
||||||
await this.load();
|
await this.load();
|
||||||
const searchParams = ["search", "productStatus", "productTypes"];
|
const searchParams = [
|
||||||
|
"search",
|
||||||
|
"productStatus",
|
||||||
|
"productTypes",
|
||||||
|
"clubs",
|
||||||
|
"counters",
|
||||||
|
];
|
||||||
for (const param of searchParams) {
|
for (const param of searchParams) {
|
||||||
this.$watch(param, () => {
|
this.$watch(param, () => {
|
||||||
this.page = defaultPage;
|
this.page = defaultPage;
|
||||||
@ -109,6 +125,8 @@ document.addEventListener("alpine:init", () => {
|
|||||||
is_archived: isArchived,
|
is_archived: isArchived,
|
||||||
// biome-ignore lint/style/useNamingConvention: api is in snake_case
|
// biome-ignore lint/style/useNamingConvention: api is in snake_case
|
||||||
product_type: [...this.productTypes],
|
product_type: [...this.productTypes],
|
||||||
|
club: [...this.clubs],
|
||||||
|
counter: [...this.counters],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
@ -121,14 +139,17 @@ document.addEventListener("alpine:init", () => {
|
|||||||
const options = this.getQueryParams();
|
const options = this.getQueryParams();
|
||||||
const resp = await productSearchProductsDetailed(options);
|
const resp = await productSearchProductsDetailed(options);
|
||||||
this.nbPages = Math.ceil(resp.data.count / defaultPageSize);
|
this.nbPages = Math.ceil(resp.data.count / defaultPageSize);
|
||||||
this.products = resp.data.results.reduce<GroupedProducts>((acc, curr) => {
|
this.products = resp.data.results.reduce<GroupedProducts>(
|
||||||
|
(acc: GroupedProducts, curr: ProductSchema) => {
|
||||||
const key = curr.product_type?.name ?? gettext("Uncategorized");
|
const key = curr.product_type?.name ?? gettext("Uncategorized");
|
||||||
if (!(key in acc)) {
|
if (!(key in acc)) {
|
||||||
acc[key] = [];
|
acc[key] = [];
|
||||||
}
|
}
|
||||||
acc[key].push(curr);
|
acc[key].push(curr);
|
||||||
return acc;
|
return acc;
|
||||||
}, {});
|
},
|
||||||
|
{},
|
||||||
|
);
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
{% block additional_js %}
|
{% block additional_js %}
|
||||||
<script type="module" src="{{ static("bundled/counter/components/ajax-select-index.ts") }}"></script>
|
<script type="module" src="{{ static("bundled/counter/components/ajax-select-index.ts") }}"></script>
|
||||||
|
<script type="module" src="{{ static("bundled/club/components/ajax-select-index.ts") }}"></script>
|
||||||
<script type="module" src="{{ static("bundled/counter/product-list-index.ts") }}"></script>
|
<script type="module" src="{{ static("bundled/counter/product-list-index.ts") }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
@ -22,7 +23,6 @@
|
|||||||
<h4 class="margin-bottom">{% trans %}Filter products{% endtrans %}</h4>
|
<h4 class="margin-bottom">{% trans %}Filter products{% endtrans %}</h4>
|
||||||
<form id="search-form" class="margin-bottom">
|
<form id="search-form" class="margin-bottom">
|
||||||
<div class="row gap-4x">
|
<div class="row gap-4x">
|
||||||
|
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<label for="search-input">{% trans %}Product name{% endtrans %}</label>
|
<label for="search-input">{% trans %}Product name{% endtrans %}</label>
|
||||||
<input
|
<input
|
||||||
@ -48,16 +48,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</div>
|
</div>
|
||||||
<fieldset>
|
<div class="row gap-4x">
|
||||||
|
<fieldset class="grow">
|
||||||
<label for="type-search-input">{% trans %}Product type{% endtrans %}</label>
|
<label for="type-search-input">{% trans %}Product type{% endtrans %}</label>
|
||||||
<product-type-ajax-select
|
<product-type-ajax-select
|
||||||
id="type-search-input"
|
id="type-search-input"
|
||||||
name="product-type"
|
name="product-type"
|
||||||
x-ref="productTypesInput"
|
x-ref="productTypesInput"
|
||||||
multiple
|
multiple
|
||||||
>
|
></product-type-ajax-select>
|
||||||
</product-type-ajax-select>
|
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
<fieldset class="grow">
|
||||||
|
<label for="club-search-input">{% trans %}Clubs{% endtrans %}</label>
|
||||||
|
<club-ajax-select
|
||||||
|
id="club-search-input"
|
||||||
|
name="club"
|
||||||
|
x-ref="clubsInput"
|
||||||
|
multiple></club-ajax-select>
|
||||||
|
</fieldset>
|
||||||
|
<fieldset class="grow">
|
||||||
|
<label for="counter-search-input">{% trans %}Counters{% endtrans %}</label>
|
||||||
|
<counter-ajax-select
|
||||||
|
id="counter-search-input"
|
||||||
|
name="counter"
|
||||||
|
x-ref="countersInput"
|
||||||
|
multiple
|
||||||
|
></counter-ajax-select>
|
||||||
|
</fieldset>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<h3 class="margin-bottom">{% trans %}Product list{% endtrans %}</h3>
|
<h3 class="margin-bottom">{% trans %}Product list{% endtrans %}</h3>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user