Added primitive search mechanism in backend.

Began implementing search mechanism for frontend.
This commit is contained in:
2021-08-05 01:22:19 -05:00
parent f71758ca69
commit c94ea4a624
56 changed files with 1623 additions and 490 deletions

View File

@@ -1,117 +1,76 @@
import Alpine from "alpinejs";
import { apiHttp } from "~/assets/js/services/http.js";
// All input fields.
let inputs = {
maxPriceEnabled: document.getElementById("max-price-enabled"),
maxShippingEnabled: document.getElementById("max-shipping-enabled"),
minRating: document.getElementById("min-rating"),
maxPrice: document.getElementById("max-price"),
maxShipping: document.getElementById("max-shipping"),
keepUnknownPurchases: document.getElementById("keep-unknown-purchases"),
keepUnknownReviews: document.getElementById("keep-unknown-reviews"),
keepUnknownShipping: document.getElementById("keep-unknown-shipping"),
keepUnrated: document.getElementById("keep-unrated"),
minPrice: document.getElementById("min-price"),
minPurchases: document.getElementById("min-purchases"),
minReviews: document.getElementById("min-reviews"),
shopToggles: {}
};
const startingSlide = "#quick-picks-slide";
async function main() {
setupInteractiveBehavior();
await setupInitialValues((await apiHttp.get("/Search/Default/Filters")).data);
await setupShopToggles((await apiHttp.get("/Search/Shops/Available")).data);
document.querySelector("#configuration .invisible").classList.remove("invisible"); // Load completed, show the UI.
}
function setupInteractiveBehavior() {
let configurationElem = document.getElementById("configuration");
function initInteractiveElements() {
let configurationToggle = document.getElementById("configuration-toggle");
let configurationElem = document.getElementById("configuration");
configurationElem.addEventListener("show.bs.collapse", function () {
configurationToggle.classList.add("active");
});
configurationElem.addEventListener("hidden.bs.collapse", function () {
configurationToggle.classList.remove("active");
});
}
inputs.maxPriceEnabled.addEventListener("change", function () {
inputs.maxPrice.disabled = !this.checked;
});
inputs.maxShippingEnabled.addEventListener("change", function () {
inputs.maxShipping.disabled = !this.checked;
});
inputs.minRating.addEventListener("input", function () {
document.getElementById("min-rating-display").innerHTML = `Minimum rating: ${this.value}%`;
async function initConfigurationData() {
const givenConfig = (await apiHttp.get("/SearchOutline/Filters")).data;
const disabledShops = (await apiHttp.get("/SearchOutline/DisabledShops")).data;
const availableShops = (await apiHttp.get("/Search/Available")).data;
document.addEventListener("alpine:init", () => {
Alpine.data("configuration", () => {
const configuration = {
maxPriceEnabled: givenConfig.enableUpperPrice,
maxPrice: givenConfig.upperPrice,
minPrice: givenConfig.lowerPrice,
maxShippingEnabled: givenConfig.enableMaxShippingFee,
maxShipping: givenConfig.maxShippingFee,
keepUnknownShipping: givenConfig.keepUnknownShipping,
minRating: givenConfig.minRating * 100,
keepUnrated: givenConfig.keepUnrated,
minReviews: givenConfig.minReviews,
keepUnknownReviews: givenConfig.keepUnknownReviewCount,
keepUnknownPurchases: givenConfig.keepUnknownPurchaseCount,
minPurchases: givenConfig.minPurchases,
shops: {},
};
availableShops.forEach(shop => {
configuration.shops[shop] = !disabledShops.includes(shop);
});
return configuration;
});
});
}
async function setupInitialValues(filters) {
inputs.maxShippingEnabled.checked = filters.enableMaxShippingFee;
inputs.maxShippingEnabled.dispatchEvent(new Event("change"));
function initSlides() {
document.querySelectorAll("#content-pages > .selectors > .nav-item > button").forEach(tabElem => {
tabElem.addEventListener("click", () => {
const destUrl = new URL(tabElem.getAttribute("data-bs-target"), window.location.href);
if (location.href === destUrl.href) return;
history.pushState({}, document.title, destUrl);
});
});
const goTo = () => {
const match = location.href.match("(#[\\w-]+)");
const idAnchor = match && match[1] ? match[1] : startingSlide;
document.querySelector("#content-pages > .selectors > .nav-item > .active")?.classList.remove("active");
document.querySelector("#content-pages > .multipage-slides > .active.show")?.classList.remove("active", "show");
document.querySelector(`#content-pages > .selectors > .nav-item > [data-bs-target="${idAnchor}"]`).classList.add("active");
document.querySelector(`#content-pages > .multipage-slides > ${idAnchor}`).classList.add("active", "show");
};
window.addEventListener("popstate", goTo);
goTo();
inputs.maxPriceEnabled.checked = filters.enableUpperPrice;
inputs.maxPriceEnabled.dispatchEvent(new Event("change"));
inputs.keepUnknownPurchases.checked = filters.keepUnknownPurchaseCount;
inputs.keepUnknownPurchases.dispatchEvent(new Event("change"));
inputs.keepUnknownReviews.checked = filters.keepUnknownReviewCount;
inputs.keepUnknownReviews.dispatchEvent(new Event("change"));
inputs.keepUnknownShipping.checked = filters.keepUnknownShipping;
inputs.keepUnknownShipping.dispatchEvent(new Event("change"));
inputs.keepUnrated.checked = filters.keepUnrated;
inputs.keepUnrated.dispatchEvent(new Event("change"));
inputs.minPrice.value = filters.lowerPrice;
inputs.minPrice.dispatchEvent(new Event("change"));
inputs.maxShipping.value = filters.maxShippingFee;
inputs.maxShipping.dispatchEvent(new Event("change"));
inputs.minPurchases.value = filters.minPurchases;
inputs.minPurchases.dispatchEvent(new Event("change"));
inputs.minRating.value = filters.minRating * 100;
inputs.minRating.dispatchEvent(new Event("input"));
inputs.minReviews.value = filters.minReviews;
inputs.minReviews.dispatchEvent(new Event("change"));
inputs.maxPrice.value = filters.upperPrice;
inputs.maxPrice.dispatchEvent(new Event("change"));
require("bootstrap/js/dist/tab.js");
document.querySelector("#content-pages").classList.remove("invisible");
}
async function setupShopToggles(availableShops) {
let disabledShops = (await apiHttp.get("/Search/Default/DisabledShops")).data;
let shopsElem = document.getElementById("shop-checkboxes");
availableShops.forEach(shopName => {
let id = `${shopName}-enabled`;
let shopLabelElem = document.createElement("label");
shopLabelElem.classList.add("form-check-label");
shopLabelElem.htmlFor = id;
shopLabelElem.innerHTML = `Enable ${shopName}`;
let shopCheckboxElem = document.createElement("input");
shopCheckboxElem.classList.add("form-check-input");
shopCheckboxElem.type = "checkbox";
shopCheckboxElem.id = id;
shopCheckboxElem.checked = !disabledShops.includes(shopName);
inputs.shopToggles[shopName] = shopCheckboxElem;
let shopToggleElem = document.createElement("div");
shopToggleElem.classList.add("form-check");
shopToggleElem.appendChild(shopCheckboxElem);
shopToggleElem.appendChild(shopLabelElem);
shopsElem.appendChild(shopToggleElem);
});
async function main() {
initInteractiveElements();
await initConfigurationData();
initSlides();
Alpine.start();
}
main();
// TODO: Implement search.