7960 Add categories v2 to product endpoint (#187)
This commit is contained in:
@@ -65,6 +65,27 @@ WHERE product_category.product_id = ?
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProductCategoriesV2(productId: number): Promise<Array<Category>> {
|
||||||
|
ScopeAccess.validate(this.user).all([Scopes.CATEGORIES_READ]);
|
||||||
|
const query = /* sql */ `
|
||||||
|
SELECT product_category.category_id as id,
|
||||||
|
categories.*
|
||||||
|
FROM product_category
|
||||||
|
JOIN v_categorytree_v2 categories ON product_category.category_id = categories.id
|
||||||
|
WHERE product_category.product_id = ?
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await this.knex.raw(query, productId).then((data) =>
|
||||||
|
data.rows.map((row) => {
|
||||||
|
return {
|
||||||
|
...row,
|
||||||
|
pathNumeric: row.path_numeric,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
async getCategoryBasedFacets(
|
async getCategoryBasedFacets(
|
||||||
productId: number,
|
productId: number,
|
||||||
): Promise<{ room: string[]; color: string[] }> {
|
): Promise<{ room: string[]; color: string[] }> {
|
||||||
@@ -153,6 +174,26 @@ WHERE product_category.product_id = ?
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getCategoriesV2(ids: number[]): Promise<Array<Category>> {
|
||||||
|
ScopeAccess.validate(this.user).some([
|
||||||
|
Scopes.CATEGORIES_READ,
|
||||||
|
Scopes.CATEGORIES_PUBLIC_READ,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
this.knex
|
||||||
|
.select('*')
|
||||||
|
.modify((queryBuilder) => {
|
||||||
|
if (ids) {
|
||||||
|
queryBuilder.whereIn('id', ids);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.from('v_categorytree_v2')
|
||||||
|
// @ts-ignore
|
||||||
|
.cache(MINUTE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
async searchCategories(name: string): Promise<Array<Category>> {
|
async searchCategories(name: string): Promise<Array<Category>> {
|
||||||
ScopeAccess.validate(this.user).all([Scopes.CATEGORIES_READ]);
|
ScopeAccess.validate(this.user).all([Scopes.CATEGORIES_READ]);
|
||||||
return this.knex
|
return this.knex
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ async function getCategories(_, { ids }, { dataSources }) {
|
|||||||
return (<CategoryAPI>dataSources.categoryApi).getCategories(ids);
|
return (<CategoryAPI>dataSources.categoryApi).getCategories(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getCategoriesV2(_, { ids }, { dataSources }) {
|
||||||
|
return (<CategoryAPI>dataSources.categoryApi).getCategoriesV2(ids);
|
||||||
|
}
|
||||||
|
|
||||||
async function getCategory(_, { id }, { dataSources }) {
|
async function getCategory(_, { id }, { dataSources }) {
|
||||||
return (<CategoryAPI>dataSources.categoryApi).getCategoryById(id);
|
return (<CategoryAPI>dataSources.categoryApi).getCategoryById(id);
|
||||||
}
|
}
|
||||||
@@ -34,5 +38,6 @@ export const categoryTypeDefs = { Category };
|
|||||||
|
|
||||||
export const categoryQueryTypeDefs = {
|
export const categoryQueryTypeDefs = {
|
||||||
categories: getCategories,
|
categories: getCategories,
|
||||||
|
categories_v2: getCategoriesV2,
|
||||||
category: getCategory,
|
category: getCategory,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import { ProductAPI } from '../datasources/product-api';
|
import { ProductAPI } from '../datasources/product-api';
|
||||||
import {
|
import { Orientation, ProductGroup } from '../types/product-types';
|
||||||
Orientation,
|
import type {
|
||||||
PrintProduct,
|
PrintProduct as PrintProductType,
|
||||||
Product,
|
Product as ProductType,
|
||||||
ProductGroup,
|
|
||||||
ProductListResult,
|
ProductListResult,
|
||||||
ProductsFilterInput,
|
ProductsFilterInput,
|
||||||
ProductsSearchResult,
|
ProductsSearchResult,
|
||||||
@@ -16,7 +15,7 @@ import { Keyword } from '../types/keyword-types';
|
|||||||
import { MarketLocaleAPI } from '../datasources/market-locale-api';
|
import { MarketLocaleAPI } from '../datasources/market-locale-api';
|
||||||
import { InteriorAPI } from '../datasources/interior-api';
|
import { InteriorAPI } from '../datasources/interior-api';
|
||||||
import { InteriorsLambdaAPI } from '../datasources/interiors-lambda-api';
|
import { InteriorsLambdaAPI } from '../datasources/interiors-lambda-api';
|
||||||
import { IdNumberResult, MarketInput } from '../types/types';
|
import type { IdNumberResult } from '../types/types';
|
||||||
import { moveS3File } from '../aws/s3';
|
import { moveS3File } from '../aws/s3';
|
||||||
import { DesignerAPI } from '../datasources/designer-api';
|
import { DesignerAPI } from '../datasources/designer-api';
|
||||||
import { PrintProductDefaultsAPI } from '../datasources/printproduct-defaults-api';
|
import { PrintProductDefaultsAPI } from '../datasources/printproduct-defaults-api';
|
||||||
@@ -36,7 +35,7 @@ const ProductBlacklist = {
|
|||||||
|
|
||||||
const Product = {
|
const Product = {
|
||||||
async printProducts(
|
async printProducts(
|
||||||
product: { printProducts: PrintProduct[] },
|
product: { printProducts: PrintProductType[] },
|
||||||
input: { groups: ProductGroup[] },
|
input: { groups: ProductGroup[] },
|
||||||
) {
|
) {
|
||||||
if (!input.groups) {
|
if (!input.groups) {
|
||||||
@@ -49,6 +48,13 @@ const Product = {
|
|||||||
async categories({ id }, _args, { dataSources }): Promise<Array<Category>> {
|
async categories({ id }, _args, { dataSources }): Promise<Array<Category>> {
|
||||||
return (<CategoryAPI>dataSources.categoryApi).getProductCategories(id);
|
return (<CategoryAPI>dataSources.categoryApi).getProductCategories(id);
|
||||||
},
|
},
|
||||||
|
async categories_v2(
|
||||||
|
{ id },
|
||||||
|
_args,
|
||||||
|
{ dataSources },
|
||||||
|
): Promise<Array<Category>> {
|
||||||
|
return (<CategoryAPI>dataSources.categoryApi).getProductCategoriesV2(id);
|
||||||
|
},
|
||||||
async collections({ id }, _args, { dataSources }) {
|
async collections({ id }, _args, { dataSources }) {
|
||||||
return dataSources.collectionApi.getProductCollections(id);
|
return dataSources.collectionApi.getProductCollections(id);
|
||||||
},
|
},
|
||||||
@@ -64,7 +70,7 @@ const Product = {
|
|||||||
async related({ id }, _args, { dataSources }) {
|
async related({ id }, _args, { dataSources }) {
|
||||||
return (<ProductAPI>dataSources.productApi).getRelatedProducts(id);
|
return (<ProductAPI>dataSources.productApi).getRelatedProducts(id);
|
||||||
},
|
},
|
||||||
async facets(product: Product, _args, { dataSources }) {
|
async facets(product: ProductType, _args, { dataSources }) {
|
||||||
const keywords = await (<KeywordAPI>(
|
const keywords = await (<KeywordAPI>(
|
||||||
dataSources.keywordApi
|
dataSources.keywordApi
|
||||||
)).getProductKeywords(product.id);
|
)).getProductKeywords(product.id);
|
||||||
@@ -177,7 +183,7 @@ async function getProductsSearchResult(
|
|||||||
]).then((d) => {
|
]).then((d) => {
|
||||||
// flatten, remove falsy (each searchBy... can return undefined above)
|
// flatten, remove falsy (each searchBy... can return undefined above)
|
||||||
// and finally remove duplicates.
|
// and finally remove duplicates.
|
||||||
const products = {} as { [key: string]: Product };
|
const products = {} as { [key: string]: ProductType };
|
||||||
d.flat().forEach((product) => {
|
d.flat().forEach((product) => {
|
||||||
if (product && !products[product.id]) {
|
if (product && !products[product.id]) {
|
||||||
products[product.id] = product;
|
products[product.id] = product;
|
||||||
@@ -208,7 +214,7 @@ async function getProductsSearchResult(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getProduct(_, { id }, { dataSources }): Promise<Product> {
|
async function getProduct(_, { id }, { dataSources }): Promise<ProductType> {
|
||||||
return (<ProductAPI>dataSources.productApi).getProduct(id);
|
return (<ProductAPI>dataSources.productApi).getProduct(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,7 +222,7 @@ async function getProductByPath(
|
|||||||
_,
|
_,
|
||||||
{ path },
|
{ path },
|
||||||
{ dataSources },
|
{ dataSources },
|
||||||
): Promise<Product> {
|
): Promise<ProductType> {
|
||||||
return (<ProductAPI>dataSources.productApi).getProductByPath(path);
|
return (<ProductAPI>dataSources.productApi).getProductByPath(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ type Query {
|
|||||||
productByPath(path: String!): Product
|
productByPath(path: String!): Product
|
||||||
productsSearch(q: String!): ProductsSearchResult
|
productsSearch(q: String!): ProductsSearchResult
|
||||||
categories(ids: [Int]): [Category]
|
categories(ids: [Int]): [Category]
|
||||||
|
categories_v2(ids: [Int]): [Category]
|
||||||
category(id: Int!): Category
|
category(id: Int!): Category
|
||||||
keywords: [Keyword]
|
keywords: [Keyword]
|
||||||
keyword(id: Int!): Keyword
|
keyword(id: Int!): Keyword
|
||||||
@@ -262,6 +263,7 @@ type Product {
|
|||||||
printProducts(groups: [ProductGroup]): [PrintProduct]
|
printProducts(groups: [ProductGroup]): [PrintProduct]
|
||||||
blacklisting: [ProductBlacklist]
|
blacklisting: [ProductBlacklist]
|
||||||
categories: [Category]
|
categories: [Category]
|
||||||
|
categories_v2: [Category]
|
||||||
collections: [Collection]
|
collections: [Collection]
|
||||||
designerId: Int
|
designerId: Int
|
||||||
designer: Designer
|
designer: Designer
|
||||||
|
|||||||
Reference in New Issue
Block a user