Skip to content

Commit

Permalink
feat(admin-ui): Display visual feedback when uploading Assets
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbromley committed May 18, 2020
1 parent e9bf90c commit ca6c30f
Show file tree
Hide file tree
Showing 7 changed files with 50 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<vdr-action-bar-items locationId="asset-list"></vdr-action-bar-items>
<vdr-asset-file-input
(selectFiles)="filesSelected($event)"
[uploading]="uploading"
dropZoneTarget=".content-area"
></vdr-asset-file-input>
</vdr-ab-right>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { SortOrder } from '@vendure/common/lib/generated-shop-types';
import { PaginationInstance } from 'ngx-pagination';
import { combineLatest, EMPTY, Observable } from 'rxjs';
import { debounceTime, map, switchMap, takeUntil } from 'rxjs/operators';
import { debounceTime, finalize, map, switchMap, takeUntil } from 'rxjs/operators';

@Component({
selector: 'vdr-asset-list',
Expand All @@ -24,6 +24,7 @@ import { debounceTime, map, switchMap, takeUntil } from 'rxjs/operators';
export class AssetListComponent extends BaseListComponent<GetAssetList.Query, GetAssetList.Items>
implements OnInit {
searchTerm = new FormControl('');
uploading = false;
paginationConfig$: Observable<PaginationInstance>;

constructor(
Expand All @@ -36,7 +37,7 @@ export class AssetListComponent extends BaseListComponent<GetAssetList.Query, Ge
super(router, route);
super.setQueryFn(
(...args: any[]) => this.dataService.product.getAssetList(...args),
data => data.assets,
(data) => data.assets,
(skip, take) => ({
options: {
skip,
Expand Down Expand Up @@ -66,24 +67,28 @@ export class AssetListComponent extends BaseListComponent<GetAssetList.Query, Ge

filesSelected(files: File[]) {
if (files.length) {
this.dataService.product.createAssets(files).subscribe(res => {
super.refresh();
this.notificationService.success(_('asset.notify-create-assets-success'), {
count: files.length,
this.uploading = true;
this.dataService.product
.createAssets(files)
.pipe(finalize(() => (this.uploading = false)))
.subscribe((res) => {
super.refresh();
this.notificationService.success(_('asset.notify-create-assets-success'), {
count: files.length,
});
});
});
}
}

deleteAsset(asset: Asset) {
this.showModalAndDelete(asset.id)
.pipe(
switchMap(response => {
switchMap((response) => {
if (response.result === DeletionResult.DELETED) {
return [true];
} else {
return this.showModalAndDelete(asset.id, response.message || '').pipe(
map(r => r.result === DeletionResult.DELETED),
map((r) => r.result === DeletionResult.DELETED),
);
}
}),
Expand All @@ -95,7 +100,7 @@ export class AssetListComponent extends BaseListComponent<GetAssetList.Query, Ge
});
this.refresh();
},
err => {
(err) => {
this.notificationService.error(_('common.notify-delete-error'), {
entity: 'Asset',
});
Expand All @@ -114,8 +119,8 @@ export class AssetListComponent extends BaseListComponent<GetAssetList.Query, Ge
],
})
.pipe(
switchMap(res => (res ? this.dataService.product.deleteAsset(assetId, !!message) : EMPTY)),
map(res => res.deleteAsset),
switchMap((res) => (res ? this.dataService.product.deleteAsset(assetId, !!message) : EMPTY)),
map((res) => res.deleteAsset),
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
<input type="file" class="file-input" #fileInput (change)="select($event)" multiple />
<button class="btn btn-primary" (click)="fileInput.click()">
<button class="btn btn-primary" (click)="fileInput.click()" [disabled]="uploading">
<ng-container *ngIf="uploading; else selectable" >
<clr-spinner clrInline></clr-spinner>
{{ 'asset.uploading' | translate }}
</ng-container>
<ng-template #selectable>
<clr-icon shape="upload-cloud"></clr-icon>
{{ 'asset.upload-assets' | translate }}
</ng-template>
</button>
<div
class="drop-zone"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class AssetFileInputComponent implements OnInit {
* drop zone. Defaults to `body`.
*/
@Input() dropZoneTarget = 'body';
@Input() uploading = false;
@Output() selectFiles = new EventEmitter<File[]>();
dragging = false;
overDropZone = false;
Expand Down Expand Up @@ -64,7 +65,7 @@ export class AssetFileInputComponent implements OnInit {
this.dragging = false;
this.overDropZone = false;
const files = Array.from(event.dataTransfer ? event.dataTransfer.items : [])
.map(i => i.getAsFile())
.map((i) => i.getAsFile())
.filter(notNullOrUndefined);
this.selectFiles.emit(files);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
{{ 'asset.select-assets' | translate }}
<vdr-asset-file-input
(selectFiles)="createAssets($event)"
[uploading]="uploading"
dropZoneTarget=".modal-content"
></vdr-asset-file-input>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FormControl } from '@angular/forms';
import { marker as _ } from '@biesbjerg/ngx-translate-extract-marker';
import { PaginationInstance } from 'ngx-pagination';
import { Observable, Subject } from 'rxjs';
import { debounceTime, map, takeUntil, tap } from 'rxjs/operators';
import { debounceTime, finalize, map, takeUntil, tap } from 'rxjs/operators';

import { Asset, GetAssetList, SortOrder } from '../../../common/generated-types';
import { DataService } from '../../../data/providers/data.service';
Expand Down Expand Up @@ -31,6 +31,7 @@ export class AssetPickerDialogComponent implements OnInit, OnDestroy, Dialog<Ass
resolveWith: (result?: Asset[]) => void;
selection: Asset[] = [];
searchTerm = new FormControl('');
uploading = false;
private listQuery: QueryResult<GetAssetList.Query, GetAssetList.Variables>;
private destroy$ = new Subject<void>();

Expand All @@ -39,15 +40,12 @@ export class AssetPickerDialogComponent implements OnInit, OnDestroy, Dialog<Ass
ngOnInit() {
this.listQuery = this.dataService.product.getAssetList(this.paginationConfig.itemsPerPage, 0);
this.assets$ = this.listQuery.stream$.pipe(
tap(result => (this.paginationConfig.totalItems = result.assets.totalItems)),
map(result => result.assets.items),
tap((result) => (this.paginationConfig.totalItems = result.assets.totalItems)),
map((result) => result.assets.items),
);
this.searchTerm.valueChanges
.pipe(
debounceTime(250),
takeUntil(this.destroy$),
)
.subscribe(searchTerm => {
.pipe(debounceTime(250), takeUntil(this.destroy$))
.subscribe((searchTerm) => {
this.fetchPage(
this.paginationConfig.currentPage,
this.paginationConfig.itemsPerPage,
Expand Down Expand Up @@ -89,16 +87,20 @@ export class AssetPickerDialogComponent implements OnInit, OnDestroy, Dialog<Ass

createAssets(files: File[]) {
if (files.length) {
this.dataService.product.createAssets(files).subscribe(res => {
this.fetchPage(
this.paginationConfig.currentPage,
this.paginationConfig.itemsPerPage,
this.searchTerm.value,
);
this.notificationService.success(_('asset.notify-create-assets-success'), {
count: files.length,
this.uploading = true;
this.dataService.product
.createAssets(files)
.pipe(finalize(() => (this.uploading = false)))
.subscribe((res) => {
this.fetchPage(
this.paginationConfig.currentPage,
this.paginationConfig.itemsPerPage,
this.searchTerm.value,
);
this.notificationService.success(_('asset.notify-create-assets-success'), {
count: files.length,
});
});
});
}
}

Expand Down
6 changes: 3 additions & 3 deletions packages/admin-ui/src/lib/static/i18n-messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
"update-focal-point": "Update point",
"update-focal-point-error": "Could not update focal point",
"update-focal-point-success": "Updated focal point",
"upload-assets": "Upload assets"
"upload-assets": "Upload assets",
"uploading": "Uploading..."
},
"breadcrumb": {
"administrators": "Administrators",
Expand Down Expand Up @@ -665,7 +666,6 @@
"job-error": "Job error",
"job-queue-name": "Queue name",
"job-result": "Job result",
"job-state": "Job state",
"jobs-in-progress": "{ count } {count, plural, one {job} other {jobs}} in progress"
"job-state": "Job state"
}
}

0 comments on commit ca6c30f

Please sign in to comment.