Renamed prefixes in angular.json
All checks were successful
FarmMaps.Develop/FarmMapsLib/develop This commit looks good
All checks were successful
FarmMaps.Develop/FarmMapsLib/develop This commit looks good
This commit is contained in:
@@ -0,0 +1,23 @@
|
||||
<div class="resumable-file-upload closed" [ngClass]="{'closed': uploadService.isClosed }">
|
||||
<div>
|
||||
<div class="card">
|
||||
<div class="card-header p-3 bg-primary text-white">
|
||||
<span *ngIf="uploadService.isUploading">Uploading files (<span>{{uploadService.totalProgress}}</span> %)</span>
|
||||
<span *ngIf="uploadService.isUploading == false">Uploaded <span>{{uploadService.files.length}}</span> files</span>
|
||||
<span title="Cancel" class="fa fa-times pull-right" (click)="uploadService.close()"></span><span title="Minimize" class="fa fa-chevron-down pull-right" (click)="uploadService.toggleMinimize()" [ngClass]="{'fa-chevron-down': uploadService.isMinimized == false, 'fa-chevron-up':uploadService.isMinimized}"></span>
|
||||
</div>
|
||||
<div [ngClass]="{'minimized': uploadService.isMinimized }">
|
||||
<div class="card-block p-3">
|
||||
<ul class="list-unstyled">
|
||||
<li *ngFor="let file of uploadService.files" class="upload-file busy" [ngClass]="{'done': file.success,'busy':file.success == false,'error': file.error }">
|
||||
<div *ngIf="file.success == false"><span class="file-name" [attr.title]="file?.fileName">{{file.fileName}}</span><span class="fa fa-times" title="Cancel" (click)="uploadService.cancelFile(file)"></span><span class="fa fa-check"></span></div>
|
||||
<div *ngIf="file.success"><a href="#" (click)="handleUploadedFileClick($event,file)" class="file-name" [attr.title]="file?.fileName">{{file.fileName}}</a><span class="fa fa-check"></span></div>
|
||||
<div class="progress-container"><div class="progress-bar" [style.width]="file.progress+'%'"></div></div>
|
||||
<div class="errormessage">{{file.errorMessage}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
@@ -0,0 +1,113 @@
|
||||
@import "../../theme.scss";
|
||||
|
||||
/* Import Bootstrap & Fonts */
|
||||
|
||||
@import "~bootstrap/scss/bootstrap.scss";
|
||||
|
||||
div.resumable-file-upload {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
width: 300px;
|
||||
max-height: 250px;
|
||||
/*z-index:2000 !important;*/
|
||||
}
|
||||
|
||||
div.minimized {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
div.closed {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
div.card {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
div.card-block {
|
||||
max-height: calc(250px - 41px);
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
div.minimized div.card-block {
|
||||
height: 0px;
|
||||
}
|
||||
|
||||
div.card-header span.fa {
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.upload-file {
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.upload-file .progress-container {
|
||||
height: 3px;
|
||||
width: 100%;
|
||||
margin-top:4px;
|
||||
}
|
||||
|
||||
.upload-file .progress-container .progress-bar {
|
||||
display: block;
|
||||
background-color: color("green");
|
||||
width: 0%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.upload-file.done .progress-container .progress-bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-file > div > span.file-name {
|
||||
display: inline-block;
|
||||
width: calc(100% - 20px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.upload-file > div > a.file-name {
|
||||
display: inline-block;
|
||||
width: calc(100% - 20px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.upload-file.busy > div > span.fa-times {
|
||||
color: theme-color("danger");
|
||||
width: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.upload-file.done > div > span.fa-times {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-file.done > div > span.fa-check {
|
||||
color: color("green");
|
||||
width: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.upload-file > div.errormessage {
|
||||
color: theme-color("danger");
|
||||
display: none;
|
||||
}
|
||||
|
||||
.upload-file.error > div.errormessage {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.upload-file.busy > div > span.fa-check {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.resumable-file-upload ul {
|
||||
padding:0px;
|
||||
}
|
@@ -0,0 +1,53 @@
|
||||
import { Component, Input,Output, HostListener, ChangeDetectorRef, OnDestroy, OnInit,EventEmitter } from '@angular/core';
|
||||
import { ResumableFileUploadService, File } from './resumable-file-upload.service';
|
||||
import { Subscription } from 'rxjs';
|
||||
import { Store } from '@ngrx/store';
|
||||
import * as commonReducer from '../../reducers/app-common.reducer';
|
||||
import * as commonActions from '../../actions/app-common.actions';
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'fm-resumable-file-upload',
|
||||
templateUrl: './resumable-file-upload.component.html',
|
||||
styleUrls: ['./resumable-file-upload.component.scss']
|
||||
})
|
||||
|
||||
export class ResumableFileUploadComponent implements OnInit, OnDestroy {
|
||||
|
||||
@Input('parentCode')
|
||||
set parentCode(parentCode: string) {
|
||||
if (parentCode && parentCode != "null" && parentCode != "")
|
||||
this.uploadService.parentCode = parentCode;
|
||||
else
|
||||
this.uploadService.parentCode = null;
|
||||
}
|
||||
|
||||
constructor(private cd: ChangeDetectorRef, public uploadService: ResumableFileUploadService,public store: Store<commonReducer.State>) {
|
||||
}
|
||||
|
||||
private refreshSub: Subscription;
|
||||
|
||||
ngOnInit() {
|
||||
this.uploadService.init();
|
||||
this.refreshSub = this.uploadService.refresh.subscribe((e: any) => {
|
||||
this.cd.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if(this.refreshSub) this.refreshSub.unsubscribe();
|
||||
}
|
||||
|
||||
handleUploadedFileClick(event:MouseEvent,file:File) {
|
||||
event.preventDefault();
|
||||
this.store.dispatch(new commonActions.UploadedFileClick(file.itemCode));
|
||||
}
|
||||
|
||||
//TODO do this with an canunload guard
|
||||
@HostListener('window:beforeunload')
|
||||
windowBeforeUnload = function () {
|
||||
if (this.uploadService.isUploading) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,149 @@
|
||||
import { Injectable, OnDestroy } from '@angular/core';
|
||||
import { OAuthService } from 'angular-oauth2-oidc';
|
||||
import { Subject , Subscription } from 'rxjs';
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { UploadxService, UploadState,UploadxOptions} from 'ngx-uploadx';
|
||||
import { AppConfig } from '../../shared/app.config';
|
||||
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class ResumableFileUploadService implements OnDestroy{
|
||||
public files: Array<File> = new Array<File>();
|
||||
public isUploading = false;
|
||||
public totalProgress = 0;
|
||||
public isClosed = true;
|
||||
public isMinimized = false;
|
||||
public parentCode: string;
|
||||
public refresh: Subject<any> = new Subject<any>();
|
||||
private _eventSub:Subscription;
|
||||
private initialized = false;
|
||||
|
||||
constructor(private httpClient: HttpClient,private oauthService: OAuthService,private uploadService: UploadxService,public appConfig: AppConfig) {
|
||||
|
||||
}
|
||||
|
||||
endPoint() {
|
||||
return `${this.appConfig.getConfig("apiEndPoint")}/api/v1/file`;
|
||||
}
|
||||
|
||||
init() {
|
||||
if(!this.initialized) {
|
||||
this._eventSub=this.uploadService.init({
|
||||
endpoint:this.endPoint(),
|
||||
token:() => this.oauthService.getAccessToken(),
|
||||
chunkSize: 2097152}).subscribe((uploadState:UploadState) => {
|
||||
this.handleState(uploadState);
|
||||
} );
|
||||
this.initialized=true;
|
||||
}
|
||||
}
|
||||
|
||||
updatetotalprogress() {
|
||||
var totalProgress =0;
|
||||
var n=0;
|
||||
for(var i =0;i<this.files.length;i++) {
|
||||
if(!this.files[i].error) {
|
||||
totalProgress+=this.files[i].progress;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
this.totalProgress=totalProgress/this.files.length;
|
||||
if(this.totalProgress==100) this.isUploading=false;
|
||||
}
|
||||
|
||||
handleState(state:UploadState) {
|
||||
switch(state.status) {
|
||||
case "queue": {
|
||||
this.files.push(new File(state));
|
||||
this.isClosed=false;
|
||||
};break;
|
||||
case "uploading": {
|
||||
this.isUploading = true;
|
||||
var file =this.files.find((f) => f.identifier == state.uploadId )
|
||||
if(file) {
|
||||
file.progress = (state.progress?state.progress:0);
|
||||
}
|
||||
};break;
|
||||
case "complete": {
|
||||
var file =this.files.find((f) => f.identifier == state.uploadId )
|
||||
if(file) {
|
||||
var parts = state.url.split("/");
|
||||
file.itemCode = parts[parts.length-1];
|
||||
file.progress = (state.progress?state.progress:0);
|
||||
file.success=true;
|
||||
}
|
||||
};break;
|
||||
case "error": {
|
||||
var file =this.files.find((f) => f.identifier == state.uploadId )
|
||||
if(file) {
|
||||
file.error=true;
|
||||
file.errorMessage = state.response;
|
||||
}
|
||||
};break;
|
||||
}
|
||||
this.updatetotalprogress();
|
||||
this.refresh.next({});
|
||||
}
|
||||
|
||||
addFiles = (files: any[], event: any, metadata:any) => {
|
||||
for (let f of files) {
|
||||
var options:UploadxOptions = {metadata:metadata};
|
||||
this.uploadService.handleFile(f,options);
|
||||
}
|
||||
}
|
||||
|
||||
toggleMinimize = function () {
|
||||
this.isMinimized = !this.isMinimized;
|
||||
};
|
||||
|
||||
cancelFile = function (file) {
|
||||
this.uploadService.control({action:'cancel',uploadId:file.identifier});
|
||||
var index = this.files.indexOf(file, 0);
|
||||
if (index > -1) {
|
||||
this.files.splice(index, 1);
|
||||
}
|
||||
};
|
||||
|
||||
doClose = function () {
|
||||
this.uploadService.control({action:'cancelAll'});
|
||||
this.files = new Array<File>();
|
||||
this.isClosed = true;
|
||||
}
|
||||
|
||||
close = function () {
|
||||
let close = true;
|
||||
if (this.isUploading) {
|
||||
close = false;
|
||||
}
|
||||
if (close) {
|
||||
this.doClose();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if(this._eventSub) this._eventSub.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
export class File {
|
||||
private file: any;
|
||||
public fileName: string;
|
||||
public progress: number;
|
||||
public identifier: string;
|
||||
public itemCode: string;
|
||||
public success: boolean;
|
||||
public error: boolean;
|
||||
public errorMessage: string;
|
||||
|
||||
|
||||
constructor(state: UploadState) {
|
||||
this.file = state;
|
||||
this.fileName = state.file.name;
|
||||
this.progress = state.progress?state.progress:0;
|
||||
this.identifier = state.uploadId;
|
||||
this.success = false;
|
||||
this.error = false;
|
||||
this.errorMessage = "";
|
||||
this.itemCode = null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user