11import { ChangeDetectionStrategy , ChangeDetectorRef , Component , EventEmitter , HostListener , Input , Output , ViewEncapsulation , } from '@angular/core' ;
22
3- import { of as observableOf } from 'rxjs' ;
4- import { FileUploader } from 'ng2-file-upload' ;
3+ import { firstValueFrom , Observable , of as observableOf } from 'rxjs' ;
4+ import { FileItem , FileUploader } from 'ng2-file-upload' ;
55import uniqueId from 'lodash/uniqueId' ;
66import { ScrollToService } from '@nicky-lenaers/ngx-scroll-to' ;
77
@@ -12,7 +12,14 @@ import { HttpXsrfTokenExtractor } from '@angular/common/http';
1212import { XSRF_COOKIE , XSRF_REQUEST_HEADER , XSRF_RESPONSE_HEADER } from '../../../core/xsrf/xsrf.interceptor' ;
1313import { CookieService } from '../../../core/services/cookie.service' ;
1414import { DragService } from '../../../core/drag.service' ;
15+ import { ConfigurationDataService } from '../../../core/data/configuration-data.service' ;
16+ import { map } from 'rxjs/operators' ;
17+ import { getFirstCompletedRemoteData } from '../../../core/shared/operators' ;
18+ import { RemoteData } from '../../../core/data/remote-data' ;
19+ import { ConfigurationProperty } from '../../../core/shared/configuration-property.model' ;
20+ import { TranslateService } from '@ngx-translate/core' ;
1521
22+ export const MAX_UPLOAD_FILE_SIZE_CFG_PROPERTY = 'spring.servlet.multipart.max-file-size' ;
1623@Component ( {
1724 selector : 'ds-uploader' ,
1825 templateUrl : 'uploader.component.html' ,
@@ -90,7 +97,9 @@ export class UploaderComponent {
9097 private scrollToService : ScrollToService ,
9198 private dragService : DragService ,
9299 private tokenExtractor : HttpXsrfTokenExtractor ,
93- private cookieService : CookieService
100+ private cookieService : CookieService ,
101+ private configurationService : ConfigurationDataService ,
102+ private translate : TranslateService
94103 ) {
95104 }
96105
@@ -129,7 +138,20 @@ export class UploaderComponent {
129138 if ( isUndefined ( this . onBeforeUpload ) ) {
130139 this . onBeforeUpload = ( ) => { return ; } ;
131140 }
132- this . uploader . onBeforeUploadItem = ( item ) => {
141+ this . uploader . onBeforeUploadItem = async ( item ) => {
142+ // Check if the file size is within the maximum upload size
143+ const canUpload = await this . checkFileSizeLimit ( item ) ;
144+ // If the file size is too large, emit an error and cancel all uploads
145+ if ( ! canUpload ) {
146+ this . onUploadError . emit ( {
147+ item : item ,
148+ response : this . translate . instant ( 'submission.sections.upload.upload-failed.size-limit-exceeded' ) ,
149+ status : 400 ,
150+ headers : { }
151+ } ) ;
152+ this . uploader . cancelAll ( ) ;
153+ return ;
154+ }
133155 if ( item . url !== this . uploader . options . url ) {
134156 item . url = this . uploader . options . url ;
135157 }
@@ -225,4 +247,38 @@ export class UploaderComponent {
225247 this . cookieService . set ( XSRF_COOKIE , token ) ;
226248 }
227249
250+ // Check if the file size is within the maximum upload size
251+ private async checkFileSizeLimit ( item : FileItem ) : Promise < boolean > {
252+ const maxFileUploadSize = await firstValueFrom ( this . getMaxFileUploadSizeFromCfg ( ) ) ;
253+ if ( maxFileUploadSize ) {
254+ const maxSizeInGigabytes = parseInt ( maxFileUploadSize ?. [ 0 ] , 10 ) ;
255+ const maxSizeInBytes = this . gigabytesToBytes ( maxSizeInGigabytes ) ;
256+ // If maxSizeInBytes is -1, it means the value in the config is invalid. The file won't be uploaded and the user
257+ // will see error messages in the UI.
258+ if ( maxSizeInBytes === - 1 ) {
259+ return false ;
260+ }
261+ return item ?. file ?. size <= maxSizeInBytes ;
262+ }
263+ return false ;
264+ }
265+
266+ // Convert gigabytes to bytes
267+ private gigabytesToBytes ( gigabytes : number ) : number {
268+ if ( typeof gigabytes !== 'number' || isNaN ( gigabytes ) || ! isFinite ( gigabytes ) || gigabytes < 0 ) {
269+ return - 1 ;
270+ }
271+ return gigabytes * Math . pow ( 2 , 30 ) ; // 2^30 bytes in a gigabyte
272+ }
273+
274+ // Get the maximum file upload size from the configuration
275+ public getMaxFileUploadSizeFromCfg ( ) : Observable < string [ ] > {
276+ return this . configurationService . findByPropertyName ( MAX_UPLOAD_FILE_SIZE_CFG_PROPERTY ) . pipe (
277+ getFirstCompletedRemoteData ( ) ,
278+ map ( ( propertyRD : RemoteData < ConfigurationProperty > ) => {
279+ return propertyRD . hasSucceeded ? propertyRD . payload . values : [ ] ;
280+ } )
281+ ) ;
282+ }
283+
228284}
0 commit comments