diff --git a/src/app/app.config.ts b/src/app/app.config.ts index 810c36e..95b1b41 100644 --- a/src/app/app.config.ts +++ b/src/app/app.config.ts @@ -55,4 +55,21 @@ export class AppConfig { return AppConfig.config.Socket; } + public getUrl(key: string): string{ + const s = this.apiUrl + key; + const kvPair: {key: string, value: string}[] = [ + {key: 'login', value: this.apiUrl + 'login'}, + {key: 'logout', value: this.apiUrl + 'logout'} + ]; + + kvPair.forEach( item => { + if ( item.key === key) { + return item.value; + } + }); + + // not found if arrive here + return s; + } + } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 033499e..6eb9c85 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -96,6 +96,7 @@ import { ImagePopupDialogComponent } from './image-popup-dialog/image-popup-dial import { PopupIncomeFilterComponent } from './popup-income-filter/popup-income-filter.component'; import { LoanCardComponent } from './loan-card/loan-card.component'; import {AppConfig} from './app.config'; +import { UploadingProgressCardComponent } from './uploading-progress-card/uploading-progress-card.component'; @@ -162,7 +163,8 @@ export function initializeApp(appConfig: AppConfig): () => Promise { SafeUrlPipe, ImagePopupDialogComponent, PopupIncomeFilterComponent, - LoanCardComponent + LoanCardComponent, + UploadingProgressCardComponent ], imports: [ BrowserModule, diff --git a/src/app/chart-past-year-monthly-performance/chart-past-year-monthly-performance.component.ts b/src/app/chart-past-year-monthly-performance/chart-past-year-monthly-performance.component.ts index ab8f333..37c6895 100644 --- a/src/app/chart-past-year-monthly-performance/chart-past-year-monthly-performance.component.ts +++ b/src/app/chart-past-year-monthly-performance/chart-past-year-monthly-performance.component.ts @@ -23,9 +23,9 @@ export class ChartPastYearMonthlyPerformanceComponent implements OnInit { private getPastYearMonthly(): Observable { return this.http.get(this.auth.getUrl('chart/past-year-monthly')).pipe(map( data => { - let ret = []; + const ret = []; data.forEach( (value: PastYearMonthlyData , index: number ) => { - let a = { + const a = { Period: value.Period, Amount: value.Amount / 1000, Summary: '', diff --git a/src/app/chart-top-brokers/chart-top-brokers.component.html b/src/app/chart-top-brokers/chart-top-brokers.component.html index 2e8b029..1557912 100644 --- a/src/app/chart-top-brokers/chart-top-brokers.component.html +++ b/src/app/chart-top-brokers/chart-top-brokers.component.html @@ -9,8 +9,8 @@ - - + + diff --git a/src/app/chart-type-of-loans/chart-type-of-loans.component.ts b/src/app/chart-type-of-loans/chart-type-of-loans.component.ts index 4b95b40..2fa761d 100644 --- a/src/app/chart-type-of-loans/chart-type-of-loans.component.ts +++ b/src/app/chart-type-of-loans/chart-type-of-loans.component.ts @@ -28,10 +28,10 @@ export class ChartTypeOfLoansComponent implements OnInit { return this.http.get(this.auth.getUrl('chart/type-of-loans')).pipe( map( input => { - let ret = []; + const ret = []; input.forEach( (value, index) =>{ ret.push({ - Kind: value.Kind + ' ' + (value.Share * 100) + '%', + Kind: value.Kind + ' ' + (value.Share * 100).toFixed(2) + '%', Count: value.Count, Share: value.Share, Amount: value.Amount diff --git a/src/app/client-profile/client-profile.component.ts b/src/app/client-profile/client-profile.component.ts index ab88a26..003a07d 100644 --- a/src/app/client-profile/client-profile.component.ts +++ b/src/app/client-profile/client-profile.component.ts @@ -5,6 +5,7 @@ import {AuthService} from '../service/auth.service'; import {PeopleService} from '../service/people.service'; import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload'; import {BrokerModel} from '../models/broker.model'; +import {AppConfig} from '../app.config'; @Component({ selector: 'app-client-profile', @@ -14,7 +15,7 @@ import {BrokerModel} from '../models/broker.model'; export class ClientProfileComponent implements OnInit { @Input() User: PeopleModel = PeopleModel.EmptyNew(); @ViewChild('fileSelect', {static: true}) fs: FileSelectComponent; - public avatarUrl = 'url(https://svr2021.lawipac.com:8080/api/v1/avatar/1000)' ; + public avatarUrl = '' ; public myRestrictions: FileRestrictions = { allowedExtensions: ['.jpg', '.png', '.jpeg'], maxFileSize: 2194304 @@ -23,7 +24,9 @@ export class ClientProfileComponent implements OnInit { public opened = false; // dialog box public Message = ''; // dialog message - constructor(private auth: AuthService, private ps: PeopleService) { } + constructor(private auth: AuthService, private ps: PeopleService) { + this.avatarUrl = 'url("' + location.origin + './assets/img/avatar.png' + '")'; + } ngOnInit(): void { diff --git a/src/app/lender-uploads/lender-uploads.component.html b/src/app/lender-uploads/lender-uploads.component.html index 9b59579..a893873 100644 --- a/src/app/lender-uploads/lender-uploads.component.html +++ b/src/app/lender-uploads/lender-uploads.component.html @@ -1,32 +1,43 @@
- - -
-
Name: {{ files[0].name }}
-
Cannot upload this file {{files[0]}}
-
fuck all {{map.get(files[0].uid).response.body.Funder}}
-
-
+ + + + + + +
- +
-
- +
+ +
diff --git a/src/app/lender-uploads/lender-uploads.component.ts b/src/app/lender-uploads/lender-uploads.component.ts index 3cd73de..0eab35a 100644 --- a/src/app/lender-uploads/lender-uploads.component.ts +++ b/src/app/lender-uploads/lender-uploads.component.ts @@ -1,11 +1,21 @@ -import {AfterViewInit, Component, ElementRef, EventEmitter, OnInit, Output, ViewChild, ViewEncapsulation} from '@angular/core'; -import {FileInfo, FileRestrictions, SuccessEvent, UploadComponent, UploadEvent, UploadProgressEvent} from '@progress/kendo-angular-upload'; +import {Component, EventEmitter, OnInit, Output} from '@angular/core'; +import {FileInfo, FileRestrictions, SuccessEvent, UploadEvent, UploadProgressEvent} from '@progress/kendo-angular-upload'; import {AuthService} from '../service/auth.service'; -import {range} from '@progress/kendo-angular-dateinputs/dist/es2015/util'; +import {debounce} from 'ts-debounce'; import {Router} from '@angular/router'; import {PageChangeEvent} from '@progress/kendo-angular-pager'; -import {ImagePopupDialogComponent} from '../image-popup-dialog/image-popup-dialog.component'; import {UploadAttachService} from '../service/upload.attach.service'; +import {AppConfig} from '../app.config'; +import {UploadMetalList, UploadMetaModel} from '../models/uploadMetaModel'; +import {UploadingInfoModel} from '../models/uploading.info.model'; + +class UploadingCards{ + Uploading = false; + IsDuplicate = false; + IsNew = false; + Info: UploadingInfoModel = new UploadingInfoModel({}); + Meta: UploadMetaModel = new UploadMetaModel({}); +} @Component({ selector: 'app-lender-uploads', @@ -13,79 +23,113 @@ import {UploadAttachService} from '../service/upload.attach.service'; styleUrls: ['./lender-uploads.component.scss'], }) export class LenderUploadsComponent implements OnInit { - @Output() success: EventEmitter = new EventEmitter(); - @Output() click: EventEmitter = new EventEmitter(); - @Output() complete: EventEmitter = new EventEmitter(); + @Output() uploadSuccessful: EventEmitter = new EventEmitter(); + @Output() uploadClick: EventEmitter = new EventEmitter(); + @Output() uploadComplete: EventEmitter = new EventEmitter(); @Output() upload: EventEmitter = new EventEmitter(); - private uploads: SuccessEvent[] = []; - public value = 0 ; - public map: Map = new Map(); public loading = false; - uploadSaveUrl = 'https://svr2021.lawipac.com:8080/api/v1/lender-upload/'; // should represent an actual API endpoint - uploadRemoveUrl = 'https://svr2021.lawipac.com:8080/api/v1/lender-upload-remove/'; // should represent an actual API endpoint + uploadSaveUrl = ''; // should represent an actual API endpoint + uploadRemoveUrl = ''; // should represent an actual API endpoint - public allUploads = [...range(30, 44 )]; - public displayedUploads: any[] = []; - public filteredUploads: any[] = []; + public allUploads: UploadingCards[] = []; public skip = 0; public pageSize = 12; public total = 0; + public strFilter = ''; + + private debouncedSearch: any; myRestrictions: FileRestrictions = { - allowedExtensions: ['.pdf', '.xls', '.xlsx'] + allowedExtensions: ['.pdf', '.xls', '.xlsx'], + maxFileSize: 30240000, + minFileSize: 1000, }; - constructor(private auth: AuthService, private router: Router, private uas: UploadAttachService) { + constructor(private auth: AuthService, private router: Router, private uas: UploadAttachService, private config: AppConfig) { + this.uploadSaveUrl = this.config.apiUrl + 'lender-upload/'; + this.uploadRemoveUrl = this.config.apiUrl + 'lender-upload-remove/'; } ngOnInit(): void { + this.debouncedSearch = debounce(this.loadDisplayRecords, 500); this.uploadSaveUrl = this.auth.getUrl('lender-upload/'); this.uploadRemoveUrl = this.auth.getUrl('lender-upload-remove/'); - this.loadDisplayedUploads(); - + this.loadAllUploads(); } - - public onClick( files: any): void{ - this.click.emit(files[0]); + this.uploadClick.emit(files[0]); } public onSuccess(ss: SuccessEvent ): void { - this.uploads.push(ss); - this.map.set(ss.files[0].uid, ss); - this.success.emit(ss); - this.allUploads.unshift(this.allUploads.length + 100); + this.uploadSuccessful.emit(ss); + + const idx = this.uid2Idx(ss.files[0].uid); + this.allUploads[idx].Meta = new UploadMetaModel(ss.response.body); + this.allUploads[idx].Info.MetaId = this.allUploads[idx].Meta.Id; // trigger analysis + this.allUploads[idx].IsDuplicate = ss.response.body.IsDuplicate; + + // remove card + const uid = ss.files[0].uid; + if (this.allUploads[idx].IsDuplicate ) { + this.allUploads[idx].Info.Progress = 100; + const timer = setInterval(() => { + this.allUploads[idx].Info.Progress -= this.randBetween(1, 10); // when many cards to be removed, it's better not altogether + if (this.allUploads[idx].Info.Progress <= 0 ) { + clearInterval(timer); + this.allUploads = this.allUploads.filter(v => { + return v.Info.UniqueId !== uid; + }); + } + }, 100); + } } - public onUpload(ss: UploadEvent ): void { - this.upload.emit(true); + private randBetween(start: number, end: number): number { + return Math.floor(Math.random() * end) + start; + } + + private uid2Idx(uid: string): number { + return this.allUploads.findIndex( v => { + return v.Info.UniqueId === uid; + }); + } + + public onStartUpload(ss: UploadEvent ): void { + const uc = new UploadingCards(); + uc.Uploading = true; + uc.IsDuplicate = false; + uc.IsNew = true; + uc.Info.UniqueId = ss.files[0].uid; + uc.Info.FileName = ss.files[0].name; + uc.Info.Progress = 0; + uc.Info.MetaId = 0 ; + this.allUploads.unshift(uc); + } public onComplete(): void { - this.upload.emit(false); + console.log('ok completed'); } - public hasResp(uid): boolean { - let found = false; - this.uploads.every(v => { - if ( v.files[0].uid === uid ) { - found = true; - return false; // stop search - } - }); - return found; + public onUploadError(e: any): void { + console.log(e); } public uploadProgress(prog: UploadProgressEvent): void { - this.value = prog.percentComplete.valueOf(); + prog.files.forEach( v => { + const idx = this.uid2Idx(v.uid); + this.allUploads[idx].Info.Progress = prog.percentComplete.valueOf(); + // console.log(prog.percentComplete.valueOf(), v.uid, v); + } ); } + public show( i: number): void{ this.router.navigate(['/upload-details/' + i]); } @@ -94,29 +138,49 @@ export class LenderUploadsComponent implements OnInit { public onPageChange(e: PageChangeEvent): void { this.skip = e.skip; this.pageSize = e.take; - this.loadDisplayedUploads(); + this.loadDisplayRecords(); } - private loadDisplayedUploads(): void { - this.filteredUploads = this.allUploads ; - this.displayedUploads = this.filteredUploads.slice(this.skip, this.skip + this.pageSize); - this.total = this.displayedUploads.length; + private loadAllUploads(): void{ + this.skip = 0; + this.onFilterUploads(this.strFilter); + } + public onFilterUploads(hint: string): void { + this.skip = 0; + this.strFilter = hint; + this.debouncedSearch(); } - private loadAllUploads(): void{ + private loadDisplayRecords(): void { + this.allUploads = []; this.loading = true; - // this.uas.getUploadMetaList(this.skip, this.skip + this.pageSize).subscribe( - // resp => { - // this.loading = false; - // } - // ); - + this.uas.getUploadMetaList(this.skip, this.pageSize, this.strFilter).subscribe( + (resp: UploadMetalList ) => { + this.loading = false; + this.total = resp.Total; + resp.Data.forEach((v) => { + const uc = new UploadingCards(); + uc.Uploading = false; + uc.Meta = new UploadMetaModel(v); + this.allUploads.push(uc); + }); + }, err => { this.loading = false; }, + () => { this.loading = false; } + ); } - public onFilterUploads(hint: string): void { - this.loadDisplayedUploads(); + public onDelete(ulMeta: UploadMetaModel): void{ + this.allUploads = this.allUploads.filter((v) => { + return v.Meta.Id !== ulMeta.Id; + }); + // console.log('delete', ulMeta, this); } - + public onCompleteSingle(uid: string): void { + const idx = this.uid2Idx(uid); + if (this.allUploads[idx] !== undefined ){ + this.allUploads[idx].Uploading = false; + } + } } diff --git a/src/app/list-all-loans/list-all-loans.component.html b/src/app/list-all-loans/list-all-loans.component.html index 4c432c6..0e4748c 100644 --- a/src/app/list-all-loans/list-all-loans.component.html +++ b/src/app/list-all-loans/list-all-loans.component.html @@ -165,9 +165,9 @@ - + - {{ dataItem.Trail | currency }} + {{ dataItem.IncomeTotal | currency }}
- +
diff --git a/src/app/models/PastYearMonthly.model.ts b/src/app/models/PastYearMonthly.model.ts index b5b9471..ed4a54d 100644 --- a/src/app/models/PastYearMonthly.model.ts +++ b/src/app/models/PastYearMonthly.model.ts @@ -6,6 +6,6 @@ export class PastYearMonthlyData { Month: number; Year: number; Amount: number; - Trail: number; + IncomeTotal: number; Summary: string; } diff --git a/src/app/models/uploadMetaModel.ts b/src/app/models/uploadMetaModel.ts index 4dbe464..d3ab6e4 100644 --- a/src/app/models/uploadMetaModel.ts +++ b/src/app/models/uploadMetaModel.ts @@ -22,6 +22,19 @@ export class UploadMetaModel { get iconUrl(): string { const t = this.Format.replace( '/', '-'); - return location.origin +'/assets/img/mime/' + t + '.png'; + return location.origin + '/assets/img/mime/' + t.toLowerCase() + '.png'; } + + static iconUrlBySuffix(suffix: string): string { + return location.origin + '/assets/img/suffix/' + suffix.toLowerCase() + '.png'; + } + + static thumbDefault(): string { + return location.origin + '/assets/img/thumb_file_icon.webp'; + } +} + +export class UploadMetalList { + Total: number; + Data: UploadMetaModel[]; } diff --git a/src/app/models/uploading.info.model.ts b/src/app/models/uploading.info.model.ts new file mode 100644 index 0000000..a4ff3ee --- /dev/null +++ b/src/app/models/uploading.info.model.ts @@ -0,0 +1,13 @@ +export class UploadingInfoModel { + FileName: string; + UniqueId: string; + MetaId: number; + Progress: number; + + constructor (payload: Partial){ + this.FileName = payload.FileName || ''; + this.UniqueId = payload.UniqueId || ''; + this.MetaId = payload.MetaId || 0; + this.Progress = payload.Progress || 0 ; + } +} diff --git a/src/app/people-select/people-select.component.ts b/src/app/people-select/people-select.component.ts index 3dd6b3a..5bbeea6 100644 --- a/src/app/people-select/people-select.component.ts +++ b/src/app/people-select/people-select.component.ts @@ -4,9 +4,7 @@ import { debounce } from 'ts-debounce'; import {PeopleModel} from '../models/people.model'; import {ControlValueAccessor, FormControl, FormGroup, NG_VALUE_ACCESSOR} from '@angular/forms'; import {MultiColumnComboBoxComponent} from '@progress/kendo-angular-dropdowns'; -import {Observable, of} from 'rxjs'; -import {PercentPipe} from '@angular/common'; -import {map} from 'rxjs/operators'; +import {Observable} from 'rxjs'; import {PeopleService} from '../service/people.service'; @Component({ diff --git a/src/app/service/auth.service.ts b/src/app/service/auth.service.ts index d106912..7f2cef7 100644 --- a/src/app/service/auth.service.ts +++ b/src/app/service/auth.service.ts @@ -9,11 +9,9 @@ import {AppConfig} from '../app.config'; @Injectable() export class AuthService { + public apiUrl = ''; + public apiWsUrl = ''; - public apiUrl = 'https://svr2021.lawipac.com:8080/api/v1/'; - public apiWsUrl = 'wss://svr2021.lawipac.com:8080/api/v1/ws'; - // public apiUrl = 'https://c5016.biukop.com.au:8080/api/v1/'; - // public apiWsUrl = 'wss://c5016.biukop.com.au:8080/api/v1/ws'; public loggedIn = ApiV1LoginResponse.EmptyNew(); loginSuccess = new EventEmitter (); diff --git a/src/app/service/upload.attach.service.ts b/src/app/service/upload.attach.service.ts index de4a70c..11f834f 100644 --- a/src/app/service/upload.attach.service.ts +++ b/src/app/service/upload.attach.service.ts @@ -2,7 +2,7 @@ import {Injectable} from '@angular/core'; import {HttpClient} from '@angular/common/http'; import {AuthService} from './auth.service'; import {Observable} from 'rxjs'; -import {UploadMetaModel} from '../models/uploadMetaModel'; +import {UploadMetalList, UploadMetaModel} from '../models/uploadMetaModel'; import {UploadAnalysisModel} from '../models/upload.analysis.model'; @@ -19,6 +19,14 @@ export class UploadAttachService { return this.http.get(this.auth.getUrl('upload-analysis/' + id)); } + public getUploadMetaList(Skip: number, Take: number, Filter: string): Observable { + return this.http.post(this.auth.getUrl('upload-meta-list/'), {Skip, Take, Filter}); + } + + public deleteUpload(id: number): Observable { + return this.http.delete(this.auth.getUrl('upload/' + id)); + } + public getUploadAsJpgUrl(id: number): string { const ts = Date.now(); return this.auth.getUrl('upload-as-image/' + id + '?date=' + ts); @@ -51,4 +59,20 @@ export class UploadAttachService { return this.auth.getUrl('upload-as-thumbnail/' + id ); } + + public createThumb(id: number): Observable { + return this.http.put(this.auth.getUrl('upload-as-thumbnail/' + id), {}); + } + + public createPreview(id: number): Observable{ + return this.http.put(this.auth.getUrl('upload-as-image/' + id), {}); + } + + public createPDF(id: number): Observable{ + return this.http.put(this.auth.getUrl('upload-as-pdf/' + id), {}); + } + + public createAnalysis(id: number): Observable { + return this.http.put(this.auth.getUrl('upload-analysis/' + id), {}); + } } diff --git a/src/app/upload-cards/upload-cards.component.html b/src/app/upload-cards/upload-cards.component.html index aa11ecb..8b2362d 100644 --- a/src/app/upload-cards/upload-cards.component.html +++ b/src/app/upload-cards/upload-cards.component.html @@ -3,11 +3,14 @@ -

some title

+ +

{{ ( uploadMeta.FileName.length > 17 ) ? (uploadMeta.FileName | slice:0:17) + "..." : (uploadMeta.FileName)}}

-

{{uploadId}}

- +

{{uploadMeta.FileName}}

+

{{uploadMeta.Ts | date:"longDate" }}

+

Id = {{uploadMeta.Id }}

+
NEW
diff --git a/src/app/upload-cards/upload-cards.component.scss b/src/app/upload-cards/upload-cards.component.scss index 2be2a11..09650db 100644 --- a/src/app/upload-cards/upload-cards.component.scss +++ b/src/app/upload-cards/upload-cards.component.scss @@ -23,6 +23,21 @@ div.card-wrapper{ background-position: center center; } + + div.isNew { + width: 80px; + height: 20px; + color: white; + background-color: #f50606; + transform: rotate( + 45deg + ); + position: absolute; + bottom: 5px; + left: -25px; + z-index: 10; + } + button.action { border-radius: 100%; height:32px; @@ -92,6 +107,15 @@ div.card-wrapper{ transition: all $speed ease-out; } + kendo-card-body { + p.FileName { + display:none; + } + p.Id { + display:none; + } + } + &:hover { p { z-index: 100; @@ -124,6 +148,17 @@ div.card-wrapper{ } } + kendo-card-body { + p.FileName { + display:block; + word-break: break-all; + } + p.Id { + display:block; + word-break: break-all; + } + } + } } diff --git a/src/app/upload-cards/upload-cards.component.ts b/src/app/upload-cards/upload-cards.component.ts index 2817462..6e401a8 100644 --- a/src/app/upload-cards/upload-cards.component.ts +++ b/src/app/upload-cards/upload-cards.component.ts @@ -4,6 +4,7 @@ import {ImagePopupDialogComponent} from '../image-popup-dialog/image-popup-dialo import {AuthService} from '../service/auth.service'; import {UploadMetaModel} from '../models/uploadMetaModel'; import {UploadAttachService} from '../service/upload.attach.service'; +import {AppConfig} from '../app.config'; @@ -15,14 +16,19 @@ import {UploadAttachService} from '../service/upload.attach.service'; export class UploadCardsComponent implements OnInit { @Input() uploadId: number; @Input() icon = ''; + @Output() deleted = new EventEmitter(); @ViewChild('imgBox', {static: true}) imgBox: ImagePopupDialogComponent; @ViewChild('downloadLink', {static: true}) downloadLink: ElementRef; public uploadMeta: UploadMetaModel = new UploadMetaModel({}); - public thumbImage = 'https://svr2021.lawipac.com:8080/api/v1/upload-as-thumbnail/31'; + public thumbImage = ''; public fullImage = ''; - constructor(private router: Router, private auth: AuthService, private uas: UploadAttachService) { } + public IsNew = false; + + constructor(private router: Router, private auth: AuthService, private uas: UploadAttachService, private config: AppConfig) { + this.thumbImage = location.origin + '/assets/img/nopreview-thumb.png'; + } ngOnInit(): void { let url = this.auth.getUrl('upload-as-thumbnail/' + this.uploadId); @@ -33,9 +39,19 @@ export class UploadCardsComponent implements OnInit { this.uas.getUploadMeta(this.uploadId).subscribe( resp => { this.uploadMeta = new UploadMetaModel(resp); this.icon = this.uploadMeta.iconUrl; + this.IsNew = this.DateDiff(this.uploadMeta.Ts, new Date()) < 1; }); } + + private DateDiff(date1: Date, date2: Date): number { + const dt1 = new Date(date1); + const dt2 = new Date(date2); + return Math.floor((Date.UTC(dt2.getFullYear(), dt2.getMonth(), dt2.getDate()) + - Date.UTC(dt1.getFullYear(), dt1.getMonth(), dt1.getDate()) ) + / (1000 * 60 * 60 * 24)); + } + public onNavigateTo(id: number ): void{ this.router.navigate(['/upload-details/', id]); } @@ -59,4 +75,10 @@ export class UploadCardsComponent implements OnInit { this.imgBox.showImg(url, this.uploadId + ' - ' + this.uploadMeta.FileName); } + public onDelete(id: number): void { + this.uas.deleteUpload(id).subscribe( resp => { + const ulMeta = new UploadMetaModel(resp); + this.deleted.emit(ulMeta); + }); + } } diff --git a/src/app/upload-detail/upload-detail.component.ts b/src/app/upload-detail/upload-detail.component.ts index b0a46ee..f24320d 100644 --- a/src/app/upload-detail/upload-detail.component.ts +++ b/src/app/upload-detail/upload-detail.component.ts @@ -21,7 +21,7 @@ export class UploadDetailComponent implements OnInit, AfterViewInit { @ViewChild('pdf', {static: false}) pdf: ElementRef; @ViewChild('tabs', {static: true}) tab: TabStripComponent; // 'http://africau.edu/images/default/sample.pdf'; - public uploadAsPicUrl = 'https://svr2021.lawipac.com:8080/api/v1/upload-as-pdf/default'; + public uploadAsPicUrl = ''; public uploadAsPdfUrl = ''; public initAnimation = false; public iframeLoaded = false; @@ -42,7 +42,10 @@ export class UploadDetailComponent implements OnInit, AfterViewInit { public analysisAAA: AnalysisAaaModel[] = []; - constructor(private us: UploadAttachService, private actRoute: ActivatedRoute, private router: Router) { } + constructor(private us: UploadAttachService, private actRoute: ActivatedRoute, private router: Router) { + this.uploadAsPicUrl = location.origin + 'assets/img/no_preview.jpg'; + this.uploadAsPdfUrl = location.origin + 'assets/pdf/no_preview.pdf'; + } ngOnInit(): void { const id = this.actRoute.snapshot.params.id; @@ -118,7 +121,6 @@ export class UploadDetailComponent implements OnInit, AfterViewInit { } const el = this.pdf.nativeElement; if (el !== undefined && el.src === this.uploadAsPdfUrl) { - console.log('yes true', this); this.iframeLoaded = true; } } diff --git a/src/app/uploading-progress-card/uploading-progress-card.component.html b/src/app/uploading-progress-card/uploading-progress-card.component.html new file mode 100644 index 0000000..c795279 --- /dev/null +++ b/src/app/uploading-progress-card/uploading-progress-card.component.html @@ -0,0 +1,59 @@ +
+
+ + + +

{{Operation}}

+

Removing...

+
+ +

+ {{ ( FileName.length > 17 ) ? (FileName | slice:0:17) + "..." : (FileName)}} +

+

This is Duplicate

+
+
+ + + + + 1 pdf convert + +
+
+ + + + + 2 preview + +
+
+ + + + + 3 miniature + +
+ +
+ + + + + 4 construction + +
+
+
DUP
+
+ +
+ +
+
+
+ +
diff --git a/src/app/uploading-progress-card/uploading-progress-card.component.scss b/src/app/uploading-progress-card/uploading-progress-card.component.scss new file mode 100644 index 0000000..f9a73c2 --- /dev/null +++ b/src/app/uploading-progress-card/uploading-progress-card.component.scss @@ -0,0 +1,110 @@ +$hoverColor: #d0d9ff; +$normalHeaderColor: #01838d; +$normalFooterColor: #10838d; +$speed: 0.5s; + +div.card-wrapper{ + width:210px; + height: 300px; + padding:10px; + margin-bottom: 20px; + + min-height:200px; + display: flex; + flex-wrap: wrap; + align-items: center; + justify-content: center; + + + .upload-thumb{ + min-height: 100px; + overflow: hidden; + background-size: contain; + background-repeat: no-repeat; + background-position: center center; + } + + .file-type-image{ + width: 32px; + // border-radius:100%; + background-repeat: no-repeat; + background-size: cover; + // border:1px white solid; + // box-shadow: inset 1px 1px 0 #b7b7b7; + + z-index: 2; + height: 32px; + position: absolute; + margin-right: 10px; + left : 160px; + top: 20px; + } + + kendo-card { + height: 100%; + box-shadow: 1px 1px 2px white; + border-radius: 10px; + } + + .upload-card-content { + p { + z-index: 100; + transition: all 0.3s ease-out; + } + + kendo-card-header, + kendo-card-footer{ + background-color: $hoverColor; + } + + kendo-card-header{ + p { + color: black; + } + + .file-type-image{ + box-shadow: none; + } + } + + kendo-card-body { + p { + color: black; + display:block; + background: $hoverColor; + word-break: break-all; + padding: 5px; + border-radius: 5px; + + } + } + } + + kendo-progressbar{ + width:100%; + } + + + div.duplicate { + width: 80px; + height: 20px; + color: black; + background-color: yellow; + -ms-transform: rotate(45deg); + transform: rotate( + 45deg + ); + position: absolute; + bottom: 5px ; + left: -25px; + z-index: 10; + } + + kendo-stepper{ + width: 180px; + } + + div.steps{ + text-align:left; + } +} diff --git a/src/app/uploading-progress-card/uploading-progress-card.component.spec.ts b/src/app/uploading-progress-card/uploading-progress-card.component.spec.ts new file mode 100644 index 0000000..fba9a2c --- /dev/null +++ b/src/app/uploading-progress-card/uploading-progress-card.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { UploadingProgressCardComponent } from './uploading-progress-card.component'; + +describe('UploadingProgressCardComponent', () => { + let component: UploadingProgressCardComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ UploadingProgressCardComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(UploadingProgressCardComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/uploading-progress-card/uploading-progress-card.component.ts b/src/app/uploading-progress-card/uploading-progress-card.component.ts new file mode 100644 index 0000000..fdcc3cb --- /dev/null +++ b/src/app/uploading-progress-card/uploading-progress-card.component.ts @@ -0,0 +1,108 @@ +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {UploadMetaModel} from '../models/uploadMetaModel'; +import {UploadAttachService} from '../service/upload.attach.service'; + +@Component({ + selector: 'app-uploading-progress-card', + templateUrl: './uploading-progress-card.component.html', + styleUrls: ['./uploading-progress-card.component.scss'] +}) +export class UploadingProgressCardComponent implements OnInit { + + @Input() MetaId = 0 ; + @Input() FileName = ''; + @Input() UniqueId = ''; + @Input() Progress = 0 ; + @Input() IsDuplicate = false ; + @Output() Complete: EventEmitter = new EventEmitter(); + + public Operation = 'Uploading'; + public icon = ''; + public thumbImage = UploadMetaModel.thumbDefault(); + // sub steps after uploading + public thumbSuccess = false; + public pdfSuccess = false; + public previewSuccess = false; + public analysisSuccess = false; + // indicator + public analyzing = false; + public currentStep = ''; + + private waitingTimer: any; + + constructor( private uas: UploadAttachService) { } + + ngOnInit(): void { + const suffix = this.FileName.split('.').pop(); + this.icon = UploadMetaModel.iconUrlBySuffix(suffix); + this.prePareToStartAnalysis(); + return; + } + + private prePareToStartAnalysis(): void { + this.waitingTimer = setInterval( + () => { + if ( this.Progress >= 100 && this.MetaId !== 0) { + clearInterval(this.waitingTimer); + this.startAnalysis(); + } + } + , 500); + } + public startAnalysis(): void { + this.thumbSuccess = false; + this.pdfSuccess = false; + this.previewSuccess = false; + this.analysisSuccess = false; + + this.analyzing = true; + this.Operation = 'Processing'; + this.createPdf(); + } + + private createPdf(): void { + this.currentStep = 'pdf'; + this.uas.createPDF(this.MetaId).subscribe( + resp => { this.pdfSuccess = resp; }, + error => { this.pdfSuccess = false; this.createPreview(); }, + () => { this.createPreview(); } + ); + } + + private createPreview(): void { + this.currentStep = 'preview'; + this.uas.createPreview(this.MetaId).subscribe( + resp => { this.previewSuccess = resp; }, + error => { this.previewSuccess = false; this.createThumb(); }, + () => { this.createThumb(); } + ); + } + + private createThumb(): void { + this.currentStep = 'thumb'; + this.uas.createThumb(this.MetaId).subscribe( + resp => { this.thumbSuccess = resp; }, + error => { this.thumbSuccess = false; this.createAnalysis(); }, + () => { this.createAnalysis(); } + ); + } + + + private createAnalysis(): void { + this.currentStep = 'analysis'; + this.uas.createAnalysis(this.MetaId).subscribe( + resp => { this.analysisSuccess = true; }, + error => { this.analysisSuccess = false; this.endAnalysis(); }, + () => { this.endAnalysis(); } + ); + } + + private endAnalysis(): void{ + this.analyzing = false; + this.Operation = 'Done'; + this.currentStep = ''; + this.Complete.emit(this.UniqueId); + } + + +} diff --git a/src/assets/img/no_preview.jpg b/src/assets/img/no_preview.jpg new file mode 100644 index 0000000..0331a92 Binary files /dev/null and b/src/assets/img/no_preview.jpg differ diff --git a/src/assets/img/nopreview-thumb.jpg b/src/assets/img/nopreview-thumb.jpg new file mode 100644 index 0000000..4c77dfa Binary files /dev/null and b/src/assets/img/nopreview-thumb.jpg differ diff --git a/src/assets/img/suffix/pdf.png b/src/assets/img/suffix/pdf.png new file mode 100644 index 0000000..e9fbafd Binary files /dev/null and b/src/assets/img/suffix/pdf.png differ diff --git a/src/assets/img/suffix/xls.png b/src/assets/img/suffix/xls.png new file mode 100644 index 0000000..ebf0d74 Binary files /dev/null and b/src/assets/img/suffix/xls.png differ diff --git a/src/assets/img/suffix/xlsx.png b/src/assets/img/suffix/xlsx.png new file mode 100644 index 0000000..ebf0d74 Binary files /dev/null and b/src/assets/img/suffix/xlsx.png differ diff --git a/src/assets/img/thumb_file_icon.webp b/src/assets/img/thumb_file_icon.webp new file mode 100644 index 0000000..24c151a Binary files /dev/null and b/src/assets/img/thumb_file_icon.webp differ diff --git a/src/assets/pdf/no_preview.pdf b/src/assets/pdf/no_preview.pdf new file mode 100644 index 0000000..f3634c6 Binary files /dev/null and b/src/assets/pdf/no_preview.pdf differ diff --git a/src/index.html b/src/index.html index 58feb1b..29c3e61 100644 --- a/src/index.html +++ b/src/index.html @@ -10,13 +10,24 @@ + +