@bnsights/bbsf-controls 1.0.179 → 1.0.181
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -3
- package/esm2022/lib/controls/FileUpload/FileUpload.component.mjs +439 -1091
- package/fesm2022/bnsights-bbsf-controls.mjs +441 -1093
- package/fesm2022/bnsights-bbsf-controls.mjs.map +1 -1
- package/lib/controls/FileUpload/FileUpload.component.d.ts +14 -123
- package/package.json +2 -2
|
@@ -52,7 +52,7 @@ import { TranslateService } from '@ngx-translate/core';
|
|
|
52
52
|
import { SweetAlert2Module } from '@sweetalert2/ngx-sweetalert2';
|
|
53
53
|
import * as i3 from '@bnsights/bbsf-utilities';
|
|
54
54
|
import { RequestOptionsModel, environment as environment$1, BBSFUtilitiesModule, UtilityService, ConfigurationService, EnvironmentService, AuthService } from '@bnsights/bbsf-utilities';
|
|
55
|
-
import { Subject, Observable, noop as noop$1, of,
|
|
55
|
+
import { Subject, Observable, noop as noop$1, of, EMPTY, Subscription, switchMap as switchMap$1 } from 'rxjs';
|
|
56
56
|
import { switchMap, map, tap } from 'rxjs/operators';
|
|
57
57
|
import * as i6 from '@angular/cdk/bidi';
|
|
58
58
|
import dayGridPlugin from '@fullcalendar/daygrid';
|
|
@@ -2107,1215 +2107,563 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
2107
2107
|
}], ctorParameters: () => [{ type: i3.RequestHandlerService }] });
|
|
2108
2108
|
|
|
2109
2109
|
class FileUploadComponent {
|
|
2110
|
-
static { this.
|
|
2111
|
-
constructor(controlContainer,
|
|
2110
|
+
static { this.controlContainerstatic = null; }
|
|
2111
|
+
constructor(controlContainer, MultipleFileUplaodControlHost, controlUtility, UtilityService, controlValidationService, globalSettings, fileUploadService) {
|
|
2112
2112
|
this.controlContainer = controlContainer;
|
|
2113
|
-
this.
|
|
2113
|
+
this.MultipleFileUplaodControlHost = MultipleFileUplaodControlHost;
|
|
2114
2114
|
this.controlUtility = controlUtility;
|
|
2115
|
-
this.
|
|
2115
|
+
this.UtilityService = UtilityService;
|
|
2116
2116
|
this.controlValidationService = controlValidationService;
|
|
2117
2117
|
this.globalSettings = globalSettings;
|
|
2118
2118
|
this.fileUploadService = fileUploadService;
|
|
2119
|
-
this.BYTES_TO_MB = 1024 * 1024;
|
|
2120
|
-
this.PROGRESS_COMPLETE = 100;
|
|
2121
|
-
this.PROGRESS_NEAR_COMPLETE = 95;
|
|
2122
|
-
this.ERROR_DISPLAY_DURATION = 5000;
|
|
2123
|
-
this.MAX_MEMORY_USAGE = 100 * 1024 * 1024; // 100MB limit
|
|
2124
|
-
this.currentMemoryUsage = 0;
|
|
2125
|
-
this.hasClearedRequiredError = false; // Track if required error was already cleared
|
|
2126
|
-
this.isSubmitted = false;
|
|
2127
2119
|
this.OnChange = new EventEmitter();
|
|
2128
2120
|
this.isUploadComplete = new EventEmitter();
|
|
2129
2121
|
this.validationMessage = '';
|
|
2130
2122
|
this.validationCountMessage = '';
|
|
2131
|
-
this.hasAnotherDropZoneOver = false;
|
|
2132
2123
|
this.acceptedType = '';
|
|
2133
2124
|
this.acceptedTypeArray = [];
|
|
2134
2125
|
this.toolTipTypeArray = [];
|
|
2135
2126
|
this.markAllAsTouched = false;
|
|
2136
2127
|
this.validationRules = [];
|
|
2137
|
-
this.
|
|
2138
|
-
this.file = null;
|
|
2128
|
+
this.validationRulesasync = [];
|
|
2139
2129
|
this.deletedFiles = [];
|
|
2140
|
-
this.subscriptions = new Subscription();
|
|
2141
2130
|
this.resetError = () => {
|
|
2142
2131
|
this.controlValidationService.removeGlobalError();
|
|
2143
2132
|
};
|
|
2133
|
+
//External Method
|
|
2144
2134
|
this.removeRequiredValidation = () => {
|
|
2145
2135
|
this.controlUtility.removeRequiredValidation(this.fileUploadFormControl, this.validationRules, this.options);
|
|
2146
2136
|
};
|
|
2147
|
-
|
|
2148
|
-
this.validationRules = this.validationRules.filter(validator => validator !== Validators.required);
|
|
2149
|
-
this.fileUploadFormControl.setValidators(this.validationRules);
|
|
2150
|
-
this.fileUploadFormControl.updateValueAndValidity();
|
|
2151
|
-
};
|
|
2137
|
+
//External Method
|
|
2152
2138
|
this.addRequiredValidation = () => {
|
|
2153
2139
|
this.controlUtility.addRequiredValidation(this.fileUploadFormControl, this.validationRules, this.options);
|
|
2154
2140
|
};
|
|
2141
|
+
//External Method
|
|
2155
2142
|
this.removeCustomValidation = (customValidation) => {
|
|
2156
2143
|
this.controlUtility.removeCustomValidation(this.fileUploadFormControl, this.validationRules, customValidation);
|
|
2157
2144
|
};
|
|
2145
|
+
//External Method
|
|
2158
2146
|
this.addCustomValidation = (customValidation) => {
|
|
2159
2147
|
this.controlUtility.addCustomValidation(this.fileUploadFormControl, this.validationRules, customValidation);
|
|
2160
2148
|
};
|
|
2149
|
+
//External Method
|
|
2161
2150
|
this.isValid = () => {
|
|
2162
2151
|
this.controlUtility.isValid(this.fileUploadFormControl);
|
|
2163
|
-
return this.fileUploadFormControl.valid;
|
|
2164
2152
|
};
|
|
2165
|
-
FileUploadComponent.
|
|
2166
|
-
this.initializeUploader();
|
|
2167
|
-
}
|
|
2168
|
-
initializeUploader() {
|
|
2153
|
+
FileUploadComponent.controlContainerstatic = this.controlContainer;
|
|
2169
2154
|
this.uploader = new FileUploader({
|
|
2170
|
-
disableMultipart: false
|
|
2155
|
+
disableMultipart: false // 'DisableMultipart' must be 'true' for formatDataFunction to be called.
|
|
2171
2156
|
});
|
|
2157
|
+
this.hasAnotherDropZoneOver = false;
|
|
2172
2158
|
}
|
|
2173
2159
|
ngOnInit() {
|
|
2174
|
-
this.initializeModels();
|
|
2175
|
-
this.setViewType();
|
|
2176
|
-
this.processInitialValue();
|
|
2177
|
-
this.setupLabels();
|
|
2178
|
-
this.setupFileTypeValidation();
|
|
2179
|
-
this.setupFormControl();
|
|
2180
|
-
this.setupSubscriptions();
|
|
2181
|
-
}
|
|
2182
|
-
initializeModels() {
|
|
2183
2160
|
this.fileUploadModel = new FileUploadModel();
|
|
2184
2161
|
this.multipleFileUploadModel = new MultipleFileUploadModel();
|
|
2185
|
-
|
|
2186
|
-
setViewType() {
|
|
2187
|
-
if (!this.options.viewType) {
|
|
2162
|
+
if (!this.options.viewType)
|
|
2188
2163
|
this.options.viewType = this.globalSettings.viewType;
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
processInitialValue() {
|
|
2192
2164
|
if (this.options.value == null) {
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
this.processSingleFileValue();
|
|
2200
|
-
}
|
|
2201
|
-
this.uploader.queue.forEach((element) => {
|
|
2202
|
-
element.progress = this.PROGRESS_COMPLETE;
|
|
2203
|
-
});
|
|
2204
|
-
}
|
|
2205
|
-
processMultipleFileValue() {
|
|
2206
|
-
const files = [];
|
|
2207
|
-
this.multipleFileUploadModel.existingFiles = this.options.value.existingFiles;
|
|
2208
|
-
this.multipleFileUploadModel.uploadedFiles = [];
|
|
2209
|
-
for (const element of this.options.value.existingFiles) {
|
|
2210
|
-
const fileLikeObject = this.createFileLikeObject(element);
|
|
2211
|
-
files.push(fileLikeObject);
|
|
2212
|
-
}
|
|
2213
|
-
this.uploader.addToQueue(files);
|
|
2214
|
-
}
|
|
2215
|
-
processSingleFileValue() {
|
|
2216
|
-
const element = this.options.value.file ?? this.options.value;
|
|
2217
|
-
const fileLikeObject = this.createFileLikeObject(element);
|
|
2218
|
-
this.file = element;
|
|
2219
|
-
this.uploader.addToQueue([fileLikeObject]);
|
|
2220
|
-
if (!this.options.value.file) {
|
|
2221
|
-
this.fileUploadModel = new FileUploadModel();
|
|
2222
|
-
this.fileUploadModel.file = this.options.value;
|
|
2165
|
+
if (this.options.isMultipleFile == true) {
|
|
2166
|
+
//this.options.Value=this.multipleFileUploadModel
|
|
2167
|
+
}
|
|
2168
|
+
else {
|
|
2169
|
+
// this.options.Value=this.fileUploadModel
|
|
2170
|
+
}
|
|
2223
2171
|
}
|
|
2224
2172
|
else {
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
return;
|
|
2250
|
-
}
|
|
2251
|
-
try {
|
|
2252
|
-
this.processAcceptedTypes();
|
|
2253
|
-
this.buildValidationMessage();
|
|
2254
|
-
// Log the processed types for debugging
|
|
2255
|
-
console.log('FileUpload: Processed file types:', {
|
|
2256
|
-
original: this.options.fileUploadAcceptsTypes,
|
|
2257
|
-
processed: this.acceptedTypeArray,
|
|
2258
|
-
acceptAttribute: this.acceptedType,
|
|
2259
|
-
displayTypes: this.toolTipTypeArray
|
|
2260
|
-
});
|
|
2261
|
-
}
|
|
2262
|
-
catch (error) {
|
|
2263
|
-
console.error('FileUpload: Error processing file types:', error);
|
|
2264
|
-
// Fallback to accepting all files if processing fails
|
|
2265
|
-
this.acceptedType = '';
|
|
2266
|
-
this.acceptedTypeArray = [];
|
|
2267
|
-
this.toolTipTypeArray = [];
|
|
2268
|
-
}
|
|
2269
|
-
}
|
|
2270
|
-
processAcceptedTypes() {
|
|
2271
|
-
// Process each file type and extract individual MIME types
|
|
2272
|
-
const allMimeTypes = [];
|
|
2273
|
-
for (const fileType of this.options.fileUploadAcceptsTypes) {
|
|
2274
|
-
if (fileType.includes(',')) {
|
|
2275
|
-
// Handle types like ImageTypes that contain multiple MIME types
|
|
2276
|
-
const mimeTypes = fileType.split(',').map(type => type.trim());
|
|
2277
|
-
allMimeTypes.push(...mimeTypes);
|
|
2173
|
+
if (this.options.isMultipleFile == true) {
|
|
2174
|
+
let files = [];
|
|
2175
|
+
this.multipleFileUploadModel.existingFiles = this.options.value.existingFiles;
|
|
2176
|
+
this.multipleFileUploadModel.uploadedFiles = [];
|
|
2177
|
+
for (let index = 0; index < this.options.value.existingFiles.length; index++) {
|
|
2178
|
+
const element = this.options.value.existingFiles[index];
|
|
2179
|
+
var bytes = new Uint8Array(element.bytes);
|
|
2180
|
+
var base64 = btoa(String.fromCharCode(null, bytes));
|
|
2181
|
+
this.fileLikeObject = {
|
|
2182
|
+
name: element.nameWithExtension,
|
|
2183
|
+
type: element.mimeType,
|
|
2184
|
+
rawFile: base64
|
|
2185
|
+
};
|
|
2186
|
+
// let blob: any;
|
|
2187
|
+
// blob = new Blob(['']) as any;
|
|
2188
|
+
// blob.name = element.FileName;
|
|
2189
|
+
// blob.lastModifiedDate = null;
|
|
2190
|
+
// blob.webkitRelativePath = '';
|
|
2191
|
+
let file = this.fileLikeObject;
|
|
2192
|
+
file.url = element.fileURL;
|
|
2193
|
+
files.push(file);
|
|
2194
|
+
}
|
|
2195
|
+
this.uploader.addToQueue(files);
|
|
2196
|
+
console.log(this.uploader.queue);
|
|
2278
2197
|
}
|
|
2279
2198
|
else {
|
|
2280
|
-
|
|
2281
|
-
|
|
2199
|
+
const element = this.options.value.file ?? this.options.value;
|
|
2200
|
+
var bytes = new Uint8Array(element.bytes);
|
|
2201
|
+
var base64 = btoa(String.fromCharCode(null, bytes));
|
|
2202
|
+
this.fileLikeObject = {
|
|
2203
|
+
name: element.nameWithExtension,
|
|
2204
|
+
type: element.mimeType,
|
|
2205
|
+
rawFile: base64
|
|
2206
|
+
};
|
|
2207
|
+
this.file = element;
|
|
2208
|
+
let file = this.fileLikeObject;
|
|
2209
|
+
file.url = element.fileURL;
|
|
2210
|
+
this.uploader.addToQueue([file]);
|
|
2211
|
+
if (!this.options.value.file) {
|
|
2212
|
+
this.fileUploadModel = new FileUploadModel();
|
|
2213
|
+
this.fileUploadModel.file = this.options.value;
|
|
2214
|
+
}
|
|
2215
|
+
else
|
|
2216
|
+
this.fileUploadModel = this.options.value;
|
|
2217
|
+
this.options.value = this.fileUploadModel;
|
|
2282
2218
|
}
|
|
2219
|
+
this.uploader.queue.forEach((element) => {
|
|
2220
|
+
element.progress = 100;
|
|
2221
|
+
});
|
|
2283
2222
|
}
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
.
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
this.acceptedTypeArray = allMimeTypes.filter(type => type.trim());
|
|
2292
|
-
const mimeTypeMap = this.getMimeTypeMap();
|
|
2293
|
-
for (const type of this.acceptedTypeArray) {
|
|
2294
|
-
const displayType = mimeTypeMap[type];
|
|
2295
|
-
if (displayType && !this.toolTipTypeArray.includes(displayType)) {
|
|
2296
|
-
this.toolTipTypeArray.push(displayType);
|
|
2223
|
+
if (this.options.labelKey != null && this.options.labelKey != '')
|
|
2224
|
+
this.options.labelValue = this.UtilityService.getResourceValue(this.options.labelKey);
|
|
2225
|
+
if (this.options.fileUploadAcceptsTypes != null &&
|
|
2226
|
+
this.options.fileUploadAcceptsTypes.length > 0) {
|
|
2227
|
+
for (let index = 0; index < this.options.fileUploadAcceptsTypes.length; index++) {
|
|
2228
|
+
const Type = this.options.fileUploadAcceptsTypes[index];
|
|
2229
|
+
this.acceptedType = this.acceptedType + Type + ',';
|
|
2297
2230
|
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2231
|
+
this.acceptedTypeArray = this.acceptedType.split(',');
|
|
2232
|
+
this.acceptedTypeArray = this.acceptedTypeArray.filter((value) => value != '');
|
|
2233
|
+
for (let index = 0; index < this.acceptedTypeArray.length; index++) {
|
|
2234
|
+
const element = this.acceptedTypeArray[index];
|
|
2235
|
+
for (let index = 0; index < this.acceptedTypeArray.length; index++) {
|
|
2236
|
+
const element = this.acceptedTypeArray[index];
|
|
2237
|
+
switch (element) {
|
|
2238
|
+
case 'application/pdf':
|
|
2239
|
+
if (!this.toolTipTypeArray.includes('PDF'))
|
|
2240
|
+
this.toolTipTypeArray.push('PDF');
|
|
2241
|
+
break;
|
|
2242
|
+
case 'application/msword':
|
|
2243
|
+
if (!this.toolTipTypeArray.includes('Word'))
|
|
2244
|
+
this.toolTipTypeArray.push('Word');
|
|
2245
|
+
break;
|
|
2246
|
+
case 'application/vnd.openxmlformats-officedocument.wordprocessingml.document':
|
|
2247
|
+
if (!this.toolTipTypeArray.includes('Word'))
|
|
2248
|
+
this.toolTipTypeArray.push('Word');
|
|
2249
|
+
break;
|
|
2250
|
+
case 'application/vnd.ms-excel':
|
|
2251
|
+
if (!this.toolTipTypeArray.includes('Excel'))
|
|
2252
|
+
this.toolTipTypeArray.push('Excel');
|
|
2253
|
+
break;
|
|
2254
|
+
case 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet':
|
|
2255
|
+
if (!this.toolTipTypeArray.includes('Excel'))
|
|
2256
|
+
this.toolTipTypeArray.push('Excel');
|
|
2257
|
+
break;
|
|
2258
|
+
case 'application/vnd.ms-powerpoint':
|
|
2259
|
+
if (!this.toolTipTypeArray.includes('PowerPoint'))
|
|
2260
|
+
this.toolTipTypeArray.push('PowerPoint');
|
|
2261
|
+
break;
|
|
2262
|
+
case 'application/vnd.openxmlformats-officedocument.presentationml.presentation':
|
|
2263
|
+
if (!this.toolTipTypeArray.includes('PowerPoint'))
|
|
2264
|
+
this.toolTipTypeArray.push('PowerPoint');
|
|
2265
|
+
break;
|
|
2266
|
+
case 'image/png':
|
|
2267
|
+
if (!this.toolTipTypeArray.includes('PNG'))
|
|
2268
|
+
this.toolTipTypeArray.push('PNG');
|
|
2269
|
+
break;
|
|
2270
|
+
case 'image/bmp':
|
|
2271
|
+
if (!this.toolTipTypeArray.includes('BMP'))
|
|
2272
|
+
this.toolTipTypeArray.push('BMP');
|
|
2273
|
+
break;
|
|
2274
|
+
case 'image/jpeg':
|
|
2275
|
+
if (!this.toolTipTypeArray.includes('JPEG'))
|
|
2276
|
+
this.toolTipTypeArray.push('JPEG');
|
|
2277
|
+
break;
|
|
2278
|
+
case 'application/zip':
|
|
2279
|
+
if (!this.toolTipTypeArray.includes('ZIP'))
|
|
2280
|
+
this.toolTipTypeArray.push('ZIP');
|
|
2281
|
+
break;
|
|
2282
|
+
case 'application/x-rar-compressed':
|
|
2283
|
+
if (!this.toolTipTypeArray.includes('RAR'))
|
|
2284
|
+
this.toolTipTypeArray.push('RAR');
|
|
2285
|
+
break;
|
|
2286
|
+
case 'video/mp4':
|
|
2287
|
+
if (!this.toolTipTypeArray.includes('MP4'))
|
|
2288
|
+
this.toolTipTypeArray.push('MP4');
|
|
2289
|
+
break;
|
|
2290
|
+
case 'video/avi':
|
|
2291
|
+
if (!this.toolTipTypeArray.includes('AVI'))
|
|
2292
|
+
this.toolTipTypeArray.push('AVI');
|
|
2293
|
+
break;
|
|
2294
|
+
case 'video/quicktime':
|
|
2295
|
+
if (!this.toolTipTypeArray.includes('MOV'))
|
|
2296
|
+
this.toolTipTypeArray.push('MOV');
|
|
2297
|
+
break;
|
|
2298
|
+
case 'video/mpeg':
|
|
2299
|
+
if (!this.toolTipTypeArray.includes('MPEG'))
|
|
2300
|
+
this.toolTipTypeArray.push('MPEG');
|
|
2301
|
+
break;
|
|
2302
|
+
case 'audio/mpeg':
|
|
2303
|
+
if (!this.toolTipTypeArray.includes('MP3'))
|
|
2304
|
+
this.toolTipTypeArray.push('MP3');
|
|
2305
|
+
break;
|
|
2306
|
+
case 'video/x-flv':
|
|
2307
|
+
if (!this.toolTipTypeArray.includes('FLV'))
|
|
2308
|
+
this.toolTipTypeArray.push('FLV');
|
|
2309
|
+
break;
|
|
2310
|
+
case 'video/x-ms-wmv':
|
|
2311
|
+
if (!this.toolTipTypeArray.includes('WMV'))
|
|
2312
|
+
this.toolTipTypeArray.push('WMV');
|
|
2313
|
+
break;
|
|
2314
|
+
case 'image/svg+xml':
|
|
2315
|
+
if (!this.toolTipTypeArray.includes('SVG'))
|
|
2316
|
+
this.toolTipTypeArray.push('SVG');
|
|
2317
|
+
break;
|
|
2318
|
+
case 'text/plain':
|
|
2319
|
+
if (!this.toolTipTypeArray.includes('Txt'))
|
|
2320
|
+
this.toolTipTypeArray.push('Txt');
|
|
2321
|
+
break;
|
|
2322
|
+
case 'application/BN':
|
|
2323
|
+
if (!this.toolTipTypeArray.includes('License'))
|
|
2324
|
+
this.toolTipTypeArray.push('License');
|
|
2325
|
+
break;
|
|
2326
|
+
default:
|
|
2327
|
+
break;
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
this.validationMessage =
|
|
2332
|
+
this.validationMessage +
|
|
2333
|
+
`${this.UtilityService.getResourceValue('Extensions')} (${this.toolTipTypeArray}) `;
|
|
2336
2334
|
}
|
|
2337
2335
|
if (this.options.fileMaxSizeInMB > 0) {
|
|
2338
|
-
|
|
2336
|
+
this.validationMessage =
|
|
2337
|
+
this.validationMessage +
|
|
2338
|
+
`<br /> ${this.UtilityService.getResourceValue('FileMaxSizeInMB') + this.options.fileMaxSizeInMB} `;
|
|
2339
2339
|
}
|
|
2340
2340
|
if (this.options.minNoOfFiles > 0) {
|
|
2341
|
-
|
|
2341
|
+
this.validationMessage =
|
|
2342
|
+
this.validationMessage +
|
|
2343
|
+
`<br /> ${this.UtilityService.getResourceValue('MinFileCountValidationKey') + this.options.minNoOfFiles}`;
|
|
2342
2344
|
}
|
|
2343
2345
|
if (this.options.maxNoOfFiles > 0) {
|
|
2344
|
-
|
|
2346
|
+
this.validationMessage =
|
|
2347
|
+
this.validationMessage +
|
|
2348
|
+
`<br /> ${this.UtilityService.getResourceValue('MaxFileCountValidationKey') + this.options.maxNoOfFiles}`;
|
|
2349
|
+
}
|
|
2350
|
+
if (this.options.fileUploadAcceptsTypes != null &&
|
|
2351
|
+
this.options.fileUploadAcceptsTypes.length > 0) {
|
|
2345
2352
|
}
|
|
2346
|
-
this.validationMessage = messages.join(' <br/> ');
|
|
2347
|
-
}
|
|
2348
|
-
setupFormControl() {
|
|
2349
2353
|
this.group.addControl(this.options.name, new FormControl(''));
|
|
2350
|
-
this.fileUploadFormControl = this.group.controls[this.options.name];
|
|
2351
|
-
this.
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
setupValidators() {
|
|
2357
|
-
if (this.options.customValidation?.length) {
|
|
2358
|
-
for (const validation of this.options.customValidation) {
|
|
2359
|
-
this.validationRules.push(validation.functionBody);
|
|
2354
|
+
this.fileUploadFormControl = this.group.controls[this.options.name]; // new FormControl('',validationRules);
|
|
2355
|
+
if (this.options.customValidation.length > 0) {
|
|
2356
|
+
let Validations = this.options.customValidation;
|
|
2357
|
+
for (let index = 0; index < Validations.length; index++) {
|
|
2358
|
+
const Validation = Validations[index];
|
|
2359
|
+
this.validationRules.push(Validation.functionBody);
|
|
2360
2360
|
}
|
|
2361
2361
|
}
|
|
2362
|
+
if (this.options.isMultipleFile && this.options.maxNoOfFiles > 0) {
|
|
2363
|
+
this.validationCountMessage = `${this.UtilityService.getResourceValue('MaxFilesCount')} : ${this.options.maxNoOfFiles}`;
|
|
2364
|
+
}
|
|
2362
2365
|
if (this.options.isRequired) {
|
|
2363
2366
|
this.validationRules.push(Validators.required);
|
|
2364
2367
|
}
|
|
2365
|
-
}
|
|
2366
|
-
setupCountMessage() {
|
|
2367
|
-
if (this.options.isMultipleFile && this.options.maxNoOfFiles > 0) {
|
|
2368
|
-
this.validationCountMessage = `${this.utilityService.getResourceValue('MaxFilesCount')} : ${this.options.maxNoOfFiles}`;
|
|
2369
|
-
}
|
|
2370
|
-
}
|
|
2371
|
-
applyValidatorsAndState() {
|
|
2372
2368
|
this.fileUploadFormControl.setValidators(this.validationRules);
|
|
2373
|
-
|
|
2374
|
-
this.fileUploadFormControl.setAsyncValidators(this.validationRulesAsync);
|
|
2375
|
-
}
|
|
2369
|
+
this.fileUploadFormControl.setAsyncValidators(this.validationRulesasync);
|
|
2376
2370
|
if (this.options.isDisabled) {
|
|
2377
2371
|
this.fileUploadFormControl.disable();
|
|
2378
2372
|
}
|
|
2379
|
-
|
|
2380
|
-
setupSubscriptions() {
|
|
2381
|
-
this.multipleFileUploadControlHost.ngSubmit.subscribe(() => {
|
|
2373
|
+
this.MultipleFileUplaodControlHost.ngSubmit.subscribe((value) => {
|
|
2382
2374
|
this.group.markAllAsTouched();
|
|
2383
2375
|
this.markAllAsTouched = true;
|
|
2384
2376
|
});
|
|
2377
|
+
this.fileUploadFormControl.setValue(this.options.value);
|
|
2385
2378
|
}
|
|
2386
2379
|
ngAfterViewInit() {
|
|
2387
|
-
this.
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
return;
|
|
2392
|
-
}
|
|
2393
|
-
const element = document.getElementById(this.options.name);
|
|
2394
|
-
if (element) {
|
|
2395
|
-
for (const attribute of this.options.attributeList) {
|
|
2396
|
-
element.setAttribute(attribute.key, attribute.value);
|
|
2380
|
+
if (this.options.attributeList != null) {
|
|
2381
|
+
var element = document.getElementById(this.options.name);
|
|
2382
|
+
for (let index = 0; index < this.options.attributeList.length; index++) {
|
|
2383
|
+
element.setAttribute(this.options.attributeList[index].key, this.options.attributeList[index].value);
|
|
2397
2384
|
}
|
|
2398
2385
|
}
|
|
2399
2386
|
}
|
|
2400
2387
|
showGlobalError() {
|
|
2401
2388
|
this.controlUtility.showGlobalError();
|
|
2402
2389
|
}
|
|
2403
|
-
getErrorValidation(
|
|
2390
|
+
getErrorValidation(ErrorList) {
|
|
2404
2391
|
if (this.markAllAsTouched && this.group.invalid) {
|
|
2405
2392
|
this.showGlobalError();
|
|
2406
2393
|
this.markAllAsTouched = false;
|
|
2407
2394
|
}
|
|
2408
|
-
|
|
2409
|
-
for (const error of errorList) {
|
|
2410
|
-
if (error.key === 'InvalidFiles') {
|
|
2411
|
-
return error.value;
|
|
2412
|
-
}
|
|
2413
|
-
}
|
|
2414
|
-
}
|
|
2415
|
-
return this.controlUtility.getErrorValidationMassage(errorList, this.group, this.options);
|
|
2395
|
+
return this.controlUtility.getErrorValidationMassage(ErrorList, this.group, this.options);
|
|
2416
2396
|
}
|
|
2417
2397
|
fileOverAnother(event) {
|
|
2418
|
-
this.hasAnotherDropZoneOver =
|
|
2398
|
+
this.hasAnotherDropZoneOver = event;
|
|
2419
2399
|
}
|
|
2420
2400
|
isHideInput() {
|
|
2421
2401
|
if (this.options.isMultipleFile) {
|
|
2422
|
-
|
|
2423
|
-
this.options.maxNoOfFiles
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
}
|
|
2427
|
-
onFileChange() {
|
|
2428
|
-
this.validateFileConstraints();
|
|
2429
|
-
const fileProcessingResult = this.processNewlyAddedFiles();
|
|
2430
|
-
this.handleFileValidationResults(fileProcessingResult);
|
|
2431
|
-
this.processValidFilesForUpload();
|
|
2432
|
-
}
|
|
2433
|
-
processNewlyAddedFiles() {
|
|
2434
|
-
const addedQueue = this.getNewlyAddedFiles();
|
|
2435
|
-
const validationResult = this.validateFilesInQueue(addedQueue);
|
|
2436
|
-
return {
|
|
2437
|
-
validFiles: addedQueue.filter(file => !validationResult.invalidFiles.includes(file)),
|
|
2438
|
-
invalidFiles: validationResult.invalidFiles,
|
|
2439
|
-
errors: validationResult.errors
|
|
2440
|
-
};
|
|
2441
|
-
}
|
|
2442
|
-
getNewlyAddedFiles() {
|
|
2443
|
-
return this.uploader.queue.filter((obj) => obj['some']?.lastModified != null);
|
|
2444
|
-
}
|
|
2445
|
-
validateFilesInQueue(fileQueue) {
|
|
2446
|
-
const validationErrors = [];
|
|
2447
|
-
const invalidFiles = [];
|
|
2448
|
-
const processedDuplicateNames = new Set();
|
|
2449
|
-
for (const element of fileQueue) {
|
|
2450
|
-
const file = element.file;
|
|
2451
|
-
if (!file)
|
|
2452
|
-
continue;
|
|
2453
|
-
const fileValidation = this.validateSingleFile(file, element, processedDuplicateNames);
|
|
2454
|
-
if (!fileValidation.isValid) {
|
|
2455
|
-
invalidFiles.push(element);
|
|
2456
|
-
validationErrors.push(...fileValidation.errors);
|
|
2457
|
-
}
|
|
2458
|
-
}
|
|
2459
|
-
return {
|
|
2460
|
-
isValid: invalidFiles.length === 0,
|
|
2461
|
-
errors: validationErrors,
|
|
2462
|
-
invalidFiles
|
|
2463
|
-
};
|
|
2464
|
-
}
|
|
2465
|
-
validateSingleFile(file, element, processedDuplicateNames) {
|
|
2466
|
-
const errors = [];
|
|
2467
|
-
const sizeValid = this.validateIndividualFileSize(file);
|
|
2468
|
-
const typeValid = this.validateIndividualFileType(file);
|
|
2469
|
-
const nameValid = this.validateDuplicateFileName(file, element);
|
|
2470
|
-
if (!sizeValid) {
|
|
2471
|
-
errors.push(this.createFileSizeErrorMessage(file.name));
|
|
2472
|
-
}
|
|
2473
|
-
if (!typeValid) {
|
|
2474
|
-
errors.push(this.createFileTypeErrorMessage(file.name));
|
|
2475
|
-
}
|
|
2476
|
-
if (!nameValid) {
|
|
2477
|
-
const duplicateError = this.createDuplicateFileErrorMessage(file.name, processedDuplicateNames);
|
|
2478
|
-
if (duplicateError) {
|
|
2479
|
-
errors.push(duplicateError);
|
|
2480
|
-
}
|
|
2481
|
-
}
|
|
2482
|
-
return {
|
|
2483
|
-
isValid: sizeValid && typeValid && nameValid,
|
|
2484
|
-
errors,
|
|
2485
|
-
invalidFiles: []
|
|
2486
|
-
};
|
|
2487
|
-
}
|
|
2488
|
-
createFileSizeErrorMessage(fileName) {
|
|
2489
|
-
return this.utilityService.getResourceValue('FileExceedsMaxSize')
|
|
2490
|
-
.replace('{fileName}', fileName)
|
|
2491
|
-
.replace('{maxSize}', this.options.fileMaxSizeInMB.toString());
|
|
2492
|
-
}
|
|
2493
|
-
createFileTypeErrorMessage(fileName) {
|
|
2494
|
-
return this.utilityService.getResourceValue('FileTypeNotAccepted')
|
|
2495
|
-
.replace('{fileName}', fileName);
|
|
2496
|
-
}
|
|
2497
|
-
createDuplicateFileErrorMessage(fileName, processedDuplicateNames) {
|
|
2498
|
-
const fileNameLower = fileName.toLowerCase();
|
|
2499
|
-
if (processedDuplicateNames.has(fileNameLower)) {
|
|
2500
|
-
return null;
|
|
2501
|
-
}
|
|
2502
|
-
processedDuplicateNames.add(fileNameLower);
|
|
2503
|
-
let duplicateErrorMsg = this.utilityService.getResourceValue('DuplicateFileName');
|
|
2504
|
-
if (!duplicateErrorMsg || duplicateErrorMsg === 'DuplicateFileName') {
|
|
2505
|
-
duplicateErrorMsg = `File '{fileName}' already exists. Please choose a different file or rename it.`;
|
|
2506
|
-
}
|
|
2507
|
-
return duplicateErrorMsg.replace('{fileName}', fileName);
|
|
2508
|
-
}
|
|
2509
|
-
handleFileValidationResults(result) {
|
|
2510
|
-
if (result.invalidFiles.length > 0) {
|
|
2511
|
-
this.removeInvalidFiles(result.invalidFiles);
|
|
2512
|
-
}
|
|
2513
|
-
if (result.errors.length > 0) {
|
|
2514
|
-
this.showValidationErrors(result.errors);
|
|
2515
|
-
}
|
|
2516
|
-
}
|
|
2517
|
-
processValidFilesForUpload() {
|
|
2518
|
-
const filesArray = [];
|
|
2519
|
-
const validQueue = this.getNewlyAddedFiles();
|
|
2520
|
-
for (const element of validQueue) {
|
|
2521
|
-
const file = element.file;
|
|
2522
|
-
if (!file)
|
|
2523
|
-
continue;
|
|
2524
|
-
if (this.shouldUseAsyncUpload(element)) {
|
|
2525
|
-
this.handleAsyncFileUpload(element, filesArray);
|
|
2526
|
-
}
|
|
2527
|
-
else {
|
|
2528
|
-
this.handleSyncFileUpload(file, filesArray);
|
|
2529
|
-
}
|
|
2530
|
-
}
|
|
2531
|
-
}
|
|
2532
|
-
shouldUseAsyncUpload(element) {
|
|
2533
|
-
return this.options.isUploadFileAsync && !element._file['iD_GUID'];
|
|
2534
|
-
}
|
|
2535
|
-
validateFileConstraints() {
|
|
2536
|
-
if (this.options.isMultipleFile) {
|
|
2537
|
-
if (!this.validateMinFileCount() || !this.validateMaxFileCount() || !this.validateTotalFileSize()) {
|
|
2538
|
-
return false;
|
|
2402
|
+
if (this.options.maxNoOfFiles != null &&
|
|
2403
|
+
this.options.maxNoOfFiles > 0 &&
|
|
2404
|
+
this.options.maxNoOfFiles == this.uploader.queue.length) {
|
|
2405
|
+
return true;
|
|
2539
2406
|
}
|
|
2540
2407
|
}
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
if (this.options.minNoOfFiles > 0 && this.options.minNoOfFiles > this.uploader.queue.length) {
|
|
2545
|
-
const minFileMsg = this.utilityService.getResourceValue('MinimumFilesRequired')
|
|
2546
|
-
.replace('{count}', this.options.minNoOfFiles.toString());
|
|
2547
|
-
this.showFileCountError('MinFileCountValidationKey', minFileMsg);
|
|
2548
|
-
return false;
|
|
2549
|
-
}
|
|
2550
|
-
return true;
|
|
2551
|
-
}
|
|
2552
|
-
validateMaxFileCount() {
|
|
2553
|
-
if (this.options.maxNoOfFiles > 0 && this.options.maxNoOfFiles < this.uploader.queue.length) {
|
|
2554
|
-
const maxFileMsg = this.utilityService.getResourceValue('MaximumFilesExceeded') ||
|
|
2555
|
-
`Maximum {maxCount} files allowed. You have selected {currentCount} files.`;
|
|
2556
|
-
const finalMsg = maxFileMsg
|
|
2557
|
-
.replace('{maxCount}', this.options.maxNoOfFiles.toString())
|
|
2558
|
-
.replace('{currentCount}', this.uploader.queue.length.toString());
|
|
2559
|
-
this.showFileCountError('MaxFileCountValidationKey', finalMsg);
|
|
2560
|
-
return false;
|
|
2561
|
-
}
|
|
2562
|
-
return true;
|
|
2563
|
-
}
|
|
2564
|
-
showFileCountError(errorKey, message) {
|
|
2565
|
-
const currentErrors = this.fileUploadFormControl.errors || {};
|
|
2566
|
-
// Preserve existing errors and add the new one
|
|
2567
|
-
const newErrors = { ...currentErrors };
|
|
2568
|
-
newErrors[errorKey] = message;
|
|
2569
|
-
this.fileUploadFormControl.setErrors(newErrors);
|
|
2570
|
-
this.fileUploadFormControl.markAsTouched();
|
|
2571
|
-
// Force the form control to be invalid
|
|
2572
|
-
this.fileUploadFormControl.markAsDirty();
|
|
2573
|
-
// Ensure the error persists
|
|
2574
|
-
this.forceValidationErrorDisplay(errorKey, message);
|
|
2575
|
-
}
|
|
2576
|
-
forceValidationErrorDisplay(errorKey, message) {
|
|
2577
|
-
// Force the validation error to persist by re-applying it after a short delay
|
|
2578
|
-
setTimeout(() => {
|
|
2579
|
-
const currentErrors = this.fileUploadFormControl.errors || {};
|
|
2580
|
-
if (!currentErrors[errorKey]) {
|
|
2581
|
-
const newErrors = { ...currentErrors };
|
|
2582
|
-
newErrors[errorKey] = message;
|
|
2583
|
-
this.fileUploadFormControl.setErrors(newErrors);
|
|
2584
|
-
this.fileUploadFormControl.markAsTouched();
|
|
2585
|
-
this.fileUploadFormControl.markAsDirty();
|
|
2586
|
-
}
|
|
2587
|
-
}, 100);
|
|
2588
|
-
}
|
|
2589
|
-
clearFileCountError(errorKey) {
|
|
2590
|
-
const currentErrors = this.fileUploadFormControl.errors;
|
|
2591
|
-
if (currentErrors && currentErrors[errorKey]) {
|
|
2592
|
-
delete currentErrors[errorKey];
|
|
2593
|
-
if (Object.keys(currentErrors).length === 0) {
|
|
2594
|
-
this.fileUploadFormControl.setErrors(null);
|
|
2595
|
-
}
|
|
2596
|
-
else {
|
|
2597
|
-
this.fileUploadFormControl.setErrors(currentErrors);
|
|
2598
|
-
}
|
|
2599
|
-
}
|
|
2600
|
-
}
|
|
2601
|
-
validateTotalFileSize() {
|
|
2602
|
-
if (this.options.maxSizeForAllFilesInMB > 0) {
|
|
2603
|
-
const totalSize = this.uploader.queue.reduce((sum, element) => sum + element.file.size, 0);
|
|
2604
|
-
const maxSizeBytes = this.options.maxSizeForAllFilesInMB * this.BYTES_TO_MB;
|
|
2605
|
-
if (totalSize > maxSizeBytes) {
|
|
2606
|
-
this.showTotalSizeError();
|
|
2607
|
-
return false;
|
|
2608
|
-
}
|
|
2609
|
-
}
|
|
2610
|
-
return true;
|
|
2611
|
-
}
|
|
2612
|
-
showTotalSizeError() {
|
|
2613
|
-
const totalSizeMsg = this.utilityService.getResourceValue('TotalFileSizeExceeded')
|
|
2614
|
-
.replace('{maxSize}', this.options.maxSizeForAllFilesInMB.toString());
|
|
2615
|
-
const currentErrors = this.fileUploadFormControl.errors || {};
|
|
2616
|
-
// Preserve existing errors and add the new one
|
|
2617
|
-
const newErrors = { ...currentErrors };
|
|
2618
|
-
newErrors['MaxSizeForAllFilesInMB'] = totalSizeMsg;
|
|
2619
|
-
this.fileUploadFormControl.setErrors(newErrors);
|
|
2620
|
-
this.fileUploadFormControl.markAsTouched();
|
|
2621
|
-
// Force the form control to be invalid
|
|
2622
|
-
this.fileUploadFormControl.markAsDirty();
|
|
2623
|
-
// Ensure the error persists
|
|
2624
|
-
this.forceValidationErrorDisplay('MaxSizeForAllFilesInMB', totalSizeMsg);
|
|
2625
|
-
}
|
|
2626
|
-
validateFileSize(file) {
|
|
2627
|
-
const maxFileSize = this.options.fileMaxSizeInMB * this.BYTES_TO_MB;
|
|
2628
|
-
if (file.size > maxFileSize) {
|
|
2629
|
-
this.setFormControlError('FileMaxSizeInMB', `${this.options.fileMaxSizeInMB}MB`);
|
|
2630
|
-
return false;
|
|
2631
|
-
}
|
|
2632
|
-
return true;
|
|
2633
|
-
}
|
|
2634
|
-
validateFileType(file) {
|
|
2635
|
-
if (this.options.fileUploadAcceptsTypes?.length) {
|
|
2636
|
-
const fileType = file.type;
|
|
2637
|
-
const isAccepted = this.acceptedTypeArray.some(type => type.toLowerCase() === fileType.toLowerCase());
|
|
2638
|
-
if (!isAccepted) {
|
|
2639
|
-
this.setFormControlError('ToolTipTypeError', this.toolTipTypeArray);
|
|
2640
|
-
return false;
|
|
2408
|
+
else {
|
|
2409
|
+
if (this.uploader.queue.length > 0) {
|
|
2410
|
+
return true;
|
|
2641
2411
|
}
|
|
2642
2412
|
}
|
|
2643
|
-
return
|
|
2644
|
-
}
|
|
2645
|
-
validateIndividualFileSize(file) {
|
|
2646
|
-
const maxFileSize = this.options.fileMaxSizeInMB * this.BYTES_TO_MB;
|
|
2647
|
-
return file.size <= maxFileSize;
|
|
2648
|
-
}
|
|
2649
|
-
validateIndividualFileType(file) {
|
|
2650
|
-
if (!this.options.fileUploadAcceptsTypes?.length) {
|
|
2651
|
-
return true;
|
|
2652
|
-
}
|
|
2653
|
-
const fileType = file.type?.toLowerCase();
|
|
2654
|
-
if (!fileType) {
|
|
2655
|
-
return false;
|
|
2656
|
-
}
|
|
2657
|
-
return this.acceptedTypeArray.some(type => type.toLowerCase() === fileType);
|
|
2413
|
+
return false;
|
|
2658
2414
|
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
});
|
|
2669
|
-
if (duplicateExists) {
|
|
2670
|
-
return false;
|
|
2671
|
-
}
|
|
2672
|
-
if (this.options.value) {
|
|
2673
|
-
const uploadedFiles = Array.isArray(this.options.value) ? this.options.value : [this.options.value];
|
|
2674
|
-
const duplicateInUploaded = uploadedFiles.some(uploadedFile => {
|
|
2675
|
-
const uploadedFileName = uploadedFile?.fileName || uploadedFile?.name;
|
|
2676
|
-
return uploadedFileName && uploadedFileName.toLowerCase() === currentFileName;
|
|
2415
|
+
onFileChange() {
|
|
2416
|
+
let FilesArray = [];
|
|
2417
|
+
if (this.options.isMultipleFile &&
|
|
2418
|
+
this.options.minNoOfFiles != null &&
|
|
2419
|
+
this.options.minNoOfFiles > 0 &&
|
|
2420
|
+
this.options.minNoOfFiles > this.uploader.queue.length) {
|
|
2421
|
+
const formControl = this.fileUploadFormControl;
|
|
2422
|
+
formControl.setErrors({
|
|
2423
|
+
MinFileCountValidationKey: this.options.minNoOfFiles
|
|
2677
2424
|
});
|
|
2678
|
-
|
|
2425
|
+
formControl.markAsTouched();
|
|
2426
|
+
this.uploader.queue = [];
|
|
2427
|
+
return;
|
|
2679
2428
|
}
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
const
|
|
2685
|
-
|
|
2686
|
-
this.
|
|
2687
|
-
}
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
showValidationErrors(errors) {
|
|
2691
|
-
if (errors.length === 0)
|
|
2429
|
+
if (this.options.isMultipleFile &&
|
|
2430
|
+
this.options.maxNoOfFiles != null &&
|
|
2431
|
+
this.options.maxNoOfFiles > 0 &&
|
|
2432
|
+
this.options.maxNoOfFiles < this.uploader.queue.length) {
|
|
2433
|
+
const formControl = this.fileUploadFormControl;
|
|
2434
|
+
formControl.setErrors({
|
|
2435
|
+
MaxFileCountValidationKey: this.options.maxNoOfFiles
|
|
2436
|
+
});
|
|
2437
|
+
formControl.markAsTouched();
|
|
2438
|
+
this.uploader.queue = [];
|
|
2692
2439
|
return;
|
|
2693
|
-
|
|
2694
|
-
this.
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
clearInvalidFilesError() {
|
|
2713
|
-
const currentErrors = this.fileUploadFormControl.errors;
|
|
2714
|
-
if (currentErrors && currentErrors['InvalidFiles']) {
|
|
2715
|
-
delete currentErrors['InvalidFiles'];
|
|
2716
|
-
if (Object.keys(currentErrors).length === 0) {
|
|
2717
|
-
this.fileUploadFormControl.setErrors(null);
|
|
2440
|
+
}
|
|
2441
|
+
if (this.options.isMultipleFile &&
|
|
2442
|
+
this.options.maxSizeForAllFilesInMB != null &&
|
|
2443
|
+
this.options.maxSizeForAllFilesInMB > 0) {
|
|
2444
|
+
let AllSizeFile = 0;
|
|
2445
|
+
for (let index = 0; index < this.uploader.queue.length; index++) {
|
|
2446
|
+
const element = this.uploader.queue[index];
|
|
2447
|
+
const file = element.file;
|
|
2448
|
+
AllSizeFile = AllSizeFile + file.size;
|
|
2449
|
+
}
|
|
2450
|
+
const MaxSizeForAllFiles = this.options.maxSizeForAllFilesInMB * 1000 * 1000;
|
|
2451
|
+
if (AllSizeFile > MaxSizeForAllFiles) {
|
|
2452
|
+
const formControl = this.fileUploadFormControl;
|
|
2453
|
+
formControl.setErrors({
|
|
2454
|
+
MaxSizeForAllFilesInMB: this.options.maxSizeForAllFilesInMB + 'MB'
|
|
2455
|
+
});
|
|
2456
|
+
formControl.markAsTouched();
|
|
2457
|
+
this.uploader.queue = [];
|
|
2458
|
+
return;
|
|
2718
2459
|
}
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2738
|
-
|
|
2739
|
-
|
|
2740
|
-
this.
|
|
2460
|
+
}
|
|
2461
|
+
let AddedQueue = this.uploader.queue.filter((obj) => obj['some'].lastModified != null);
|
|
2462
|
+
for (let index = 0; index < AddedQueue.length; index++) {
|
|
2463
|
+
const element = AddedQueue[index];
|
|
2464
|
+
const file = element.file;
|
|
2465
|
+
const maxFileSize = this.options.fileMaxSizeInMB * 1000 * 1000;
|
|
2466
|
+
if (file) {
|
|
2467
|
+
const fileType = file.type;
|
|
2468
|
+
if (file.size > maxFileSize) {
|
|
2469
|
+
const formControl = this.fileUploadFormControl;
|
|
2470
|
+
formControl.setErrors({
|
|
2471
|
+
FileMaxSizeInMB: this.options.fileMaxSizeInMB + 'M'
|
|
2472
|
+
});
|
|
2473
|
+
formControl.markAsTouched();
|
|
2474
|
+
this.uploader.queue = [];
|
|
2475
|
+
return;
|
|
2476
|
+
}
|
|
2477
|
+
if (this.options.fileUploadAcceptsTypes != null &&
|
|
2478
|
+
this.options.fileUploadAcceptsTypes.length > 0 &&
|
|
2479
|
+
!(this.acceptedTypeArray.includes(fileType.toUpperCase()) ||
|
|
2480
|
+
this.acceptedTypeArray.includes(fileType.toLowerCase()))) {
|
|
2481
|
+
const formControl = this.fileUploadFormControl;
|
|
2482
|
+
formControl.setErrors({ ToolTipTypeError: this.toolTipTypeArray });
|
|
2483
|
+
formControl.markAsTouched();
|
|
2484
|
+
this.uploader.queue = [];
|
|
2485
|
+
return;
|
|
2741
2486
|
}
|
|
2742
|
-
|
|
2743
|
-
this.
|
|
2487
|
+
if (this.options.isUploadFileAsync && !element._file['iD_GUID']) {
|
|
2488
|
+
this.fileUploadService.uploadFile(element._file).subscribe({
|
|
2489
|
+
next: (event) => {
|
|
2490
|
+
let queueIndex = this.uploader.queue.findIndex((file) => file == element);
|
|
2491
|
+
if (event.type === HttpEventType.UploadProgress) {
|
|
2492
|
+
let value = Math.round((100 * event.loaded) / event.total);
|
|
2493
|
+
this.uploader.queue[queueIndex].progress = value >= 95 ? 95 : value;
|
|
2494
|
+
}
|
|
2495
|
+
else if (event.type === HttpEventType.Response) {
|
|
2496
|
+
this.uploader.queue[queueIndex].progress = 100;
|
|
2497
|
+
let fileID = event.body.val;
|
|
2498
|
+
this.uploader.queue[queueIndex]._file['iD_GUID'] = fileID;
|
|
2499
|
+
this.uploader.queue[queueIndex]._file['isNew'] = true;
|
|
2500
|
+
let AddedFile = {
|
|
2501
|
+
iD_GUID: fileID,
|
|
2502
|
+
fileName: this.uploader.queue[queueIndex]._file['name'],
|
|
2503
|
+
fileType: this.uploader.queue[queueIndex]._file['type'],
|
|
2504
|
+
isNew: true
|
|
2505
|
+
};
|
|
2506
|
+
if (this.options.isMultipleFile == false) {
|
|
2507
|
+
this.fileUploadModel = new FileUploadModel();
|
|
2508
|
+
this.fileUploadModel.file = AddedFile;
|
|
2509
|
+
this.fileUploadFormControl.setValue(this.fileUploadModel);
|
|
2510
|
+
this.group.get(this.options.name).setValue(this.fileUploadModel);
|
|
2511
|
+
//Use this line to enable two way binding.
|
|
2512
|
+
this.options.value = this.fileUploadModel;
|
|
2513
|
+
}
|
|
2514
|
+
else {
|
|
2515
|
+
FilesArray.push(AddedFile);
|
|
2516
|
+
this.multipleFileUploadModel.uploadedFiles = FilesArray;
|
|
2517
|
+
if (this.options.value != null && this.options.value != undefined) {
|
|
2518
|
+
if (this.options.value.correlationID_GUID == null) {
|
|
2519
|
+
this.multipleFileUploadModel.removedFiles = [];
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
this.multipleFileUploadModel.correlationID_GUID =
|
|
2523
|
+
this.options.value?.correlationID_GUID;
|
|
2524
|
+
this.fileUploadFormControl.setValue(this.multipleFileUploadModel);
|
|
2525
|
+
this.group.get(this.options.name).setValue(this.multipleFileUploadModel);
|
|
2526
|
+
//Use this line to enable two way binding.
|
|
2527
|
+
this.options.value = this.multipleFileUploadModel;
|
|
2528
|
+
this.isUploadComplete.emit(true);
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
});
|
|
2533
|
+
}
|
|
2534
|
+
else {
|
|
2535
|
+
let reader = new FileReader();
|
|
2536
|
+
let fileObject = file.rawFile;
|
|
2537
|
+
reader.readAsDataURL(fileObject);
|
|
2538
|
+
reader.onload = () => {
|
|
2539
|
+
let existingID_GUID = null;
|
|
2540
|
+
if (!this.options.isMultipleFile && this.file)
|
|
2541
|
+
existingID_GUID = this.file.NameWithExtension == file.name ? this.file.iD_GUID : null;
|
|
2542
|
+
let AddedFile = {
|
|
2543
|
+
fileName: file.name,
|
|
2544
|
+
fileType: file.type,
|
|
2545
|
+
fileBase64: reader.result.toString().split(',')[1],
|
|
2546
|
+
fileSizeInMB: file.size / 1000 / 1000,
|
|
2547
|
+
nameWithExtension: file.name,
|
|
2548
|
+
iD_GUID: existingID_GUID,
|
|
2549
|
+
isNew: true
|
|
2550
|
+
};
|
|
2551
|
+
if (this.options.isMultipleFile == false) {
|
|
2552
|
+
this.fileUploadModel = new FileUploadModel();
|
|
2553
|
+
this.fileUploadModel.file = AddedFile;
|
|
2554
|
+
this.fileUploadFormControl.setValue(this.fileUploadModel);
|
|
2555
|
+
this.group.get(this.options.name).setValue(this.fileUploadModel);
|
|
2556
|
+
//Use this line to enable two way binding.
|
|
2557
|
+
this.options.value = this.fileUploadModel;
|
|
2558
|
+
}
|
|
2559
|
+
else {
|
|
2560
|
+
FilesArray.push(AddedFile);
|
|
2561
|
+
this.multipleFileUploadModel.uploadedFiles = FilesArray;
|
|
2562
|
+
if (this.options.value != null && this.options.value != undefined) {
|
|
2563
|
+
if (this.options.value.correlationID_GUID == null) {
|
|
2564
|
+
this.multipleFileUploadModel.removedFiles = [];
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
this.multipleFileUploadModel.correlationID_GUID =
|
|
2568
|
+
this.options.value?.correlationID_GUID;
|
|
2569
|
+
this.fileUploadFormControl.setValue(this.multipleFileUploadModel);
|
|
2570
|
+
this.group.get(this.options.name).setValue(this.multipleFileUploadModel);
|
|
2571
|
+
//Use this line to enable two way binding.
|
|
2572
|
+
this.options.value = this.multipleFileUploadModel;
|
|
2573
|
+
}
|
|
2574
|
+
};
|
|
2575
|
+
let originalValue = this.group.get(this.options.name).value;
|
|
2576
|
+
if (this.options.patchFunction &&
|
|
2577
|
+
this.options.patchPath &&
|
|
2578
|
+
this.group.get(this.options.name).valid) {
|
|
2579
|
+
this.controlUtility.patchControlValue(originalValue, this.options.patchFunction, this.options.patchPath);
|
|
2580
|
+
}
|
|
2581
|
+
this.OnChange.emit(originalValue);
|
|
2744
2582
|
}
|
|
2745
|
-
},
|
|
2746
|
-
error: (error) => {
|
|
2747
|
-
console.error('Upload failed:', error);
|
|
2748
|
-
// Handle upload error - you can add custom error handling here
|
|
2749
|
-
}
|
|
2750
|
-
});
|
|
2751
|
-
// Store subscription for cleanup
|
|
2752
|
-
this.subscriptions.add(uploadSubscription);
|
|
2753
|
-
}
|
|
2754
|
-
handleUploadProgress(element, event) {
|
|
2755
|
-
const queueIndex = this.uploader.queue.findIndex((file) => file === element);
|
|
2756
|
-
if (queueIndex === -1)
|
|
2757
|
-
return;
|
|
2758
|
-
const progress = Math.round((100 * event.loaded) / event.total);
|
|
2759
|
-
this.uploader.queue[queueIndex].progress =
|
|
2760
|
-
progress >= this.PROGRESS_NEAR_COMPLETE ? this.PROGRESS_NEAR_COMPLETE : progress;
|
|
2761
|
-
}
|
|
2762
|
-
handleUploadComplete(element, event, filesArray) {
|
|
2763
|
-
const queueIndex = this.uploader.queue.findIndex((file) => file === element);
|
|
2764
|
-
if (queueIndex === -1)
|
|
2765
|
-
return;
|
|
2766
|
-
this.uploader.queue[queueIndex].progress = this.PROGRESS_COMPLETE;
|
|
2767
|
-
const fileID = event.body.val;
|
|
2768
|
-
this.updateElementWithFileInfo(element, fileID, event.body.downloadUrl);
|
|
2769
|
-
const addedFile = this.createFileDTO(element, fileID, event.body.downloadUrl);
|
|
2770
|
-
this.updateFormValue(addedFile, filesArray);
|
|
2771
|
-
}
|
|
2772
|
-
updateElementWithFileInfo(element, fileID, downloadUrl) {
|
|
2773
|
-
element._file['iD_GUID'] = fileID;
|
|
2774
|
-
element._file['isNew'] = true;
|
|
2775
|
-
if (downloadUrl) {
|
|
2776
|
-
element._file['url'] = downloadUrl;
|
|
2777
|
-
element.file.url = downloadUrl;
|
|
2778
|
-
}
|
|
2779
|
-
}
|
|
2780
|
-
createFileDTO(element, fileID, downloadUrl) {
|
|
2781
|
-
return {
|
|
2782
|
-
iD_GUID: fileID,
|
|
2783
|
-
fileName: element._file['name'],
|
|
2784
|
-
fileType: element._file['type'],
|
|
2785
|
-
isNew: true,
|
|
2786
|
-
fileBase64: '',
|
|
2787
|
-
fileSizeInMB: element._file.size / this.BYTES_TO_MB,
|
|
2788
|
-
nameWithExtension: element._file['name'],
|
|
2789
|
-
fullFileURL: downloadUrl || null
|
|
2790
|
-
};
|
|
2791
|
-
}
|
|
2792
|
-
handleSyncFileUpload(file, filesArray) {
|
|
2793
|
-
this.trackMemoryUsage(file.size);
|
|
2794
|
-
const reader = new FileReader();
|
|
2795
|
-
// Store reader reference for cleanup
|
|
2796
|
-
const readerRef = reader;
|
|
2797
|
-
reader.onload = () => {
|
|
2798
|
-
try {
|
|
2799
|
-
const existingGUID = this.getExistingFileGUID(file);
|
|
2800
|
-
this.updateQueueItemForSync(file);
|
|
2801
|
-
const addedFile = this.createSyncFileDTO(file, reader.result, existingGUID);
|
|
2802
|
-
this.updateFormValue(addedFile, filesArray);
|
|
2803
|
-
this.handlePatchAndEmit();
|
|
2804
|
-
}
|
|
2805
|
-
finally {
|
|
2806
|
-
// Clean up reader
|
|
2807
|
-
readerRef.onload = null;
|
|
2808
|
-
readerRef.onerror = null;
|
|
2809
|
-
readerRef.onabort = null;
|
|
2810
2583
|
}
|
|
2811
|
-
};
|
|
2812
|
-
reader.onerror = () => {
|
|
2813
|
-
console.error('File reading failed');
|
|
2814
|
-
readerRef.onload = null;
|
|
2815
|
-
readerRef.onerror = null;
|
|
2816
|
-
readerRef.onabort = null;
|
|
2817
|
-
};
|
|
2818
|
-
reader.readAsDataURL(file.rawFile);
|
|
2819
|
-
}
|
|
2820
|
-
updateQueueItemForSync(file) {
|
|
2821
|
-
const queueItem = this.findQueueItemByFile(file);
|
|
2822
|
-
if (queueItem) {
|
|
2823
|
-
this.preserveFileReference(queueItem, file);
|
|
2824
|
-
queueItem.progress = this.PROGRESS_COMPLETE;
|
|
2825
|
-
}
|
|
2826
|
-
}
|
|
2827
|
-
findQueueItemByFile(file) {
|
|
2828
|
-
return this.uploader.queue.find(item => item.file.name === file.name && item.file.size === file.size);
|
|
2829
|
-
}
|
|
2830
|
-
preserveFileReference(queueItem, file) {
|
|
2831
|
-
queueItem._file.rawFile = file.rawFile;
|
|
2832
|
-
queueItem.file.rawFile = file.rawFile;
|
|
2833
|
-
}
|
|
2834
|
-
createSyncFileDTO(file, readerResult, existingGUID) {
|
|
2835
|
-
return {
|
|
2836
|
-
fileName: file.name,
|
|
2837
|
-
fileType: file.type,
|
|
2838
|
-
fileBase64: readerResult.split(',')[1],
|
|
2839
|
-
fileSizeInMB: file.size / this.BYTES_TO_MB,
|
|
2840
|
-
nameWithExtension: file.name,
|
|
2841
|
-
iD_GUID: existingGUID,
|
|
2842
|
-
isNew: true,
|
|
2843
|
-
fullFileURL: null
|
|
2844
|
-
};
|
|
2845
|
-
}
|
|
2846
|
-
getExistingFileGUID(file) {
|
|
2847
|
-
if (!this.options.isMultipleFile && this.file) {
|
|
2848
|
-
return this.file.nameWithExtension === file.name ? this.file.iD_GUID : null;
|
|
2849
2584
|
}
|
|
2850
|
-
return null;
|
|
2851
|
-
}
|
|
2852
|
-
updateFormValue(addedFile, filesArray) {
|
|
2853
|
-
if (!this.options.isMultipleFile) {
|
|
2854
|
-
this.fileUploadModel = new FileUploadModel();
|
|
2855
|
-
this.fileUploadModel.file = addedFile;
|
|
2856
|
-
this.updateFormControl(this.fileUploadModel);
|
|
2857
|
-
}
|
|
2858
|
-
else {
|
|
2859
|
-
filesArray.push(addedFile);
|
|
2860
|
-
this.multipleFileUploadModel.uploadedFiles = filesArray;
|
|
2861
|
-
this.setupMultipleFileModel();
|
|
2862
|
-
this.updateFormControl(this.multipleFileUploadModel);
|
|
2863
|
-
this.isUploadComplete.emit(true);
|
|
2864
|
-
}
|
|
2865
|
-
}
|
|
2866
|
-
setupMultipleFileModel() {
|
|
2867
|
-
if (this.options.value?.correlationID_GUID == null) {
|
|
2868
|
-
this.multipleFileUploadModel.removedFiles = [];
|
|
2869
|
-
}
|
|
2870
|
-
this.multipleFileUploadModel.correlationID_GUID = this.options.value?.correlationID_GUID;
|
|
2871
|
-
}
|
|
2872
|
-
updateFormControl(value) {
|
|
2873
|
-
this.preserveErrorsAndUpdateValue(value);
|
|
2874
|
-
this.options.value = value;
|
|
2875
|
-
}
|
|
2876
|
-
preserveErrorsAndUpdateValue(value) {
|
|
2877
|
-
// If we have a valid file value and haven't cleared the required error yet, remove it
|
|
2878
|
-
if (this.hasValidFileValue(value) && !this.hasClearedRequiredError) {
|
|
2879
|
-
// Use the custom method that only removes the validator without changing the isRequired option
|
|
2880
|
-
// This keeps the asterisk visible while removing the validation logic
|
|
2881
|
-
this.removeRequiredValidatorOnly();
|
|
2882
|
-
// Mark that we've cleared the required error
|
|
2883
|
-
this.hasClearedRequiredError = true;
|
|
2884
|
-
}
|
|
2885
|
-
// Set the form control value
|
|
2886
|
-
this.fileUploadFormControl.setValue(value, { emitEvent: false });
|
|
2887
|
-
// Update the form group control value
|
|
2888
|
-
this.group.get(this.options.name)?.setValue(value, { emitEvent: false });
|
|
2889
|
-
}
|
|
2890
|
-
hasValidFileValue(value) {
|
|
2891
|
-
if (!value)
|
|
2892
|
-
return false;
|
|
2893
|
-
if (this.options.isMultipleFile) {
|
|
2894
|
-
const multipleValue = value;
|
|
2895
|
-
return (multipleValue.uploadedFiles && multipleValue.uploadedFiles.length > 0) ||
|
|
2896
|
-
(multipleValue.existingFiles && multipleValue.existingFiles.length > 0);
|
|
2897
|
-
}
|
|
2898
|
-
else {
|
|
2899
|
-
const singleValue = value;
|
|
2900
|
-
return singleValue.file && singleValue.file.fileName !== '';
|
|
2901
|
-
}
|
|
2902
|
-
}
|
|
2903
|
-
handlePatchAndEmit() {
|
|
2904
|
-
const originalValue = this.group.get(this.options.name)?.value;
|
|
2905
|
-
if (this.options.patchFunction && this.options.patchPath && this.group.get(this.options.name)?.valid) {
|
|
2906
|
-
this.controlUtility.patchControlValue(originalValue, this.options.patchFunction, this.options.patchPath);
|
|
2907
|
-
}
|
|
2908
|
-
this.OnChange.emit(originalValue);
|
|
2909
2585
|
}
|
|
2910
2586
|
removeFromControlValue(item) {
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
if (downloadUrl && downloadUrl.startsWith('blob:')) {
|
|
2914
|
-
this.cleanupBlobUrl(downloadUrl);
|
|
2915
|
-
}
|
|
2916
|
-
this.handleAsyncFileDeletion(item);
|
|
2917
|
-
if (!this.options.isMultipleFile) {
|
|
2918
|
-
this.handleSingleFileRemoval();
|
|
2919
|
-
}
|
|
2920
|
-
else {
|
|
2921
|
-
this.handleMultipleFileRemoval(item);
|
|
2922
|
-
}
|
|
2923
|
-
this.checkAndClearMaxFileCountValidation();
|
|
2924
|
-
}
|
|
2925
|
-
handleAsyncFileDeletion(item) {
|
|
2926
|
-
if (this.options.isUploadFileAsync &&
|
|
2927
|
-
item.progress === this.PROGRESS_COMPLETE &&
|
|
2928
|
-
item._file['isNew']) {
|
|
2929
|
-
const deleteSubscription = this.fileUploadService.deleteFile(item._file['iD_GUID']).subscribe({
|
|
2930
|
-
error: (error) => console.error('Delete failed:', error)
|
|
2931
|
-
});
|
|
2932
|
-
this.subscriptions.add(deleteSubscription);
|
|
2933
|
-
}
|
|
2934
|
-
}
|
|
2935
|
-
handleSingleFileRemoval() {
|
|
2936
|
-
this.uploader.queue = [];
|
|
2937
|
-
this.fileUploadModel = null;
|
|
2938
|
-
if (this.options.isRequired) {
|
|
2939
|
-
this.fileUploadFormControl.markAsTouched();
|
|
2940
|
-
// Use the existing utility function to add required validation back
|
|
2941
|
-
this.addRequiredValidation();
|
|
2942
|
-
}
|
|
2943
|
-
// Reset the flag so required validation can work again
|
|
2944
|
-
this.hasClearedRequiredError = false;
|
|
2945
|
-
this.group.get(this.options.name)?.setValue(this.fileUploadModel, { emitEvent: false });
|
|
2946
|
-
this.options.value = this.fileUploadModel;
|
|
2947
|
-
// Re-evaluate all validations after file removal
|
|
2948
|
-
this.reEvaluateAllValidations();
|
|
2949
|
-
}
|
|
2950
|
-
handleMultipleFileRemoval(item) {
|
|
2951
|
-
// Clean up blob URL
|
|
2952
|
-
const downloadUrl = this.getFileDownloadUrl(item);
|
|
2953
|
-
if (downloadUrl && downloadUrl.startsWith('blob:')) {
|
|
2954
|
-
this.cleanupBlobUrl(downloadUrl);
|
|
2955
|
-
}
|
|
2956
|
-
const queueIndex = this.uploader.queue.indexOf(item);
|
|
2957
|
-
if (queueIndex > -1) {
|
|
2958
|
-
this.uploader.queue.splice(queueIndex, 1);
|
|
2959
|
-
}
|
|
2960
|
-
this.processFileRemovalFromExisting(item);
|
|
2961
|
-
this.removeFromUploadedFiles(item);
|
|
2962
|
-
this.validateRemainingFiles();
|
|
2963
|
-
this.updateMultipleFileModel();
|
|
2964
|
-
}
|
|
2965
|
-
processFileRemovalFromExisting(item) {
|
|
2966
|
-
if (!this.options.value) {
|
|
2967
|
-
this.resetDeletedFiles();
|
|
2968
|
-
return;
|
|
2587
|
+
if (this.options.isUploadFileAsync && item.progress == 100 && item._file['isNew']) {
|
|
2588
|
+
this.fileUploadService.deleteFile(item._file['iD_GUID']).subscribe((res) => { });
|
|
2969
2589
|
}
|
|
2970
|
-
if (
|
|
2971
|
-
this.
|
|
2590
|
+
if (this.options.isMultipleFile == false) {
|
|
2591
|
+
this.fileUploadModel = null;
|
|
2592
|
+
if (this.options.isRequired == true) {
|
|
2593
|
+
this.fileUploadFormControl.markAsTouched();
|
|
2594
|
+
this.fileUploadFormControl.invalid;
|
|
2595
|
+
}
|
|
2596
|
+
this.group.get(this.options.name).setValue(this.fileUploadModel);
|
|
2597
|
+
this.options.value = this.fileUploadModel;
|
|
2972
2598
|
}
|
|
2973
2599
|
else {
|
|
2974
|
-
this.
|
|
2975
|
-
|
|
2976
|
-
|
|
2977
|
-
|
|
2978
|
-
|
|
2979
|
-
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2986
|
-
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
return obj.iD_GUID !== itemGUID;
|
|
2600
|
+
if (this.options.value != null && this.options.value != undefined) {
|
|
2601
|
+
if (this.options.value.correlationID_GUID == null) {
|
|
2602
|
+
this.deletedFiles = [];
|
|
2603
|
+
this.multipleFileUploadModel.removedFiles = [];
|
|
2604
|
+
}
|
|
2605
|
+
else {
|
|
2606
|
+
if (this.multipleFileUploadModel.removedFiles.length == 0) {
|
|
2607
|
+
let FileObject = item.file.rawFile;
|
|
2608
|
+
let DeletedItem = this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension == FileObject.name)[0];
|
|
2609
|
+
this.multipleFileUploadModel.existingFiles =
|
|
2610
|
+
this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension != FileObject.name);
|
|
2611
|
+
this.deletedFiles.push(DeletedItem);
|
|
2612
|
+
this.multipleFileUploadModel.removedFiles.push(DeletedItem.iD_GUID);
|
|
2613
|
+
}
|
|
2614
|
+
else {
|
|
2615
|
+
let FileObject = item.file.rawFile;
|
|
2616
|
+
let deletedList = this.deletedFiles.filter((obj) => obj.nameWithExtension == FileObject.name);
|
|
2617
|
+
if (deletedList.length == 0 || deletedList == undefined) {
|
|
2618
|
+
let DeletedItem = this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension == FileObject.name)[0];
|
|
2619
|
+
this.multipleFileUploadModel.existingFiles =
|
|
2620
|
+
this.multipleFileUploadModel.existingFiles.filter((obj) => obj.nameWithExtension != FileObject.name);
|
|
2621
|
+
this.deletedFiles.push(DeletedItem);
|
|
2622
|
+
this.multipleFileUploadModel.removedFiles.push(DeletedItem.iD_GUID);
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
3000
2625
|
}
|
|
3001
|
-
const objFileName = obj.nameWithExtension || obj.fileName;
|
|
3002
|
-
const objFileSize = obj.fileSizeInMB ? obj.fileSizeInMB * this.BYTES_TO_MB : 0;
|
|
3003
|
-
return !(objFileName === itemFileName && Math.abs(objFileSize - itemFileSize) < 1000);
|
|
3004
|
-
});
|
|
3005
|
-
}
|
|
3006
|
-
validateRemainingFiles() {
|
|
3007
|
-
if ((!this.multipleFileUploadModel.uploadedFiles ||
|
|
3008
|
-
this.multipleFileUploadModel.uploadedFiles.length === 0) &&
|
|
3009
|
-
this.options.isRequired) {
|
|
3010
|
-
this.fileUploadFormControl.setErrors({
|
|
3011
|
-
MinFileCountValidationKey: this.options.minNoOfFiles
|
|
3012
|
-
});
|
|
3013
|
-
this.fileUploadFormControl.markAsTouched();
|
|
3014
|
-
this.addRequiredValidation();
|
|
3015
|
-
this.hasClearedRequiredError = false;
|
|
3016
|
-
}
|
|
3017
|
-
// Re-evaluate all validations after file removal
|
|
3018
|
-
this.reEvaluateAllValidations();
|
|
3019
|
-
}
|
|
3020
|
-
reEvaluateAllValidations() {
|
|
3021
|
-
// Clear all existing validation errors first
|
|
3022
|
-
this.fileUploadFormControl.setErrors(null);
|
|
3023
|
-
// Re-apply required validation if needed
|
|
3024
|
-
if (this.options.isRequired) {
|
|
3025
|
-
this.addRequiredValidation();
|
|
3026
|
-
}
|
|
3027
|
-
// Re-validate file count constraints
|
|
3028
|
-
this.reValidateFileCountConstraints();
|
|
3029
|
-
// Re-validate total file size
|
|
3030
|
-
this.reValidateTotalFileSize();
|
|
3031
|
-
// Re-validate individual files
|
|
3032
|
-
this.reValidateIndividualFiles();
|
|
3033
|
-
// Clear validation errors that are no longer applicable
|
|
3034
|
-
this.clearObsoleteValidationErrors();
|
|
3035
|
-
// Update form control validity
|
|
3036
|
-
this.fileUploadFormControl.updateValueAndValidity();
|
|
3037
|
-
}
|
|
3038
|
-
clearObsoleteValidationErrors() {
|
|
3039
|
-
const currentFileCount = this.uploader.queue.length;
|
|
3040
|
-
// Clear max file count error if current count is within limit
|
|
3041
|
-
if (this.options.maxNoOfFiles > 0 && currentFileCount <= this.options.maxNoOfFiles) {
|
|
3042
|
-
this.clearFileCountError('MaxFileCountValidationKey');
|
|
3043
|
-
}
|
|
3044
|
-
// Clear min file count error if current count meets minimum requirement
|
|
3045
|
-
if (this.options.minNoOfFiles > 0 && currentFileCount >= this.options.minNoOfFiles) {
|
|
3046
|
-
this.clearFileCountError('MinFileCountValidationKey');
|
|
3047
|
-
}
|
|
3048
|
-
// Clear total size error if current total size is within limit
|
|
3049
|
-
if (this.options.maxSizeForAllFilesInMB > 0) {
|
|
3050
|
-
const totalSize = this.uploader.queue.reduce((sum, element) => sum + element.file.size, 0);
|
|
3051
|
-
const maxSizeBytes = this.options.maxSizeForAllFilesInMB * this.BYTES_TO_MB;
|
|
3052
|
-
if (totalSize <= maxSizeBytes) {
|
|
3053
|
-
this.clearFileCountError('MaxSizeForAllFilesInMB');
|
|
3054
|
-
}
|
|
3055
|
-
}
|
|
3056
|
-
}
|
|
3057
|
-
reValidateFileCountConstraints() {
|
|
3058
|
-
const currentFileCount = this.uploader.queue.length;
|
|
3059
|
-
// Check minimum file count
|
|
3060
|
-
if (this.options.minNoOfFiles > 0 && currentFileCount < this.options.minNoOfFiles) {
|
|
3061
|
-
const minFileMsg = this.utilityService.getResourceValue('MinimumFilesRequired')
|
|
3062
|
-
.replace('{count}', this.options.minNoOfFiles.toString());
|
|
3063
|
-
this.showFileCountError('MinFileCountValidationKey', minFileMsg);
|
|
3064
|
-
}
|
|
3065
|
-
// Check maximum file count
|
|
3066
|
-
if (this.options.maxNoOfFiles > 0 && currentFileCount > this.options.maxNoOfFiles) {
|
|
3067
|
-
const maxFileMsg = this.utilityService.getResourceValue('MaximumFilesExceeded') ||
|
|
3068
|
-
`Maximum {maxCount} files allowed. You have selected {currentCount} files.`;
|
|
3069
|
-
const finalMsg = maxFileMsg
|
|
3070
|
-
.replace('{maxCount}', this.options.maxNoOfFiles.toString())
|
|
3071
|
-
.replace('{currentCount}', currentFileCount.toString());
|
|
3072
|
-
this.showFileCountError('MaxFileCountValidationKey', finalMsg);
|
|
3073
|
-
}
|
|
3074
|
-
}
|
|
3075
|
-
reValidateTotalFileSize() {
|
|
3076
|
-
if (this.options.maxSizeForAllFilesInMB > 0) {
|
|
3077
|
-
const totalSize = this.uploader.queue.reduce((sum, element) => sum + element.file.size, 0);
|
|
3078
|
-
const maxSizeBytes = this.options.maxSizeForAllFilesInMB * this.BYTES_TO_MB;
|
|
3079
|
-
if (totalSize > maxSizeBytes) {
|
|
3080
|
-
this.showTotalSizeError();
|
|
3081
|
-
}
|
|
3082
|
-
}
|
|
3083
|
-
}
|
|
3084
|
-
reValidateIndividualFiles() {
|
|
3085
|
-
// Re-validate each remaining file for size and type
|
|
3086
|
-
for (const element of this.uploader.queue) {
|
|
3087
|
-
const file = element.file;
|
|
3088
|
-
if (!file)
|
|
3089
|
-
continue;
|
|
3090
|
-
// Check file size
|
|
3091
|
-
if (!this.validateIndividualFileSize(file)) {
|
|
3092
|
-
this.setFormControlError('FileMaxSizeInMB', `${this.options.fileMaxSizeInMB}MB`);
|
|
3093
2626
|
}
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
this.
|
|
2627
|
+
else {
|
|
2628
|
+
this.deletedFiles = [];
|
|
2629
|
+
this.multipleFileUploadModel.removedFiles = [];
|
|
2630
|
+
}
|
|
2631
|
+
this.multipleFileUploadModel.uploadedFiles =
|
|
2632
|
+
this.multipleFileUploadModel.uploadedFiles.filter((obj) => (obj.nameWithExtension && obj.nameWithExtension != item._file.name) ||
|
|
2633
|
+
obj.iD_GUID != item._file['iD_GUID']);
|
|
2634
|
+
if ((this.multipleFileUploadModel.uploadedFiles == null ||
|
|
2635
|
+
this.multipleFileUploadModel.uploadedFiles.length == 0) &&
|
|
2636
|
+
this.options.isRequired) {
|
|
2637
|
+
const formControl = this.fileUploadFormControl;
|
|
2638
|
+
formControl.setErrors({
|
|
2639
|
+
MinFileCountValidationKey: this.options.minNoOfFiles
|
|
2640
|
+
});
|
|
2641
|
+
this.fileUploadFormControl.markAsTouched();
|
|
2642
|
+
this.fileUploadFormControl.invalid;
|
|
3097
2643
|
}
|
|
2644
|
+
this.multipleFileUploadModel.correlationID_GUID = this.options.value?.correlationID_GUID;
|
|
2645
|
+
this.fileUploadFormControl.setValue(this.multipleFileUploadModel);
|
|
2646
|
+
this.group.get(this.options.name).setValue(this.multipleFileUploadModel);
|
|
2647
|
+
//Use this line to enable two way binding.
|
|
2648
|
+
this.options.value = this.multipleFileUploadModel;
|
|
3098
2649
|
}
|
|
3099
2650
|
}
|
|
3100
|
-
updateMultipleFileModel() {
|
|
3101
|
-
this.multipleFileUploadModel.correlationID_GUID = this.options.value?.correlationID_GUID;
|
|
3102
|
-
this.fileUploadFormControl.setValue(this.multipleFileUploadModel, { emitEvent: false });
|
|
3103
|
-
this.group.get(this.options.name)?.setValue(this.multipleFileUploadModel, { emitEvent: false });
|
|
3104
|
-
this.options.value = this.multipleFileUploadModel;
|
|
3105
|
-
}
|
|
3106
2651
|
convertSizeToMB(size) {
|
|
3107
2652
|
if (size === 0) {
|
|
3108
2653
|
return 0;
|
|
3109
2654
|
}
|
|
3110
|
-
|
|
3111
|
-
const megabytes = size /
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
return item._file ? item._file.name + item._file.size : index;
|
|
3116
|
-
}
|
|
3117
|
-
shouldShowFileList() {
|
|
3118
|
-
return this.uploader?.queue && this.uploader.queue.length > 0;
|
|
3119
|
-
}
|
|
3120
|
-
isDownloadEnabled() {
|
|
3121
|
-
return true;
|
|
3122
|
-
}
|
|
3123
|
-
isRemoveEnabled() {
|
|
3124
|
-
return !this.options.isReadonly && !this.options.isDisabled;
|
|
3125
|
-
}
|
|
3126
|
-
getFileDownloadUrl(item) {
|
|
3127
|
-
const existingUrl = this.getExistingFileUrl(item);
|
|
3128
|
-
if (existingUrl) {
|
|
3129
|
-
return existingUrl;
|
|
3130
|
-
}
|
|
3131
|
-
return this.createFileUrl(item);
|
|
3132
|
-
}
|
|
3133
|
-
getExistingFileUrl(item) {
|
|
3134
|
-
return item?.file?.url ||
|
|
3135
|
-
item?._file?.url ||
|
|
3136
|
-
item?.url ||
|
|
3137
|
-
item?.file?.rawFile?.url ||
|
|
3138
|
-
item?._file?.rawFile?.url ||
|
|
3139
|
-
null;
|
|
3140
|
-
}
|
|
3141
|
-
createFileUrl(item) {
|
|
3142
|
-
const fileName = this.getFileName(item);
|
|
3143
|
-
const fileType = item?.file?.type || item?._file?.type;
|
|
3144
|
-
const originalFile = item?._file?.rawFile || item?.file?.rawFile;
|
|
3145
|
-
if (originalFile && originalFile instanceof File) {
|
|
3146
|
-
return URL.createObjectURL(originalFile);
|
|
3147
|
-
}
|
|
3148
|
-
const base64Data = typeof originalFile === 'string' ? originalFile : null;
|
|
3149
|
-
if (base64Data && fileName) {
|
|
3150
|
-
return this.createBlobUrlWithFilename(base64Data, fileType, fileName);
|
|
3151
|
-
}
|
|
3152
|
-
const fileId = item?._file?.['iD_GUID'];
|
|
3153
|
-
if (fileId && this.options.isUploadFileAsync) {
|
|
3154
|
-
return this.constructDownloadUrl(fileId, fileName);
|
|
3155
|
-
}
|
|
3156
|
-
return null;
|
|
3157
|
-
}
|
|
3158
|
-
createBlobUrlWithFilename(base64Data, fileType, fileName) {
|
|
3159
|
-
try {
|
|
3160
|
-
const byteCharacters = atob(base64Data);
|
|
3161
|
-
const byteNumbers = new Array(byteCharacters.length);
|
|
3162
|
-
for (let i = 0; i < byteCharacters.length; i++) {
|
|
3163
|
-
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
3164
|
-
}
|
|
3165
|
-
const byteArray = new Uint8Array(byteNumbers);
|
|
3166
|
-
const blob = new Blob([byteArray], { type: fileType || 'application/octet-stream' });
|
|
3167
|
-
return URL.createObjectURL(blob);
|
|
3168
|
-
}
|
|
3169
|
-
catch (error) {
|
|
3170
|
-
const errorMsg = this.utilityService.getResourceValue('ErrorCreatingBlobUrl');
|
|
3171
|
-
console.error(errorMsg, error);
|
|
3172
|
-
return `data:${fileType || 'application/octet-stream'};base64,${base64Data}`;
|
|
3173
|
-
}
|
|
3174
|
-
}
|
|
3175
|
-
constructDownloadUrl(fileId, fileName) {
|
|
3176
|
-
const downloadBaseUrl = this.options.downloadBaseUrl;
|
|
3177
|
-
let url;
|
|
3178
|
-
if (downloadBaseUrl) {
|
|
3179
|
-
url = `${downloadBaseUrl}/${fileId}`;
|
|
3180
|
-
}
|
|
3181
|
-
else {
|
|
3182
|
-
url = `/api/files/download/${fileId}`;
|
|
3183
|
-
}
|
|
3184
|
-
if (fileName) {
|
|
3185
|
-
const separator = url.includes('?') ? '&' : '?';
|
|
3186
|
-
url += `${separator}filename=${encodeURIComponent(fileName)}`;
|
|
3187
|
-
}
|
|
3188
|
-
return url;
|
|
3189
|
-
}
|
|
3190
|
-
getFileName(item) {
|
|
3191
|
-
return item?.file?.name || item?._file?.name || 'file';
|
|
3192
|
-
}
|
|
3193
|
-
downloadFile(item) {
|
|
3194
|
-
const downloadInfo = this.prepareFileDownload(item);
|
|
3195
|
-
if (!downloadInfo.url) {
|
|
3196
|
-
this.handleDownloadError(downloadInfo.fileName);
|
|
3197
|
-
return;
|
|
3198
|
-
}
|
|
3199
|
-
this.executeFileDownload(downloadInfo.url, downloadInfo.fileName);
|
|
3200
|
-
}
|
|
3201
|
-
prepareFileDownload(item) {
|
|
3202
|
-
return {
|
|
3203
|
-
url: this.getFileDownloadUrl(item),
|
|
3204
|
-
fileName: this.getFileName(item)
|
|
3205
|
-
};
|
|
3206
|
-
}
|
|
3207
|
-
handleDownloadError(fileName) {
|
|
3208
|
-
const errorMsg = this.utilityService.getResourceValue('NoDownloadUrlAvailable')
|
|
3209
|
-
.replace('{fileName}', fileName);
|
|
3210
|
-
console.error(errorMsg);
|
|
3211
|
-
}
|
|
3212
|
-
executeFileDownload(url, fileName) {
|
|
3213
|
-
const link = this.createDownloadLink(url, fileName);
|
|
3214
|
-
this.triggerDownload(link);
|
|
3215
|
-
this.cleanupBlobUrl(url);
|
|
3216
|
-
}
|
|
3217
|
-
createDownloadLink(url, fileName) {
|
|
3218
|
-
const link = document.createElement('a');
|
|
3219
|
-
link.href = url;
|
|
3220
|
-
link.download = fileName;
|
|
3221
|
-
link.style.display = 'none';
|
|
3222
|
-
return link;
|
|
3223
|
-
}
|
|
3224
|
-
triggerDownload(link) {
|
|
3225
|
-
document.body.appendChild(link);
|
|
3226
|
-
link.click();
|
|
3227
|
-
document.body.removeChild(link);
|
|
3228
|
-
}
|
|
3229
|
-
cleanupBlobUrl(url) {
|
|
3230
|
-
if (url.startsWith('blob:')) {
|
|
3231
|
-
setTimeout(() => {
|
|
3232
|
-
URL.revokeObjectURL(url);
|
|
3233
|
-
}, 100);
|
|
3234
|
-
}
|
|
3235
|
-
}
|
|
3236
|
-
trackMemoryUsage(fileSize) {
|
|
3237
|
-
this.currentMemoryUsage += fileSize;
|
|
3238
|
-
// If memory usage exceeds limit, clean up old files
|
|
3239
|
-
if (this.currentMemoryUsage > this.MAX_MEMORY_USAGE) {
|
|
3240
|
-
this.cleanupOldFiles();
|
|
3241
|
-
}
|
|
3242
|
-
}
|
|
3243
|
-
cleanupOldFiles() {
|
|
3244
|
-
if (this.uploader?.queue && this.uploader.queue.length > 0) {
|
|
3245
|
-
// Remove oldest files to free memory
|
|
3246
|
-
const oldestFile = this.uploader.queue.shift();
|
|
3247
|
-
if (oldestFile) {
|
|
3248
|
-
const url = this.getFileDownloadUrl(oldestFile);
|
|
3249
|
-
if (url && url.startsWith('blob:')) {
|
|
3250
|
-
this.cleanupBlobUrl(url);
|
|
3251
|
-
}
|
|
3252
|
-
this.currentMemoryUsage -= (oldestFile.file?.size || 0);
|
|
3253
|
-
}
|
|
3254
|
-
}
|
|
3255
|
-
}
|
|
3256
|
-
cleanupEventListeners() {
|
|
3257
|
-
// Clear file input references
|
|
3258
|
-
if (this.fileInput?.nativeElement) {
|
|
3259
|
-
this.fileInput.nativeElement.value = '';
|
|
3260
|
-
}
|
|
3261
|
-
// Clear uploader queue to prevent memory leaks
|
|
3262
|
-
if (this.uploader?.queue) {
|
|
3263
|
-
this.uploader.queue = [];
|
|
3264
|
-
}
|
|
3265
|
-
}
|
|
3266
|
-
cleanupUploaderQueue() {
|
|
3267
|
-
if (this.uploader?.queue) {
|
|
3268
|
-
// Clear all items and their associated resources
|
|
3269
|
-
this.uploader.queue.forEach(item => {
|
|
3270
|
-
// Clean up blob URLs
|
|
3271
|
-
const url = this.getFileDownloadUrl(item);
|
|
3272
|
-
if (url && url.startsWith('blob:')) {
|
|
3273
|
-
this.cleanupBlobUrl(url);
|
|
3274
|
-
}
|
|
3275
|
-
// Clear file references
|
|
3276
|
-
if (item._file) {
|
|
3277
|
-
item._file = null;
|
|
3278
|
-
}
|
|
3279
|
-
if (item.file) {
|
|
3280
|
-
item.file = null;
|
|
3281
|
-
}
|
|
3282
|
-
});
|
|
3283
|
-
// Clear the queue
|
|
3284
|
-
this.uploader.queue = [];
|
|
3285
|
-
}
|
|
3286
|
-
}
|
|
3287
|
-
ngOnDestroy() {
|
|
3288
|
-
// Clean up subscriptions
|
|
3289
|
-
this.subscriptions.unsubscribe();
|
|
3290
|
-
// Clean up uploader queue
|
|
3291
|
-
this.cleanupUploaderQueue();
|
|
3292
|
-
// Clean up event listeners
|
|
3293
|
-
this.cleanupEventListeners();
|
|
3294
|
-
// Clean up blob URLs
|
|
3295
|
-
if (this.uploader?.queue) {
|
|
3296
|
-
this.uploader.queue.forEach(item => {
|
|
3297
|
-
const url = this.getFileDownloadUrl(item);
|
|
3298
|
-
if (url && url.startsWith('blob:')) {
|
|
3299
|
-
URL.revokeObjectURL(url);
|
|
3300
|
-
}
|
|
3301
|
-
});
|
|
3302
|
-
}
|
|
3303
|
-
}
|
|
3304
|
-
checkAndClearMaxFileCountValidation() {
|
|
3305
|
-
if (!this.options.maxNoOfFiles || this.options.maxNoOfFiles <= 0) {
|
|
3306
|
-
return;
|
|
3307
|
-
}
|
|
3308
|
-
const currentQueueLength = this.uploader.queue.length;
|
|
3309
|
-
if (currentQueueLength <= this.options.maxNoOfFiles) {
|
|
3310
|
-
this.clearFileCountError('MaxFileCountValidationKey');
|
|
3311
|
-
}
|
|
2655
|
+
// Convert size to megabytes
|
|
2656
|
+
const megabytes = size / (1024 * 1024);
|
|
2657
|
+
// Round to two decimal places
|
|
2658
|
+
const roundedMegabytes = Math.round(megabytes * 100) / 100;
|
|
2659
|
+
return roundedMegabytes;
|
|
3312
2660
|
}
|
|
3313
2661
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileUploadComponent, deps: [{ token: i2.ControlContainer, optional: true }, { token: i2.FormGroupDirective }, { token: ControlUtility }, { token: i3.UtilityService }, { token: i3.ControlValidationService }, { token: GlobalSettings }, { token: FileUploadService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3314
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FileUploadComponent, selector: "BBSF-FileUpload", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange", isUploadComplete: "isUploadComplete" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType === 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!-- Label -->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!-- Required asterisk -->\r\n <span *ngIf=\"options.isRequired && !options.isReadonly && (options.showAsterisk || true)\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!-- Drop zone enabled -->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" [id]=\"options.name\"\r\n [attr.multiple]=\"options.isMultipleFile ? 'multiple' : null\"\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputControl.click()\">\r\n\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <!-- Upload icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <!-- Instruction text -->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ utilityService.getResourceValue('DragAndDropHere') }}\r\n </div>\r\n\r\n <!-- Validation messages -->\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\">\r\n </div>\r\n\r\n <div class=\"bbsf-validation-msg text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\">\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden file input -->\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n [attr.multiple]=\"options.isMultipleFile ? 'multiple' : null\" name=\"file\" type=\"file\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType === 1 ? '' : 'col-md-9'\" [id]=\"options.name\"\r\n #fileInputControl [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- Click to upload (no drop zone) -->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <!-- Upload icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <!-- Upload text -->\r\n <div class=\"bbsf-validation-msg text-center\">\r\n {{ utilityService.getResourceValue('Upload') }}\r\n </div>\r\n\r\n <!-- Validation messages -->\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\">\r\n </div>\r\n\r\n <div class=\"bbsf-validation-msg text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\">\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden file input -->\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n [attr.multiple]=\"options.isMultipleFile ? 'multiple' : null\" name=\"file\" type=\"file\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType === 1 ? '' : 'col-md-9'\" [id]=\"options.name\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- Read-only state with no files -->\r\n <div *ngIf=\"options.isReadonly && (!options.value || (uploader.queue && uploader.queue.length === 0))\">\r\n <span class=\"readonly-view\">{{ utilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!-- Uploaded files list -->\r\n <div class=\"uploaded-items\" *ngIf=\"shouldShowFileList()\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue; trackBy: trackByFunction\">\r\n\r\n <!-- Async upload completed files -->\r\n <ng-container *ngIf=\"item?.progress === 100 && options.isUploadFileAsync\">\r\n <!-- Download link - always visible -->\r\n <button *ngIf=\"getFileDownloadUrl(item); else noUrlTemplate\" type=\"button\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" (click)=\"downloadFile(item)\"\r\n [title]=\"'Download ' + getFileName(item)\">\r\n <span class=\"file-name\">{{ getFileName(item) }}</span>\r\n </button>\r\n\r\n <!-- File name display when no URL available -->\r\n <ng-template #noUrlTemplate>\r\n <span class=\"btn-download-file btn-sm btn-progress-upload\" [title]=\"getFileName(item)\">\r\n <span class=\"file-name\">{{ getFileName(item) }}</span>\r\n </span>\r\n </ng-template>\r\n\r\n <!-- Remove button - only show when not readonly and not disabled -->\r\n <button *ngIf=\"isRemoveEnabled()\" class=\"btn btn-download-file btn-sm\" type=\"button\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\" [attr.aria-label]=\"'Remove ' + getFileName(item)\"\r\n [title]=\"'Remove ' + getFileName(item)\">\r\n <!-- Delete icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Sync upload files -->\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <!-- Download link - always visible -->\r\n <button type=\"button\" class=\"btn btn-download-file btn-sm\" (click)=\"downloadFile(item)\"\r\n [title]=\"'Download ' + getFileName(item)\">\r\n <!-- Download icon -->\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ getFileName(item) }}</span>\r\n </button>\r\n\r\n <!-- Remove button - only show when not readonly and not disabled -->\r\n <button *ngIf=\"isRemoveEnabled()\" class=\"btn btn-download-file btn-sm btn-danger\" type=\"button\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\" [attr.aria-label]=\"'Remove ' + getFileName(item)\"\r\n [title]=\"'Remove ' + getFileName(item)\">\r\n <i class=\"fa fa-times px-0\" aria-hidden=\"true\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- File upload progress indicators -->\r\n <div *ngFor=\"let item of uploader.queue; trackBy: trackByFunction\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync && !options.isReadonly\">\r\n\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ getFileName(item) }}</h4>\r\n <button *ngIf=\"isRemoveEnabled()\" type=\"button\" class=\"btn-cancel-upload\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\"\r\n [attr.aria-label]=\"'Cancel upload for ' + getFileName(item)\">\r\n <!-- Cancel icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" [attr.aria-valuenow]=\"item?.progress\" aria-valuemin=\"0\"\r\n aria-valuemax=\"100\" [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\"\r\n *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Validation and description section -->\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- Validation messages -->\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n <span [innerHTML]=\"getErrorValidation(fileUploadFormControl.errors | keyvalue)\"></span>\r\n </div>\r\n\r\n <!-- Control description -->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription\">\r\n {{ options.labelDescription }}\r\n </div>\r\n\r\n <!-- Reset error state -->\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7$2.FileDropDirective, selector: "[ng2FileDrop]", inputs: ["uploader"], outputs: ["fileOver", "onFileDrop"] }, { kind: "directive", type: i7$2.FileSelectDirective, selector: "[ng2FileSelect]", inputs: ["uploader"], outputs: ["onFileSelected"] }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }] }); }
|
|
2662
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: FileUploadComponent, selector: "BBSF-FileUpload", inputs: { group: "group", options: "options" }, outputs: { OnChange: "OnChange", isUploadComplete: "isUploadComplete" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileInput"], descendants: true }], ngImport: i0, template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType == 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk && options.isRequired) || options.isRequired) && !options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !(options.isMultipleFile == false && uploader.queue.length > 0) && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" id=\"{{ options.name }}\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" aria-describedby=\"email-error\" aria-invalid=\"true\"\r\n type=\"file\" #fileInput [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputControl.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ UtilityService.getResourceValue('DragAndDropHere') }}\r\n </div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{ options.name }}\" #fileInputControl\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg text-center\">{{ UtilityService.getResourceValue('Upload') }}</div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{ options.name }}\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly && !options.value\">\r\n <span class=\"readonly-view\">{{ UtilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!--items uploaded-->\r\n <div class=\"uploaded-items\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue\">\r\n <ng-container *ngIf=\"item?.progress == 100 && options.isUploadFileAsync\">\r\n <a *ngIf=\"item?.file?.rawFile['url']\" href=\"{{ item?.file?.rawFile['url'] }}\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" download>\r\n <span class=\"file-name\">{{ item?.file?.name }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ item?.file?.name }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <a href=\"{{ item?.file?.rawFile['url'] }}\" class=\"btn btn-download-file btn-sm\" download>\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ item?.file?.name }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm btn-danger\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <i class=\"fa fa-times px-0\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!--progress bar file upload-->\r\n <div *ngFor=\"let item of uploader.queue\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile == true }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync\">\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ item?.file?.name }}</h4>\r\n <span (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"70\" aria-valuemin=\"0\" aria-valuemax=\"100\"\r\n [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\" *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n {{ getErrorValidation(fileUploadFormControl.errors | keyvalue) }}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription != null\">{{ options.labelDescription }}</div>\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>", dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7$2.FileDropDirective, selector: "[ng2FileDrop]", inputs: ["uploader"], outputs: ["fileOver", "onFileDrop"] }, { kind: "directive", type: i7$2.FileSelectDirective, selector: "[ng2FileSelect]", inputs: ["uploader"], outputs: ["onFileSelected"] }, { kind: "directive", type: i7.NativeElementInjectorDirective, selector: "[ngModel], [formControl], [formControlName]" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }] }); }
|
|
3315
2663
|
}
|
|
3316
2664
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: FileUploadComponent, decorators: [{
|
|
3317
2665
|
type: Component,
|
|
3318
|
-
args: [{ selector: 'BBSF-FileUpload', standalone: false, template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType === 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!-- Label -->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!-- Required asterisk -->\r\n <span *ngIf=\"options.isRequired && !options.isReadonly && (options.showAsterisk || true)\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!-- Drop zone enabled -->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" [id]=\"options.name\"\r\n [attr.multiple]=\"options.isMultipleFile ? 'multiple' : null\"\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputControl.click()\">\r\n\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <!-- Upload icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <!-- Instruction text -->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ utilityService.getResourceValue('DragAndDropHere') }}\r\n </div>\r\n\r\n <!-- Validation messages -->\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\">\r\n </div>\r\n\r\n <div class=\"bbsf-validation-msg text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\">\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden file input -->\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n [attr.multiple]=\"options.isMultipleFile ? 'multiple' : null\" name=\"file\" type=\"file\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType === 1 ? '' : 'col-md-9'\" [id]=\"options.name\"\r\n #fileInputControl [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- Click to upload (no drop zone) -->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <!-- Upload icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n\r\n <!-- Upload text -->\r\n <div class=\"bbsf-validation-msg text-center\">\r\n {{ utilityService.getResourceValue('Upload') }}\r\n </div>\r\n\r\n <!-- Validation messages -->\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\">\r\n </div>\r\n\r\n <div class=\"bbsf-validation-msg text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\">\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden file input -->\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n [attr.multiple]=\"options.isMultipleFile ? 'multiple' : null\" name=\"file\" type=\"file\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType === 1 ? '' : 'col-md-9'\" [id]=\"options.name\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- Read-only state with no files -->\r\n <div *ngIf=\"options.isReadonly && (!options.value || (uploader.queue && uploader.queue.length === 0))\">\r\n <span class=\"readonly-view\">{{ utilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!-- Uploaded files list -->\r\n <div class=\"uploaded-items\" *ngIf=\"shouldShowFileList()\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue; trackBy: trackByFunction\">\r\n\r\n <!-- Async upload completed files -->\r\n <ng-container *ngIf=\"item?.progress === 100 && options.isUploadFileAsync\">\r\n <!-- Download link - always visible -->\r\n <button *ngIf=\"getFileDownloadUrl(item); else noUrlTemplate\" type=\"button\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" (click)=\"downloadFile(item)\"\r\n [title]=\"'Download ' + getFileName(item)\">\r\n <span class=\"file-name\">{{ getFileName(item) }}</span>\r\n </button>\r\n\r\n <!-- File name display when no URL available -->\r\n <ng-template #noUrlTemplate>\r\n <span class=\"btn-download-file btn-sm btn-progress-upload\" [title]=\"getFileName(item)\">\r\n <span class=\"file-name\">{{ getFileName(item) }}</span>\r\n </span>\r\n </ng-template>\r\n\r\n <!-- Remove button - only show when not readonly and not disabled -->\r\n <button *ngIf=\"isRemoveEnabled()\" class=\"btn btn-download-file btn-sm\" type=\"button\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\" [attr.aria-label]=\"'Remove ' + getFileName(item)\"\r\n [title]=\"'Remove ' + getFileName(item)\">\r\n <!-- Delete icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n\r\n <!-- Sync upload files -->\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <!-- Download link - always visible -->\r\n <button type=\"button\" class=\"btn btn-download-file btn-sm\" (click)=\"downloadFile(item)\"\r\n [title]=\"'Download ' + getFileName(item)\">\r\n <!-- Download icon -->\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ getFileName(item) }}</span>\r\n </button>\r\n\r\n <!-- Remove button - only show when not readonly and not disabled -->\r\n <button *ngIf=\"isRemoveEnabled()\" class=\"btn btn-download-file btn-sm btn-danger\" type=\"button\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\" [attr.aria-label]=\"'Remove ' + getFileName(item)\"\r\n [title]=\"'Remove ' + getFileName(item)\">\r\n <i class=\"fa fa-times px-0\" aria-hidden=\"true\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!-- File upload progress indicators -->\r\n <div *ngFor=\"let item of uploader.queue; trackBy: trackByFunction\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync && !options.isReadonly\">\r\n\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ getFileName(item) }}</h4>\r\n <button *ngIf=\"isRemoveEnabled()\" type=\"button\" class=\"btn-cancel-upload\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\"\r\n [attr.aria-label]=\"'Cancel upload for ' + getFileName(item)\">\r\n <!-- Cancel icon -->\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </button>\r\n </div>\r\n\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" [attr.aria-valuenow]=\"item?.progress\" aria-valuemin=\"0\"\r\n aria-valuemax=\"100\" [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\"\r\n *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Validation and description section -->\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- Validation messages -->\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n <span [innerHTML]=\"getErrorValidation(fileUploadFormControl.errors | keyvalue)\"></span>\r\n </div>\r\n\r\n <!-- Control description -->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription\">\r\n {{ options.labelDescription }}\r\n </div>\r\n\r\n <!-- Reset error state -->\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>" }]
|
|
2666
|
+
args: [{ selector: 'BBSF-FileUpload', standalone: false, template: "<div class=\"form-group bbsf-control bbsf-file-upload\" [formGroup]=\"group\">\r\n <div [ngClass]=\"options.viewType == 1 ? 'bbsf-vertical' : 'bbsf-horizontal'\">\r\n <!--label-->\r\n <label [hidden]=\"options.hideLabel\" class=\"bbsf-label {{ options.labelExtraClasses }}\">\r\n {{ options.labelValue }}\r\n <!--Asterisk-->\r\n <span *ngIf=\"((options.showAsterisk && options.isRequired) || options.isRequired) && !options.isReadonly\"\r\n class=\"text-danger\">*</span>\r\n </label>\r\n <!--Allow dropZone-->\r\n <div ng2FileDrop class=\"bbsf-input-container {{ options.extraClasses }}\"\r\n *ngIf=\"options.isDropZone && !(options.isMultipleFile == false && uploader.queue.length > 0) && !options.isReadonly\"\r\n [ngClass]=\"{ 'another-file-over-class': hasAnotherDropZoneOver }\" (onFileDrop)=\"onFileChange()\"\r\n (fileOver)=\"fileOverAnother($event)\" [uploader]=\"uploader\" [accept]=\"acceptedType\" id=\"{{ options.name }}\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" aria-describedby=\"email-error\" aria-invalid=\"true\"\r\n type=\"file\" #fileInput [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\"\r\n (click)=\"fileInputControl.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg validation-msg-header text-center\">\r\n {{ UtilityService.getResourceValue('DragAndDropHere') }}\r\n </div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{ options.name }}\" #fileInputControl\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!--Not allowed dropZone-->\r\n <div class=\"bbsf-input-container\" *ngIf=\"!options.isDropZone && !isHideInput() && !options.isReadonly\"\r\n (click)=\"fileInput.click()\">\r\n <div class=\"dropzone-label\">\r\n <div class=\"svg-and-validation\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"70\" height=\"70\" viewBox=\"0 0 70 70\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M58.333 48.8332C61.8957 45.8908 64.1663 41.4397 64.1663 36.4583C64.1663 27.5988 56.9843 20.4167 48.1247 20.4167C47.4874 20.4167 46.8912 20.0842 46.5675 19.5351C42.7641 13.0808 35.7417 8.75 27.708 8.75C15.6268 8.75 5.83301 18.5438 5.83301 30.625C5.83301 36.6511 8.26974 42.1082 12.2116 46.0644\"\r\n stroke=\"#4B5489\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M23.333 46.6667L34.9997 35M34.9997 35L46.6663 46.6667M34.9997 35V61.25\" stroke=\"#4B5489\"\r\n stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n <!--Validation text-->\r\n <div class=\"bbsf-validation-msg text-center\">{{ UtilityService.getResourceValue('Upload') }}</div>\r\n <div class=\"bbsf-validation-msg text-center\" *ngIf=\"validationMessage\" [innerHTML]=\"validationMessage\"></div>\r\n <div class=\"bbsf-validation-msg ng-star-inserted text-center text-danger\"\r\n *ngIf=\"validationCountMessage && options.isMultipleFile && options.maxNoOfFiles > 0\"\r\n [innerHTML]=\"validationCountMessage\"></div>\r\n </div>\r\n </div>\r\n <input ng2FileSelect [uploader]=\"uploader\" [accept]=\"acceptedType\"\r\n class=\"fileSelector customFileUploadPlacment hidden v-required-multiplefiles d-none\"\r\n multiple=\"{{ options.isMultipleFile ? 'multiple' : '' }}\" name=\"file\" type=\"file\" value=\"\" autocomplete=\"off\"\r\n (change)=\"onFileChange()\" [ngClass]=\"options.viewType == 1 ? '' : 'col-md-9'\" id=\"{{ options.name }}\"\r\n aria-describedby=\"email-error\" aria-invalid=\"true\" formControlName=\"{{ options.name }}\" #fileInput\r\n [class.is-invalid]=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\" />\r\n </div>\r\n <!-- readonly -->\r\n <div *ngIf=\"options.isReadonly && !options.value\">\r\n <span class=\"readonly-view\">{{ UtilityService.getResourceValue('NA') }}</span>\r\n </div>\r\n </div>\r\n <!--items uploaded-->\r\n <div class=\"uploaded-items\">\r\n <div class=\"btn-group\" *ngFor=\"let item of uploader.queue\">\r\n <ng-container *ngIf=\"item?.progress == 100 && options.isUploadFileAsync\">\r\n <a *ngIf=\"item?.file?.rawFile['url']\" href=\"{{ item?.file?.rawFile['url'] }}\"\r\n class=\"btn-download-file btn-sm btn-progress-upload\" download>\r\n <span class=\"file-name\">{{ item?.file?.name }}</span>\r\n </a>\r\n <a *ngIf=\"item?.file?.rawFile['url'] == null\" class=\"btn-download-file btn-sm btn-progress-upload\">\r\n <span class=\"file-name\">{{ item?.file?.name }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\r\n <path opacity=\"0.4\"\r\n d=\"M9.33301 3.70584V3.26663C9.33301 2.65166 9.33301 2.34419 9.20587 2.1093C9.09405 1.9027 8.91555 1.73471 8.69604 1.62944C8.44647 1.50977 8.11977 1.50977 7.46638 1.50977H6.53305C5.87965 1.50977 5.55296 1.50977 5.30339 1.62944C5.08387 1.73471 4.90539 1.9027 4.79354 2.1093C4.66638 2.34419 4.66638 2.65166 4.66638 3.26663V3.70584\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path\r\n d=\"M1.75 3.70605H12.25M11.0834 3.70605V9.8551C11.0834 10.7775 11.0834 11.2387 10.8926 11.591C10.7248 11.901 10.4571 12.1529 10.1278 12.3109C9.75345 12.4904 9.26345 12.4904 8.28334 12.4904H5.71666C4.73658 12.4904 4.24653 12.4904 3.87218 12.3109C3.5429 12.1529 3.27519 11.901 3.10741 11.591C2.91666 11.2387 2.91666 10.7775 2.91666 9.8551V3.70605\"\r\n stroke=\"#D83731\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n </ng-container>\r\n <ng-container *ngIf=\"!options.isUploadFileAsync\">\r\n <a href=\"{{ item?.file?.rawFile['url'] }}\" class=\"btn btn-download-file btn-sm\" download>\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M21 22H3C2.4 22 2 21.6 2 21C2 20.4 2.4 20 3 20H21C21.6 20 22 20.4 22 21C22 21.6 21.6 22 21 22ZM13 13.4V3C13 2.4 12.6 2 12 2C11.4 2 11 2.4 11 3V13.4H13Z\"\r\n fill=\"currentColor\"></path>\r\n <path opacity=\"0.3\" d=\"M7 13.4H17L12.7 17.7C12.3 18.1 11.7 18.1 11.3 17.7L7 13.4Z\" fill=\"currentColor\">\r\n </path>\r\n </svg>\r\n <span class=\"file-name\">{{ item?.file?.name }}</span>\r\n </a>\r\n <button *ngIf=\"!options.isReadonly\" class=\"btn btn-download-file btn-sm btn-danger\"\r\n (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <i class=\"fa fa-times px-0\"></i>\r\n </button>\r\n </ng-container>\r\n </div>\r\n </div>\r\n <!--progress bar file upload-->\r\n <div *ngFor=\"let item of uploader.queue\">\r\n <div class=\"upload-items\" [ngClass]=\"{ 'mt-4': options.isMultipleFile == true }\"\r\n *ngIf=\"item?.progress < 100 && options.isUploadFileAsync\">\r\n <div class=\"upload-items-toolbar\">\r\n <h4>{{ item?.file?.name }}</h4>\r\n <span (click)=\"item.remove(); removeFromControlValue(item)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 18 18\" fill=\"none\">\r\n <g clip-path=\"url(#clip0_1324_13216)\">\r\n <path opacity=\"0.4\"\r\n d=\"M9 16.5C13.1421 16.5 16.5 13.1421 16.5 9C16.5 4.85786 13.1421 1.5 9 1.5C4.85786 1.5 1.5 4.85786 1.5 9C1.5 13.1421 4.85786 16.5 9 16.5Z\"\r\n stroke=\"#DBE1F0\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n <path d=\"M11.25 6.75L6.75 11.25M6.75 6.75L11.25 11.25\" stroke=\"#DBE1F0\" stroke-width=\"2\"\r\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </g>\r\n <defs>\r\n <clipPath id=\"clip0_1324_13216\">\r\n <rect width=\"18\" height=\"18\" fill=\"white\" />\r\n </clipPath>\r\n </defs>\r\n </svg>\r\n </span>\r\n </div>\r\n <div class=\"progress\">\r\n <div class=\"progress-bar\" role=\"progressbar\" aria-valuenow=\"70\" aria-valuemin=\"0\" aria-valuemax=\"100\"\r\n [class.file-uploaded]=\"item?.progress < 100\" [style.width.%]=\"item?.progress\" *ngIf=\"item?.progress > 0\">\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"subtext-container\" *ngIf=\"!options.isReadonly\">\r\n <!-- required text-->\r\n <div class=\"bbsf-validation\" *ngIf=\"fileUploadFormControl.invalid && fileUploadFormControl.touched\">\r\n {{ getErrorValidation(fileUploadFormControl.errors | keyvalue) }}\r\n </div>\r\n <!-- LabelDescription-->\r\n <div class=\"bbsf-control-desc\" *ngIf=\"options.labelDescription != null\">{{ options.labelDescription }}</div>\r\n <div *ngIf=\"(group.valid && group.dirty && group.touched) || (group.untouched && group.invalid && group.dirty)\">\r\n {{ resetError() }}\r\n </div>\r\n </div>\r\n</div>" }]
|
|
3319
2667
|
}], ctorParameters: () => [{ type: i2.ControlContainer, decorators: [{
|
|
3320
2668
|
type: Optional
|
|
3321
2669
|
}] }, { type: i2.FormGroupDirective }, { type: ControlUtility }, { type: i3.UtilityService }, { type: i3.ControlValidationService }, { type: GlobalSettings }, { type: FileUploadService }], propDecorators: { fileInput: [{
|