Fix Global Catalogue browsing and import
Removes InventoryView's broken duplicate Global Catalogue tab, which misused createproductlocation with catalogue ids that never match real product ids (imports silently failed to land) and showed fabricated Math.random() pricing/ratings. "Import Product" now routes to the already-correct CatalogueBrowser instead. Also fixes catalogueApi's product_count field mismatch (brand chip counts were always blank), a pagination bug that capped the catalogue at 100 of ~237 products with no way to see the rest, and replaces ImportProductModal's free-text category id input with a real dropdown scoped to the tenant's own categories, filtering subcategories to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -36,17 +36,19 @@ export interface ImportCatalogueProductRequest {
|
||||
taxpercent: number;
|
||||
}
|
||||
|
||||
async function apiGet<T>(url: URL): Promise<T[]> {
|
||||
async function apiGet<T>(url: URL): Promise<{ items: T[]; total: number }> {
|
||||
const res = await fetch(url, { headers: { Accept: 'application/json' } });
|
||||
if (!res.ok) {
|
||||
throw new Error(`Catalogue API failed: ${res.status} ${res.statusText}`);
|
||||
}
|
||||
const json = await res.json();
|
||||
if (Array.isArray(json)) return json;
|
||||
if (Array.isArray(json)) return { items: json, total: json.length };
|
||||
if (json && typeof json === 'object' && 'details' in json) {
|
||||
return json.details || [];
|
||||
const items = json.details || [];
|
||||
const total = typeof json.total === 'number' ? json.total : items.length;
|
||||
return { items, total };
|
||||
}
|
||||
return [];
|
||||
return { items: [], total: 0 };
|
||||
}
|
||||
|
||||
// brand omitted → the entire catalogue, all brands merged.
|
||||
@@ -59,9 +61,9 @@ export async function getCatalogueProducts(opts: {
|
||||
if (keyword) url.searchParams.set("keyword", keyword);
|
||||
url.searchParams.set("pageno", String(pageno));
|
||||
url.searchParams.set("pagesize", String(pagesize));
|
||||
|
||||
const products = await apiGet<CatalogueProduct>(url);
|
||||
return { products, total: products.length };
|
||||
|
||||
const { items, total } = await apiGet<CatalogueProduct>(url);
|
||||
return { products: items, total };
|
||||
}
|
||||
|
||||
// brand omitted → imported refs across every brand.
|
||||
@@ -69,9 +71,9 @@ export async function getImportedCatalogueRefs(tenantid: number, brand?: string)
|
||||
const url = new URL(`${API_BASE}/products/getimportedcatalogueproducts`);
|
||||
url.searchParams.set("tenantid", String(tenantid));
|
||||
if (brand) url.searchParams.set("brand", brand);
|
||||
|
||||
const refs = await apiGet<ImportedRef>(url);
|
||||
return new Set(refs.map((r) => `${r.brand}:${r.catalogueid}`));
|
||||
|
||||
const { items } = await apiGet<ImportedRef>(url);
|
||||
return new Set(items.map((r) => `${r.brand}:${r.catalogueid}`));
|
||||
}
|
||||
|
||||
export async function importCatalogueProducts(items: ImportCatalogueProductRequest[]) {
|
||||
@@ -102,16 +104,21 @@ export async function removeFromStoreCatalogue(tenantid: number, locationid: num
|
||||
return json;
|
||||
}
|
||||
|
||||
export interface CatalogueBrand {
|
||||
brand: string;
|
||||
product_count: number;
|
||||
}
|
||||
|
||||
export async function getBrands() {
|
||||
const url = new URL(`${API_BASE}/catalogue/getbrands`);
|
||||
const brands = await apiGet<{ brand: string; count: number }>(url);
|
||||
return brands;
|
||||
const { items } = await apiGet<CatalogueBrand>(url);
|
||||
return items;
|
||||
}
|
||||
|
||||
export async function getProductSubcategories(tenantid: number, categoryid?: number) {
|
||||
const url = new URL(`${API_BASE}/products/getproductsubcategories`);
|
||||
url.searchParams.set("tenantid", String(tenantid));
|
||||
if (categoryid) url.searchParams.set("categoryid", String(categoryid));
|
||||
const subcategories = await apiGet<{ subcategoryid: number; subcategoryname: string }>(url);
|
||||
return subcategories;
|
||||
const { items } = await apiGet<{ subcategoryid: number; subcategoryname: string }>(url);
|
||||
return items;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user