Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: price filter #70

Merged
merged 5 commits into from
May 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions import_map.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"imports": {
"deco-sites/std/": "./",
"$live/": "https://denopkg.com/deco-cx/live@1.2.2/",
"$live/": "https://denopkg.com/deco-cx/live@1.3.7/",
"partytown/": "https://deno.land/x/[email protected]/",
"$fresh/": "https://deno.land/x/[email protected]/",
"preact": "https://esm.sh/[email protected]",
Expand All @@ -11,4 +11,4 @@
"@preact/signals-core": "https://esm.sh/*@preact/[email protected]",
"std/": "https://deno.land/[email protected]/"
}
}
}
5 changes: 3 additions & 2 deletions packs/vtex/loaders/intelligentSearch/productDetailsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
withSegmentCookie,
} from "deco-sites/std/packs/vtex/utils/segment.ts";
import {
toPath,
withDefaultFacets,
withDefaultParams,
} from "deco-sites/std/packs/vtex/utils/intelligentSearch.ts";
Expand Down Expand Up @@ -85,7 +86,7 @@ const loader = async (
const params = withDefaultParams({ query, count: 1 }, ctx);

const { products: [product] } = await fetchAPI<ProductSearchResult>(
`${search.facets(facets)}?${params}`,
`${search.facets(toPath(facets))}?${params}`,
{
withProxyCache: true,
headers: withSegmentCookie(segment),
Expand All @@ -107,7 +108,7 @@ const loader = async (
}, ctx);

const result = await fetchAPI<ProductSearchResult>(
`${search.facets(facets)}?${params}`,
`${search.facets(toPath(facets))}?${params}`,
{
withProxyCache: true,
headers: withSegmentCookie(segment),
Expand Down
3 changes: 2 additions & 1 deletion packs/vtex/loaders/intelligentSearch/productList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "deco-sites/std/packs/vtex/utils/segment.ts";
import { fetchAPI } from "deco-sites/std/utils/fetch.ts";
import {
toPath,
withDefaultFacets,
withDefaultParams,
} from "deco-sites/std/packs/vtex/utils/intelligentSearch.ts";
Expand Down Expand Up @@ -129,7 +130,7 @@ const loader = async (

// search products on VTEX. Feel free to change any of these parameters
const { products: vtexProducts } = await fetchAPI<ProductSearchResult>(
`${search.facets(facets)}?${params}`,
`${search.facets(toPath(facets))}?${params}`,
{
withProxyCache: true,
headers: withSegmentCookie(segment),
Expand Down
58 changes: 45 additions & 13 deletions packs/vtex/loaders/intelligentSearch/productListingPage.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
filtersFromSearchParams,
mergeFacets,
toFilter,
toProduct,
} from "deco-sites/std/packs/vtex/utils/transform.ts";
Expand All @@ -16,6 +17,7 @@ import type {
SelectedFacet,
} from "deco-sites/std/packs/vtex/types.ts";
import {
toPath,
withDefaultFacets,
withDefaultParams,
} from "deco-sites/std/packs/vtex/utils/intelligentSearch.ts";
Expand All @@ -25,11 +27,14 @@ import {
pageTypesFromPathname,
pageTypesToBreadcrumbList,
} from "deco-sites/std/packs/vtex/utils/legacy.ts";
import { parseRange } from "deco-sites/std/utils/filters.ts";
import type { ProductListingPage } from "deco-sites/std/commerce/types.ts";
import type {
Filter,
ProductListingPage,
} from "deco-sites/std/commerce/types.ts";
import type { Fuzzy, Sort } from "deco-sites/std/packs/vtex/types.ts";
Facet,
Fuzzy,
RangeFacet,
Sort,
} from "deco-sites/std/packs/vtex/types.ts";
import type { Context } from "deco-sites/std/packs/vtex/accounts/vtex.ts";

/** this type is more friendly user to fuzzy type that is 0, 1 or auto. */
Expand Down Expand Up @@ -133,10 +138,12 @@ const searchArgsOf = (props: Props, url: URL) => {
const page = url.searchParams.get("page")
? Number(url.searchParams.get("page")) - (currentPageoffset)
: 0;
const sort = url.searchParams.get("sort") as Sort ??
const sort = props.sort ?? url.searchParams.get("sort") as Sort ??
LEGACY_TO_IS[url.searchParams.get("O") ?? ""] ?? sortOptions[0].value;
const selectedFacets = props.selectedFacets ||
filtersFromSearchParams(url.searchParams);
const selectedFacets = mergeFacets(
props.selectedFacets ?? [],
filtersFromSearchParams(url.searchParams),
);
const fuzzy = mapLabelledFuzzyToFuzzy(props.fuzzy) ??
url.searchParams.get("fuzzy") as Fuzzy;

Expand Down Expand Up @@ -185,6 +192,31 @@ const filtersFromPathname = (pages: PageType[]) =>
})
.filter((facet): facet is { key: string; value: string } => Boolean(facet));

// Search API does not return the selected price filter, so there is no way for the
// user to remove this price filter after it is set. This function selects the facet
// so users can clear the price filters
const selectPriceFacet = (facets: Facet[], selectedFacets: SelectedFacet[]) => {
const price = facets.find((f): f is RangeFacet => f.key === "price");
const ranges = selectedFacets
.filter((k) => k.key === "price")
.map((s) => parseRange(s.value))
.filter(Boolean);

if (price) {
for (const range of ranges) {
if (!range) continue;

for (const val of price.values) {
if (val.range.from === range.from && val.range.to === range.to) {
val.selected = true;
}
}
}
}

return facets;
};

/**
* @title VTEX product listing page - Intelligent Search
* @description Returns data ready for search pages like category,brand pages
Expand Down Expand Up @@ -214,22 +246,23 @@ const loader = async (
: baseSelectedFacets;

const selected = withDefaultFacets(selectedFacets, ctx);
const fselected = selected.filter((f) => f.key !== "price");
const params = withDefaultParams({ ...args, page }, ctx);

// search products on VTEX. Feel free to change any of these parameters
const [productsResult, facetsResult] = await Promise.all([
fetchAPI<ProductSearchResult>(
`${search.product_search.facets(selected)}?${params}`,
`${search.product_search.facets(toPath(selected))}?${params}`,
{ withProxyCache: true, headers: withSegmentCookie(segment) },
),
fetchAPI<FacetSearchResult>(
`${search.facets.facets(selected)}?${params}`,
`${search.facets.facets(toPath(fselected))}?${params}`,
{ withProxyCache: true, headers: withSegmentCookie(segment) },
),
]);
const { products: vtexProducts, pagination, recordsFiltered } =
productsResult;
const { facets } = facetsResult;
const facets = selectPriceFacet(facetsResult.facets, selectedFacets);

// Transform VTEX product format into schema.org's compatible format
// If a property is missing from the final `products` array you can add
Expand All @@ -240,9 +273,8 @@ const loader = async (
priceCurrency: config!.defaultPriceCurrency,
})
);
const filters = facets
.map((f) => !f.hidden && toFilter(f, selectedFacets))
.filter((x): x is Filter => Boolean(x));

const filters = facets.filter((f) => !f.hidden).map(toFilter(selectedFacets));
const itemListElement = pageTypesToBreadcrumbList(
await pageTypesPromise,
baseUrl,
Expand Down
3 changes: 2 additions & 1 deletion packs/vtex/loaders/intelligentSearch/suggestions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from "deco-sites/std/packs/vtex/utils/segment.ts";
import { fetchAPI } from "deco-sites/std/utils/fetch.ts";
import {
toPath,
withDefaultFacets,
withDefaultParams,
} from "deco-sites/std/packs/vtex/utils/intelligentSearch.ts";
Expand Down Expand Up @@ -61,7 +62,7 @@ const loaders = async (
const params = withDefaultParams({ query, count: count ?? 4, locale }, ctx);

return fetchAPI<ProductSearchResult>(
`${search.product_search.facets(facets)}?${params}`,
`${search.product_search.facets(toPath(facets))}?${params}`,
{ withProxyCache: true, headers: withSegmentCookie(segment) },
);
};
Expand Down
22 changes: 17 additions & 5 deletions packs/vtex/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -827,22 +827,32 @@ export interface SpecificationGroup {
}>;
}

export type FilterType = "PRICERANGE" | "TEXT" | "NUMBER" | "CATEGORYTREE";
export type FilterType = RangeFacet["type"] | BooleanFacet["type"];

export interface FacetSearchResult {
facets: Facet[];
breadcrumb: Breadcrumb[];
}

export interface Facet<T = FacetValueBoolean | FacetValueRange> {
type: FilterType;
export interface BaseFacet {
name: string;
hidden: boolean;
values: T[];
quantity: number;
key: string;
quantity: number;
}

export interface RangeFacet extends BaseFacet {
type: "PRICERANGE";
values: FacetValueRange[];
}

export interface BooleanFacet extends BaseFacet {
type: "TEXT" | "NUMBER";
values: FacetValueBoolean[];
}

export type Facet = RangeFacet | BooleanFacet;

export interface FacetValueBoolean {
quantity: number;
name: string;
Expand All @@ -853,6 +863,8 @@ export interface FacetValueBoolean {
}

export interface FacetValueRange {
selected: boolean;
quantity: number;
range: {
from: number;
to: number;
Expand Down
7 changes: 4 additions & 3 deletions packs/vtex/utils/intelligentSearch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,12 @@ export const withDefaultFacets = (
facets.push(regionFacet);
}

return facets
.map(({ key, value }) => `${key}/${value}`)
.join("/");
return facets;
};

export const toPath = (facets: SelectedFacet[]) =>
facets.map(({ key, value }) => `${key}/${value}`).join("/");

interface Params {
query: string;
page: number;
Expand Down
Loading