resolved the assets filter
This commit is contained in:
@@ -33,9 +33,23 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
const [isBulkMode, setIsBulkMode] = useState(false);
|
||||
const [selectedVariantIds, setSelectedVariantIds] = useState<string[]>([]);
|
||||
|
||||
// Strict product isolation & configured variants filtering
|
||||
const configuredVariants = useMemo(() => {
|
||||
const productSpecific = variants.filter((v: any) => {
|
||||
const pId = v.parentProductId || v.product_id || v.productId;
|
||||
return !pId || pId === productId;
|
||||
});
|
||||
if (productSpecific.length <= 1) return productSpecific;
|
||||
return productSpecific.filter((v: any) => {
|
||||
const hasAttrObj = v.attributes && Object.keys(v.attributes).length > 0;
|
||||
const hasAttrArr = Array.isArray(v.values) && v.values.length > 0;
|
||||
return hasAttrObj || hasAttrArr;
|
||||
});
|
||||
}, [variants, productId]);
|
||||
|
||||
const variantFilterOptions = useMemo(() => {
|
||||
const map = new Map<string, { name: string; values: Set<string> }>();
|
||||
variants.forEach(v => {
|
||||
configuredVariants.forEach(v => {
|
||||
if (v.attributes && typeof v.attributes === 'object') {
|
||||
Object.entries(v.attributes).forEach(([code, val]) => {
|
||||
if (val !== undefined && val !== null && val !== '') {
|
||||
@@ -67,7 +81,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
});
|
||||
});
|
||||
return result;
|
||||
}, [variants]);
|
||||
}, [configuredVariants]);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
@@ -164,7 +178,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
|
||||
const combinedAssets = useMemo(() => {
|
||||
const list: any[] = [];
|
||||
const validVariantIds = new Set(variants.map(v => v.id));
|
||||
const validVariantIds = new Set(configuredVariants.map(v => v.id));
|
||||
|
||||
assignedAssets.forEach(a => {
|
||||
const aProdId = a.product_id || (a as any).productId;
|
||||
@@ -181,7 +195,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
assignedVariantAssets.forEach(va => {
|
||||
const vId = va.variantId || va.variant_id || va.variant?.id;
|
||||
if (vId && (validVariantIds.size === 0 || validVariantIds.has(vId))) {
|
||||
const matchedVariant = variants.find(v => v.id === vId);
|
||||
const matchedVariant = configuredVariants.find(v => v.id === vId);
|
||||
const vName = va.variantName || va.variant?.name || matchedVariant?.name || 'Variant';
|
||||
const vSku = va.variantSku || va.variant?.sku || matchedVariant?.sku || '';
|
||||
list.push({
|
||||
@@ -195,7 +209,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
});
|
||||
|
||||
return list;
|
||||
}, [assignedAssets, assignedVariantAssets, variants, productId]);
|
||||
}, [assignedAssets, assignedVariantAssets, configuredVariants, productId]);
|
||||
|
||||
const [scopeFilter, setScopeFilter] = useState<string>('all');
|
||||
|
||||
@@ -234,7 +248,11 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
const sorted = [...data].sort((a, b) => (a.display_order || 0) - (b.display_order || 0));
|
||||
setAssignedAssets(sorted);
|
||||
const rawVars = Array.isArray(productVariants) ? productVariants : (productVariants as any)?.data || [];
|
||||
setVariants(Array.isArray(rawVars) ? rawVars : []);
|
||||
const productIsolatedVars = (Array.isArray(rawVars) ? rawVars : []).filter((v: any) => {
|
||||
const pId = v.parentProductId || v.product_id || v.productId;
|
||||
return !pId || pId === productId;
|
||||
});
|
||||
setVariants(productIsolatedVars);
|
||||
const rawVarAssets = Array.isArray(allVariantAssets) ? allVariantAssets : (allVariantAssets as any)?.data || [];
|
||||
setAssignedVariantAssets(Array.isArray(rawVarAssets) ? rawVarAssets : []);
|
||||
} catch (err: any) {
|
||||
@@ -635,7 +653,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
</div>
|
||||
|
||||
{/* Variant Target Selector */}
|
||||
{variants.length > 0 && (
|
||||
{configuredVariants.length > 0 && (
|
||||
<div className="flex-1 min-w-[240px]">
|
||||
<label className="text-xs font-bold text-foreground block mb-2 flex items-center justify-between">
|
||||
<span>Variant Target Scope</span>
|
||||
@@ -664,7 +682,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
className="w-full text-xs font-semibold border-primary/20 bg-primary/5/10 text-primary-dark"
|
||||
>
|
||||
<option value="global">Global (Product level)</option>
|
||||
{variants.map((v) => (
|
||||
{configuredVariants.map((v) => (
|
||||
<option key={v.id} value={v.id}>
|
||||
Variant: {v.name.split(' - ')[1] || v.name} ({v.sku || 'No SKU'})
|
||||
</option>
|
||||
@@ -684,7 +702,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setSelectedVariantIds(variants.map(v => v.id))}
|
||||
onClick={() => setSelectedVariantIds(configuredVariants.map(v => v.id))}
|
||||
className="px-2 py-1 bg-surface border border-border hover:bg-background rounded text-[10px] font-bold text-muted-foreground cursor-pointer"
|
||||
>
|
||||
Select All
|
||||
@@ -709,7 +727,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
<span className="text-[10px] font-bold text-foreground min-w-[60px]">{option.name}:</span>
|
||||
<div className="flex gap-1.5 flex-wrap">
|
||||
{option.values.map(val => {
|
||||
const matchingIds = variants
|
||||
const matchingIds = configuredVariants
|
||||
.filter(v => {
|
||||
if (v.attributes && String(v.attributes[option.code]) === val) return true;
|
||||
if (Array.isArray(v.values) && v.values.some((av: any) => av.axis?.code === option.code && String(av.value_text) === val)) return true;
|
||||
@@ -749,7 +767,7 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
|
||||
{/* Variants Checkbox Grid */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-2 pt-2 border-t border-border max-h-[200px] overflow-y-auto">
|
||||
{variants.map(v => {
|
||||
{configuredVariants.map(v => {
|
||||
const isChecked = selectedVariantIds.includes(v.id);
|
||||
return (
|
||||
<label key={v.id} className="flex items-center gap-2 p-1.5 hover:bg-surface-muted rounded-md cursor-pointer transition-colors text-[11px] font-medium text-foreground">
|
||||
@@ -958,8 +976,8 @@ export const ProductAssetsTab: React.FC<ProductAssetsTabProps> = ({
|
||||
>
|
||||
Global ({assignedAssets.length})
|
||||
</button>
|
||||
{variants.map(v => {
|
||||
const count = assignedVariantAssets.filter(va => va.variantId === v.id).length;
|
||||
{configuredVariants.map(v => {
|
||||
const count = assignedVariantAssets.filter(va => (va.variantId || va.variant_id) === v.id).length;
|
||||
if (count === 0) return null;
|
||||
const isSelected = scopeFilter === v.id;
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user