Query serialization.

This commit is contained in:
Mario Zechner 2023-06-12 11:46:59 +02:00
parent d7426bc395
commit df5b78c1d5
3 changed files with 79 additions and 14 deletions

View File

@ -10,9 +10,9 @@ require("./views");
itemsFilter.model = itemsList.model = model.items;
const stateToUrl = (event) => {
const filterState = JSON.stringify(itemsFilter.state);
const listState = JSON.stringify(itemsList.state);
const chartState = JSON.stringify(itemsChart.state);
const filterState = itemsFilter.shareableState;
const listState = itemsList.shareableState;
const chartState = itemsChart.shareableState;
const chartedItems = model.items.filteredItems
.filter((item) => item.chart)
.map((item) => item.store + item.id)
@ -27,9 +27,9 @@ require("./views");
const l = getQueryParameter("l");
const c = getQueryParameter("c");
const d = getQueryParameter("d");
if (f) itemsFilter.state = JSON.parse(f);
if (l) itemsList.state = JSON.parse(l);
if (c) itemsChart.state = JSON.parse(c);
if (f) itemsFilter.shareableState = f;
if (l) itemsList.shareableState = l;
if (c) itemsChart.shareableState = c;
if (d) {
for (const id of d.split(";")) {
model.items.lookup[id].chart = true;

View File

@ -42,15 +42,10 @@ class ItemsFilter extends View {
</select>
</label>
<label>
<input x-id="priceChangesSinceLast" x-state type="radio" name="type" /> Billiger seit letzter Änderung
<input x-id="priceChangesCheaper" x-state type="radio" name="type" /> Billiger seit letzter Änderung
</label>
</div>
<div x-id="priceDirection" class="flex justify-center gap-2 mt-4 ${this._hideMisc ? "" : "mb-4"} ${hidePriceDirection}">
<custom-checkbox x-id="priceIncreased" x-state x-change label="Teurer" checked class="gray"></custom-checkbox>
<custom-checkbox x-id="priceDecreased" x-state x-change label="Billiger" checked class="gray"></custom-checkbox>
</div>
<div x-id="misc" class="flex items-center justify-center flex-wrap gap-2 mt-4 ${hideMisc}">
<custom-checkbox
x-id="budgetBrands" x-state x-change
@ -65,6 +60,11 @@ class ItemsFilter extends View {
<input x-id="maxPrice" x-state x-input-debounce class="w-12" type="number" min="0" value="100">
</label>
</div>
<div x-id="priceDirection" class="flex justify-center gap-2 mt-4 ${this._hideMisc ? "" : "mb-4"} ${hidePriceDirection}">
<custom-checkbox x-id="priceIncreased" x-state x-change label="Teurer" checked class="gray"></custom-checkbox>
<custom-checkbox x-id="priceDecreased" x-state x-change label="Billiger" checked class="gray"></custom-checkbox>
</div>
`;
this.classList.add("items-filter");
@ -93,8 +93,8 @@ class ItemsFilter extends View {
this.fireChangeEvent();
});
elements.priceChangesSinceLast.addEventListener("change", () => {
if (elements.priceChangesSinceLast.checked) elements.priceDirection.classList.add("hidden");
elements.priceChangesCheaper.addEventListener("change", () => {
if (elements.priceChangesCheaper.checked) elements.priceDirection.classList.add("hidden");
else elements.priceDirection.classList.remove("hidden");
this.fireChangeEvent();
});
@ -239,6 +239,44 @@ class ItemsFilter extends View {
get checkedStores() {
return STORE_KEYS.filter((store) => this.elements[store].checked);
}
get shareableState() {
const state = this.state;
const shareableState = Object.keys(state)
.sort()
.filter((el) => !STORE_KEYS.includes(el))
.map((el) => {
let value = state[el];
if (value === true) value = ".";
if (value === false) value = "-";
return value;
})
.join(";");
const disabledStores = STORE_KEYS.filter((store) => !state[store]).join(";");
if (disabledStores.length > 0) return shareableState + ";" + disabledStores;
else return shareableState;
}
set shareableState(shareableState) {
const values = shareableState.split(";");
const state = this.state;
let storeIndex = -1;
Object.keys(state)
.sort()
.filter((el) => !STORE_KEYS.includes(el))
.forEach((el, index) => {
if (values[index] === ".") state[el] = true;
else if (values[index] === "-") state[el] = false;
else state[el] = values[index];
storeIndex = index + 1;
});
if (storeIndex < values.length) {
for (let i = storeIndex; i < values.length; i++) {
state[values[i]] = false;
}
}
this.state = state;
}
}
customElements.define("items-filter", ItemsFilter);

View File

@ -114,6 +114,33 @@ class View extends HTMLElement {
this.fireChangeEvent();
}
get shareableState() {
const state = this.state;
const shareableState = Object.keys(state)
.sort()
.map((el) => {
let value = state[el];
if (value === true) value = ".";
if (value === false) value = "-";
return value;
})
.join(";");
return shareableState;
}
set shareableState(shareableState) {
const values = shareableState.split(";");
const state = this.state;
Object.keys(state)
.sort()
.forEach((el, index) => {
if (values[index] === ".") state[el] = true;
else if (values[index] === "-") state[el] = false;
else state[el] = values[index];
});
this.state = state;
}
render() {}
setupEventHandlers() {