Explorar el Código

fix(dashboard): Fix render issues for asset & facet blocks

Michael Bromley hace 7 meses
padre
commit
e14c457f70

+ 13 - 14
packages/dashboard/src/lib/components/shared/assigned-facet-values.tsx

@@ -23,19 +23,19 @@ interface AssignedFacetValuesProps {
 }
 
 export function AssignedFacetValues({
-    value = [],
-    facetValues,
-    canUpdate = true,
-    onBlur,
-    onChange,
-}: AssignedFacetValuesProps) {
+                                        value = [],
+                                        facetValues,
+                                        canUpdate = true,
+                                        onBlur,
+                                        onChange,
+                                    }: AssignedFacetValuesProps) {
     const [knownFacetValues, setKnownFacetValues] = useState<FacetValue[]>(facetValues);
-    
+
     function onSelectHandler(facetValue: FacetValue) {
         setKnownFacetValues(prev => [...prev, facetValue]);
         onChange?.([...new Set([...(value ?? []), facetValue.id])]);
     }
-    
+
     function onRemoveHandler(id: string) {
         onChange?.(value?.filter(fvId => fvId !== id) ?? []);
     }
@@ -47,12 +47,11 @@ export function AssignedFacetValues({
                     const facetValue = knownFacetValues.find(fv => fv.id === id);
                     if (!facetValue) return null;
                     return (
-                        <div className="mb-2 mr-1">
-                        <FacetValueChip
-                            key={facetValue.id}
-                            facetValue={facetValue}
-                            removable={canUpdate}
-                            onRemove={onRemoveHandler}
+                        <div className="mb-2 mr-1" key={facetValue.id}>
+                            <FacetValueChip
+                                facetValue={facetValue}
+                                removable={canUpdate}
+                                onRemove={onRemoveHandler}
                             />
                         </div>
                     );

+ 140 - 70
packages/dashboard/src/lib/components/shared/entity-assets.tsx

@@ -47,16 +47,55 @@ interface EntityAssetsProps {
     onChange?: (change: EntityAssetValue) => void;
 }
 
+// FeaturedAsset component
+interface FeaturedAssetProps {
+    featuredAsset?: Asset | null;
+    compact?: boolean;
+    onSelectAssets: () => void;
+    onPreviewAsset: (asset: Asset) => void;
+}
+
+function FeaturedAsset({
+                           featuredAsset,
+                           compact = false,
+                           onSelectAssets,
+                           onPreviewAsset,
+                       }: FeaturedAssetProps) {
+    return (
+        <div
+            className={`flex items-center justify-center ${compact ? 'h-40' : 'h-64'} border border-dashed rounded-md`}
+        >
+            {featuredAsset ? (
+                <VendureImage
+                    asset={featuredAsset}
+                    mode="crop"
+                    preset="small"
+                    onClick={() => onPreviewAsset(featuredAsset)}
+                    className="max-w-full max-h-full object-contain cursor-pointer"
+                />
+            ) : (
+                <div
+                    className="flex flex-col items-center justify-center text-muted-foreground cursor-pointer"
+                    onClick={onSelectAssets}
+                >
+                    <ImageIcon className={compact ? 'h-10 w-10' : 'h-16 w-16'} />
+                    {!compact && <div className="mt-2">No featured asset</div>}
+                </div>
+            )}
+        </div>
+    );
+}
+
 // Sortable asset item component
 function SortableAsset({
-    asset,
-    compact,
-    isFeatured,
-    updatePermissions,
-    onPreview,
-    onSetAsFeatured,
-    onRemove,
-}: {
+                           asset,
+                           compact,
+                           isFeatured,
+                           updatePermissions,
+                           onPreview,
+                           onSetAsFeatured,
+                           onRemove,
+                       }: {
     asset: Asset;
     compact: boolean;
     isFeatured: boolean;
@@ -122,13 +161,13 @@ function SortableAsset({
 }
 
 export function EntityAssets({
-    assets: initialAssets = [],
-    featuredAsset: initialFeaturedAsset,
-    compact = false,
-    updatePermissions = true,
-    multiSelect = true,
-    onChange,
-}: EntityAssetsProps) {
+                                 assets: initialAssets = [],
+                                 featuredAsset: initialFeaturedAsset,
+                                 compact = false,
+                                 updatePermissions = true,
+                                 multiSelect = true,
+                                 onChange,
+                             }: EntityAssetsProps) {
     const [assets, setAssets] = useState<Asset[]>([...initialAssets]);
     const [featuredAsset, setFeaturedAsset] = useState<Asset | undefined | null>(initialFeaturedAsset);
     const [isPickerOpen, setIsPickerOpen] = useState(false);
@@ -234,57 +273,6 @@ export function EntityAssets({
         },
         [featuredAsset],
     );
-
-    const renderAssetList = () => (
-        <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
-            <div className={`${compact ? 'max-h-32' : ''} overflow-auto p-1`}>
-                <SortableContext
-                    items={assets.map(asset => asset.id)}
-                    strategy={horizontalListSortingStrategy}
-                >
-                    <div className="flex flex-wrap gap-2">
-                        {assets.map(asset => (
-                            <SortableAsset
-                                key={asset.id}
-                                asset={asset}
-                                compact={compact}
-                                isFeatured={isFeatured(asset)}
-                                updatePermissions={updatePermissions}
-                                onPreview={setPreviewAsset}
-                                onSetAsFeatured={handleSetAsFeatured}
-                                onRemove={handleRemoveAsset}
-                            />
-                        ))}
-                    </div>
-                </SortableContext>
-            </div>
-        </DndContext>
-    );
-
-    const FeaturedAsset = () => (
-        <div
-            className={`flex items-center justify-center ${compact ? 'h-40' : 'h-64'} border border-dashed rounded-md`}
-        >
-            {featuredAsset ? (
-                <VendureImage
-                    asset={featuredAsset}
-                    mode="crop"
-                    preset="small"
-                    onClick={() => setPreviewAsset(featuredAsset)}
-                    className="max-w-full max-h-full object-contain cursor-pointer"
-                />
-            ) : (
-                <div
-                    className="flex flex-col items-center justify-center text-muted-foreground cursor-pointer"
-                    onClick={handleSelectAssets}
-                >
-                    <ImageIcon className={compact ? 'h-10 w-10' : 'h-16 w-16'} />
-                    {!compact && <div className="mt-2">No featured asset</div>}
-                </div>
-            )}
-        </div>
-    );
-
     // AddAssetButton component
     const AddAssetButton = () =>
         updatePermissions && (
@@ -303,15 +291,45 @@ export function EntityAssets({
         <>
             {compact ? (
                 <div className="flex flex-col gap-3">
-                    <FeaturedAsset />
-                    {renderAssetList()}
+                    <FeaturedAsset
+                        featuredAsset={featuredAsset}
+                        compact={compact}
+                        onSelectAssets={handleSelectAssets}
+                        onPreviewAsset={setPreviewAsset}
+                    />
+                    <AssetList
+                        assets={assets}
+                        compact={compact}
+                        sensors={sensors}
+                        updatePermissions={updatePermissions}
+                        isFeatured={isFeatured}
+                        onPreview={setPreviewAsset}
+                        onSetAsFeatured={handleSetAsFeatured}
+                        onRemove={handleRemoveAsset}
+                        onDragEnd={handleDragEnd}
+                    />
                     <AddAssetButton />
                 </div>
             ) : (
                 <div className="grid grid-cols-1 md:grid-cols-[256px_1fr] gap-4">
-                    <FeaturedAsset />
+                    <FeaturedAsset
+                        featuredAsset={featuredAsset}
+                        compact={compact}
+                        onSelectAssets={handleSelectAssets}
+                        onPreviewAsset={setPreviewAsset}
+                    />
                     <div className="flex flex-col gap-4">
-                        {renderAssetList()}
+                        <AssetList
+                            assets={assets}
+                            compact={compact}
+                            sensors={sensors}
+                            updatePermissions={updatePermissions}
+                            isFeatured={isFeatured}
+                            onPreview={setPreviewAsset}
+                            onSetAsFeatured={handleSetAsFeatured}
+                            onRemove={handleRemoveAsset}
+                            onDragEnd={handleDragEnd}
+                        />
                         <AddAssetButton />
                     </div>
                 </div>
@@ -338,3 +356,55 @@ export function EntityAssets({
         </>
     );
 }
+
+// AssetList component
+interface AssetListProps {
+    assets: Asset[];
+    compact: boolean;
+    sensors: ReturnType<typeof useSensors>;
+    updatePermissions: boolean;
+    isFeatured: (asset: Asset) => boolean;
+    onPreview: (asset: Asset) => void;
+    onSetAsFeatured: (asset: Asset) => void;
+    onRemove: (asset: Asset) => void;
+    onDragEnd: (event: DragEndEvent) => void;
+}
+
+
+function AssetList({
+                       assets,
+                       compact,
+                       sensors,
+                       updatePermissions,
+                       isFeatured,
+                       onPreview,
+                       onSetAsFeatured,
+                       onRemove,
+                       onDragEnd,
+                   }: AssetListProps) {
+    return (
+        <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={onDragEnd}>
+            <div className={`${compact ? 'max-h-32' : ''} overflow-auto p-1`}>
+                <SortableContext
+                    items={assets.map(asset => asset.id)}
+                    strategy={horizontalListSortingStrategy}
+                >
+                    <div className="flex flex-wrap gap-2">
+                        {assets.map(asset => (
+                            <SortableAsset
+                                key={asset.id}
+                                asset={asset}
+                                compact={compact}
+                                isFeatured={isFeatured(asset)}
+                                updatePermissions={updatePermissions}
+                                onPreview={onPreview}
+                                onSetAsFeatured={onSetAsFeatured}
+                                onRemove={onRemove}
+                            />
+                        ))}
+                    </div>
+                </SortableContext>
+            </div>
+        </DndContext>
+    );
+}