Просмотр исходного кода

feat(admin-ui): Add image carousel to asset preview dialog (#2370)

Closes #2129

(cherry picked from commit bd834d030189c7bcc6d42c8be4439ea4b37c2979)
Mizan3050 2 лет назад
Родитель
Сommit
cd7b2bf751

+ 1 - 1
packages/admin-ui/src/lib/catalog/src/components/assets/assets.component.ts

@@ -86,7 +86,7 @@ export class AssetsComponent {
             .fromComponent(AssetPreviewDialogComponent, {
                 size: 'xl',
                 closable: true,
-                locals: { asset },
+                locals: { asset, assets: this.assets },
             })
             .subscribe();
     }

+ 1 - 2
packages/admin-ui/src/lib/catalog/src/components/product-variant-list/product-variant-list-bulk-actions.ts

@@ -10,12 +10,11 @@ import {
     Permission,
     createBulkRemoveFromChannelAction,
     isMultiChannel,
+    ProductVariant,
 } from '@vendure/admin-ui/core';
 import { unique } from '@vendure/common/lib/unique';
 import { EMPTY } from 'rxjs';
 import { map, switchMap } from 'rxjs/operators';
-
-import { ProductVariant } from 'package/core';
 import { AssignProductsToChannelDialogComponent } from '../assign-products-to-channel-dialog/assign-products-to-channel-dialog.component';
 import { ProductVariantListComponent } from './product-variant-list.component';
 

+ 1 - 1
packages/admin-ui/src/lib/core/src/shared/components/asset-gallery/asset-gallery.component.ts

@@ -71,7 +71,7 @@ export class AssetGalleryComponent implements OnChanges {
             .fromComponent(AssetPreviewDialogComponent, {
                 size: 'xl',
                 closable: true,
-                locals: { asset },
+                locals: { asset, assets: this.assets },
             })
             .subscribe();
     }

+ 1 - 0
packages/admin-ui/src/lib/core/src/shared/components/asset-preview-dialog/asset-preview-dialog.component.html

@@ -9,4 +9,5 @@
     [asset]="assetWithTags"
     (assetChange)="assetChanges = $event"
     (editClick)="resolveWith()"
+    [assets]="assetsWithTags$ | async"
 ></vdr-asset-preview>

+ 6 - 2
packages/admin-ui/src/lib/core/src/shared/components/asset-preview-dialog/asset-preview-dialog.component.ts

@@ -1,7 +1,7 @@
 import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
 import { gql } from 'apollo-angular';
 import { Observable, of } from 'rxjs';
-import { mergeMap } from 'rxjs/operators';
+import { map, mergeMap, tap } from 'rxjs/operators';
 
 import { GetAssetQuery, UpdateAssetInput } from '../../../common/generated-types';
 import { ASSET_FRAGMENT, TAG_FRAGMENT } from '../../../data/definitions/product-definitions';
@@ -29,11 +29,13 @@ export const ASSET_PREVIEW_QUERY = gql`
     changeDetection: ChangeDetectionStrategy.OnPush,
 })
 export class AssetPreviewDialogComponent implements Dialog<void>, OnInit {
-    constructor(private dataService: DataService) {}
+    constructor(private dataService: DataService) { }
     asset: AssetLike;
+    assets?: AssetLike[];
     assetChanges?: UpdateAssetInput;
     resolveWith: (result?: void) => void;
     assetWithTags$: Observable<GetAssetQuery['asset']>;
+    assetsWithTags$: Observable<Array<GetAssetQuery['asset']>>;
 
     ngOnInit() {
         this.assetWithTags$ = of(this.asset).pipe(
@@ -46,6 +48,8 @@ export class AssetPreviewDialogComponent implements Dialog<void>, OnInit {
                 }
             }),
         );
+
+        this.assetsWithTags$ = of(this.assets ?? []);
     }
 
     private hasTags(asset: AssetLike): asset is AssetLike & { tags: string[] } {

+ 6 - 0
packages/admin-ui/src/lib/core/src/shared/components/asset-preview/asset-preview.component.html

@@ -106,6 +106,9 @@
             <vdr-page-entity-info *ngIf="asset as entity" [entity]="entity"></vdr-page-entity-info>
         </vdr-card>
     </vdr-page-detail-sidebar>
+    <div class="carousel-container">
+    <button *ngIf="showSlideButtons" (click)="previousImage()" [class.disabled]="disablePreviousButton"><clr-icon shape="caret left" class="color-weight-800"></clr-icon
+        ></button>
     <div class="preview-image" #previewDiv [class.centered]="centered">
         <div class="image-wrapper">
             <vdr-focal-point-control
@@ -139,4 +142,7 @@
             </div>
         </div>
     </div>
+    <button  *ngIf="showSlideButtons" (click)="nextImage()" [class.disabled]="disableNextButton"><clr-icon shape="caret right" class="color-weight-800"></clr-icon
+        ></button>
+    </div>
 </vdr-page-detail-layout>

+ 26 - 1
packages/admin-ui/src/lib/core/src/shared/components/asset-preview/asset-preview.component.scss

@@ -5,7 +5,7 @@
 
 .preview-image {
     width: 100%;
-    max-width: 800px;
+    max-width: 750px;
     height: 100%;
     min-height: 60vh;
     overflow: auto;
@@ -89,3 +89,28 @@
         }
     }
 }
+
+.carousel-container{
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+
+    button{
+        cursor: pointer;
+        width: 30px;
+        height: 30px;
+        border: none;
+        border-radius: 50%;
+        text-align: center;
+        background-color: var(--color-grey-300);
+        &:hover {
+            background-color: var(--color-grey-400);;
+        }
+    }
+
+    .disabled {
+        pointer-events: none;
+        opacity: 0.4;
+    }
+}

+ 36 - 1
packages/admin-ui/src/lib/core/src/shared/components/asset-preview/asset-preview.component.ts

@@ -33,6 +33,7 @@ export type PreviewPreset = 'tiny' | 'thumb' | 'small' | 'medium' | 'large' | ''
 })
 export class AssetPreviewComponent implements OnInit, OnDestroy {
     @Input() asset: AssetLike;
+    @Input() assets?: AssetLike[];
     @Input() editable = false;
     @Input() customFields: CustomFieldConfig[] = [];
     @Input() customFieldsForm: UntypedFormGroup | undefined;
@@ -50,6 +51,10 @@ export class AssetPreviewComponent implements OnInit, OnDestroy {
     centered = true;
     settingFocalPoint = false;
     lastFocalPoint?: Point;
+    previewAssetIndex = 0;
+    disableNextButton = false;
+    disablePreviousButton = false;
+    showSlideButtons = false;
     @ViewChild('imageElement', { static: true }) private imageElementRef: ElementRef<HTMLImageElement>;
     @ViewChild('previewDiv', { static: true }) private previewDivRef: ElementRef<HTMLDivElement>;
     private subscription: Subscription;
@@ -61,7 +66,7 @@ export class AssetPreviewComponent implements OnInit, OnDestroy {
         private notificationService: NotificationService,
         private changeDetector: ChangeDetectorRef,
         private modalService: ModalService,
-    ) {}
+    ) { }
 
     get fpx(): number | null {
         return this.asset.focalPoint ? this.asset.focalPoint.x : null;
@@ -73,6 +78,14 @@ export class AssetPreviewComponent implements OnInit, OnDestroy {
 
     ngOnInit() {
         const { focalPoint } = this.asset;
+        if (this.assets?.length) {
+            this.showSlideButtons = true;
+            this.previewAssetIndex = this.assets.findIndex(asset => asset.id === this.asset.id) || 0;
+        } else {
+            this.showSlideButtons = false;
+            this.updateButtonAccessibility();
+        }
+        this.updateButtonAccessibility();
         this.form.get('name')?.setValue(this.asset.name);
         this.form.get('tags')?.setValue(this.asset.tags?.map(t => t.value));
         this.subscription = this.form.valueChanges.subscribe(value => {
@@ -206,4 +219,26 @@ export class AssetPreviewComponent implements OnInit, OnDestroy {
                 }
             });
     }
+
+    nextImage() {
+        this.previewAssetIndex = this.previewAssetIndex + 1;
+        if (Array.isArray(this.assets)) {
+            this.asset = this.assets[this.previewAssetIndex];
+            this.updateButtonAccessibility();
+        }
+    }
+
+    previousImage() {
+        this.previewAssetIndex = this.previewAssetIndex - 1;
+        if (Array.isArray(this.assets)) {
+            this.asset = this.assets[this.previewAssetIndex];
+            this.updateButtonAccessibility();
+        }
+    }
+
+    updateButtonAccessibility() {
+        this.disableNextButton = this.assets?.[this.previewAssetIndex + 1]?.id ? false : true;
+        this.disablePreviousButton = this.assets?.[this.previewAssetIndex - 1]?.id ? false : true;
+    }
+
 }

+ 1 - 2
packages/admin-ui/src/lib/settings/src/components/tax-category-list/tax-category-list-bulk-actions.ts

@@ -1,5 +1,4 @@
-import { createBulkDeleteAction, GetSellersQuery, ItemOf, Permission } from '@vendure/admin-ui/core';
-import { GetTaxCategoryListQuery } from '@vendure/core/e2e/graphql/generated-e2e-admin-types';
+import { createBulkDeleteAction, GetTaxCategoryListQuery, ItemOf, Permission } from '@vendure/admin-ui/core';
 import { map } from 'rxjs/operators';
 
 export const deleteTaxCategoriesBulkAction = createBulkDeleteAction<