@progress/kendo-angular-upload 17.0.0-develop.9 → 17.0.1-develop.1

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.
Files changed (87) hide show
  1. package/common/action-buttons-layout.d.ts +1 -1
  2. package/common/base.d.ts +1 -1
  3. package/dropzone-external.directive.d.ts +1 -1
  4. package/dropzone-internal.directive.d.ts +1 -1
  5. package/dropzone.component.d.ts +1 -1
  6. package/{esm2020 → esm2022}/common/base.mjs +96 -67
  7. package/{esm2020 → esm2022}/dropzone-base.mjs +13 -9
  8. package/{esm2020 → esm2022}/dropzone-external.directive.mjs +16 -5
  9. package/{esm2020 → esm2022}/dropzone-internal.directive.mjs +14 -6
  10. package/{esm2020 → esm2022}/dropzone.component.mjs +38 -19
  11. package/{esm2020 → esm2022}/dropzone.service.mjs +3 -3
  12. package/{esm2020 → esm2022}/events/cancel-event.mjs +4 -0
  13. package/{esm2020 → esm2022}/events/error-event.mjs +12 -0
  14. package/{esm2020 → esm2022}/events/pause-event.mjs +4 -0
  15. package/{esm2020 → esm2022}/events/preventable-event.mjs +1 -3
  16. package/{esm2020 → esm2022}/events/remove-event.mjs +12 -0
  17. package/{esm2020 → esm2022}/events/resume-event.mjs +4 -0
  18. package/{esm2020 → esm2022}/events/select-event.mjs +4 -0
  19. package/{esm2020 → esm2022}/events/success-event.mjs +12 -0
  20. package/{esm2020 → esm2022}/events/upload-event.mjs +35 -0
  21. package/{esm2020 → esm2022}/events/upload-progress-event.mjs +8 -0
  22. package/{esm2020 → esm2022}/file-select.directive.mjs +17 -8
  23. package/{esm2020 → esm2022}/fileselect.component.mjs +60 -42
  24. package/{esm2020 → esm2022}/fileselect.module.mjs +8 -8
  25. package/{esm2020 → esm2022}/localization/custom-messages.component.mjs +12 -11
  26. package/{esm2020 → esm2022}/localization/localized-messages.directive.mjs +9 -8
  27. package/esm2022/localization/messages.mjs +143 -0
  28. package/{esm2020 → esm2022}/navigation.service.mjs +17 -14
  29. package/{esm2020 → esm2022}/package-metadata.mjs +2 -2
  30. package/{esm2020 → esm2022}/rendering/file-list-item-action-button.component.mjs +15 -9
  31. package/{esm2020 → esm2022}/rendering/file-list-item-base.mjs +7 -4
  32. package/{esm2020 → esm2022}/rendering/file-list-item.mjs +10 -5
  33. package/{esm2020 → esm2022}/rendering/file-list-multiple-items.component.mjs +18 -13
  34. package/{esm2020 → esm2022}/rendering/file-list-single-item.component.mjs +16 -12
  35. package/{esm2020 → esm2022}/rendering/file-list.component.mjs +14 -5
  36. package/{esm2020 → esm2022}/rendering/upload-action-buttons.component.mjs +17 -10
  37. package/{esm2020 → esm2022}/rendering/upload-status-total.component.mjs +14 -8
  38. package/esm2022/templates/file-info-template.directive.mjs +40 -0
  39. package/esm2022/templates/file-template.directive.mjs +40 -0
  40. package/{esm2020 → esm2022}/types/chunk-map.mjs +1 -0
  41. package/{esm2020 → esm2022}/types/file-map.mjs +1 -0
  42. package/{esm2020 → esm2022}/upload.component.mjs +113 -95
  43. package/{esm2020 → esm2022}/upload.module.mjs +8 -8
  44. package/{esm2020 → esm2022}/upload.service.mjs +50 -49
  45. package/{esm2020 → esm2022}/uploads.module.mjs +8 -8
  46. package/{fesm2020 → fesm2022}/progress-kendo-angular-upload.mjs +822 -442
  47. package/file-select.directive.d.ts +1 -1
  48. package/fileselect.component.d.ts +1 -1
  49. package/localization/messages.d.ts +1 -1
  50. package/package.json +16 -22
  51. package/rendering/file-list-item-action-button.component.d.ts +1 -1
  52. package/rendering/file-list-item.d.ts +1 -1
  53. package/rendering/file-list-multiple-items.component.d.ts +1 -1
  54. package/rendering/file-list-single-item.component.d.ts +1 -1
  55. package/rendering/file-list.component.d.ts +1 -1
  56. package/rendering/upload-action-buttons.component.d.ts +1 -1
  57. package/rendering/upload-status-total.component.d.ts +1 -1
  58. package/schematics/ngAdd/index.js +4 -4
  59. package/templates/file-info-template.directive.d.ts +17 -1
  60. package/templates/file-template.directive.d.ts +17 -1
  61. package/types/direction.d.ts +1 -1
  62. package/types/operation-type.d.ts +1 -1
  63. package/upload.component.d.ts +1 -1
  64. package/upload.service.d.ts +1 -1
  65. package/esm2020/localization/messages.mjs +0 -59
  66. package/esm2020/templates/file-info-template.directive.mjs +0 -23
  67. package/esm2020/templates/file-template.directive.mjs +0 -23
  68. package/fesm2015/progress-kendo-angular-upload.mjs +0 -4808
  69. /package/{esm2020 → esm2022}/common/action-buttons-layout.mjs +0 -0
  70. /package/{esm2020 → esm2022}/common/util.mjs +0 -0
  71. /package/{esm2020 → esm2022}/common/validation-util.mjs +0 -0
  72. /package/{esm2020 → esm2022}/directives.mjs +0 -0
  73. /package/{esm2020 → esm2022}/events/clear-event.mjs +0 -0
  74. /package/{esm2020 → esm2022}/events.mjs +0 -0
  75. /package/{esm2020 → esm2022}/index.mjs +0 -0
  76. /package/{esm2020 → esm2022}/progress-kendo-angular-upload.mjs +0 -0
  77. /package/{esm2020 → esm2022}/types/async-settings.mjs +0 -0
  78. /package/{esm2020 → esm2022}/types/chunk-info.mjs +0 -0
  79. /package/{esm2020 → esm2022}/types/chunk-metadata.mjs +0 -0
  80. /package/{esm2020 → esm2022}/types/chunk-settings.mjs +0 -0
  81. /package/{esm2020 → esm2022}/types/direction.mjs +0 -0
  82. /package/{esm2020 → esm2022}/types/file-groups.mjs +0 -0
  83. /package/{esm2020 → esm2022}/types/file-info.mjs +0 -0
  84. /package/{esm2020 → esm2022}/types/file-restrictions.mjs +0 -0
  85. /package/{esm2020 → esm2022}/types/file-state.mjs +0 -0
  86. /package/{esm2020 → esm2022}/types/operation-type.mjs +0 -0
  87. /package/{esm2020 → esm2022}/types.mjs +0 -0
@@ -1,4808 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2024 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import * as i1 from '@angular/common/http';
6
- import { HttpHeaders, HttpRequest, HttpEventType, HttpResponse } from '@angular/common/http';
7
- import * as i0 from '@angular/core';
8
- import { EventEmitter, Injectable, Directive, ElementRef, ContentChild, ViewChild, Input, HostBinding, Output, Component, HostListener, ViewChildren, Inject, forwardRef, isDevMode, NgModule } from '@angular/core';
9
- import { guid, Keys, isControlRequired, isChanged, isDocumentAvailable, KendoInput, ResizeBatchService } from '@progress/kendo-angular-common';
10
- import { fileAudioIcon, fileVideoIcon, fileImageIcon, fileTxtIcon, filePresentationIcon, fileDataIcon, fileProgrammingIcon, filePdfIcon, fileConfigIcon, fileZipIcon, fileDiscImageIcon, arrowRotateCwSmallIcon, playSmIcon, pauseSmIcon, cancelIcon, xIcon, copyIcon, fileIcon, checkIcon, exclamationCircleIcon, uploadIcon } from '@progress/kendo-svg-icons';
11
- import { NgControl, NG_VALUE_ACCESSOR } from '@angular/forms';
12
- import * as i1$1 from '@progress/kendo-angular-l10n';
13
- import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
14
- import { fromEvent, merge } from 'rxjs';
15
- import { filter } from 'rxjs/operators';
16
- import { validatePackage } from '@progress/kendo-licensing';
17
- import { trigger, state, style, transition, animate } from '@angular/animations';
18
- import { ButtonComponent } from '@progress/kendo-angular-buttons';
19
- import { NgIf, NgFor, NgClass, NgTemplateOutlet } from '@angular/common';
20
- import { IconWrapperComponent, IconsService } from '@progress/kendo-angular-icons';
21
- import { ProgressBarComponent } from '@progress/kendo-angular-progressbar';
22
- import { PopupService } from '@progress/kendo-angular-popup';
23
-
24
- /**
25
- * Lists the possible states of a file.
26
- */
27
- var FileState;
28
- (function (FileState) {
29
- /**
30
- * The file upload process has failed.
31
- */
32
- FileState[FileState["Failed"] = 0] = "Failed";
33
- /**
34
- * An initially selected fake file without a set state.
35
- */
36
- FileState[FileState["Initial"] = 1] = "Initial";
37
- /**
38
- * The file is selected.
39
- */
40
- FileState[FileState["Selected"] = 2] = "Selected";
41
- /**
42
- * The file is successfully uploaded.
43
- */
44
- FileState[FileState["Uploaded"] = 3] = "Uploaded";
45
- /**
46
- * The file is in the process of uploading.
47
- */
48
- FileState[FileState["Uploading"] = 4] = "Uploading";
49
- /**
50
- * The file upload process has been paused.
51
- */
52
- FileState[FileState["Paused"] = 5] = "Paused";
53
- })(FileState || (FileState = {}));
54
-
55
- /**
56
- * @hidden
57
- */
58
- class FileMap {
59
- constructor() {
60
- this._files = {};
61
- }
62
- add(file) {
63
- const uid = file.uid;
64
- if (this.has(uid)) {
65
- if (file.validationErrors && file.validationErrors.length > 0) {
66
- this._files[uid].unshift(file);
67
- }
68
- else {
69
- this._files[uid].push(file);
70
- }
71
- }
72
- else {
73
- this._files[uid] = [file];
74
- }
75
- }
76
- remove(uid) {
77
- if (this.has(uid)) {
78
- this._files[uid] = null;
79
- delete this._files[uid];
80
- }
81
- }
82
- clear() {
83
- const allFiles = this._files;
84
- for (const uid in allFiles) {
85
- if (allFiles.hasOwnProperty(uid)) {
86
- for (const file of allFiles[uid]) {
87
- if (file.httpSubscription) {
88
- file.httpSubscription.unsubscribe();
89
- }
90
- }
91
- allFiles[uid] = null;
92
- delete allFiles[uid];
93
- }
94
- }
95
- }
96
- has(uid) {
97
- return uid in this._files;
98
- }
99
- get(uid) {
100
- return this._files[uid];
101
- }
102
- setFilesState(files, state) {
103
- for (const file of files) {
104
- this.setFilesStateByUid(file.uid, state);
105
- }
106
- }
107
- setFilesStateByUid(uid, state) {
108
- this.get(uid).forEach((f) => {
109
- f.state = state;
110
- });
111
- }
112
- get count() {
113
- return Object.getOwnPropertyNames(this._files).length;
114
- }
115
- get files() {
116
- const initial = this._files;
117
- const transformed = [];
118
- for (const uid in initial) {
119
- if (initial.hasOwnProperty(uid)) {
120
- transformed.push(initial[uid]);
121
- }
122
- }
123
- return transformed;
124
- }
125
- get filesFlat() {
126
- const initial = this._files;
127
- const transformed = [];
128
- for (const uid in initial) {
129
- if (initial.hasOwnProperty(uid)) {
130
- const current = initial[uid];
131
- current.forEach((file) => {
132
- transformed.push(file);
133
- });
134
- }
135
- }
136
- return transformed;
137
- }
138
- get filesToUpload() {
139
- const files = this._files;
140
- const notUploaded = [];
141
- for (const uid in files) {
142
- if (files.hasOwnProperty(uid)) {
143
- const currentFiles = files[uid];
144
- let currentFilesValid = true;
145
- for (const file of currentFiles) {
146
- if (file.state !== FileState.Selected || (file.validationErrors && file.validationErrors.length > 0)) {
147
- currentFilesValid = false;
148
- }
149
- }
150
- if (currentFilesValid) {
151
- notUploaded.push(currentFiles);
152
- }
153
- }
154
- }
155
- return notUploaded;
156
- }
157
- get firstFileToUpload() {
158
- const files = this._files;
159
- for (const uid in files) {
160
- if (files.hasOwnProperty(uid)) {
161
- const currentFiles = files[uid];
162
- let currentFilesValid = true;
163
- for (const file of currentFiles) {
164
- if (file.state !== FileState.Selected || (file.validationErrors && file.validationErrors.length > 0)) {
165
- currentFilesValid = false;
166
- }
167
- }
168
- if (currentFilesValid) {
169
- return currentFiles;
170
- }
171
- }
172
- }
173
- return null;
174
- }
175
- getFilesWithState(state) {
176
- return this.filesFlat.filter(file => file.state === state);
177
- }
178
- hasFileWithState(fileStates) {
179
- const files = this._files;
180
- for (const uid in files) {
181
- if (files.hasOwnProperty(uid)) {
182
- const currentFiles = files[uid];
183
- for (const file of currentFiles) {
184
- if (fileStates.indexOf(file.state) >= 0) {
185
- return true;
186
- }
187
- }
188
- }
189
- }
190
- return false;
191
- }
192
- }
193
-
194
- /**
195
- * Arguments for the `cancel` event. The `cancel` event fires when
196
- * the user cancels the process of uploading a file or a batch of files.
197
- *
198
- * ```ts-no-run
199
- * @Component({
200
- * selector: 'my-upload',
201
- * template: `
202
- * <p>Click the <span class='k-icon k-font-icon k-i-cancel'></span> icon during upload to trigger the event</p>
203
- * <kendo-upload
204
- * [saveUrl]="uploadSaveUrl"
205
- * [removeUrl]="uploadRemoveUrl"
206
- * (cancel)="cancelEventHandler($event)">
207
- * </kendo-upload>
208
- * `
209
- * })
210
- * export class UploadComponent {
211
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
212
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
213
- *
214
- * cancelEventHandler(e: CancelEvent) {
215
- * console.log('Canceling file upload', e.files);
216
- * }
217
- * }
218
- * ```
219
- */
220
- class CancelEvent {
221
- /**
222
- * @hidden
223
- * Constructs the event arguments for the `cancel` event.
224
- * @param files - The list of the files that were going to be uploaded.
225
- */
226
- constructor(files) {
227
- this.files = files;
228
- }
229
- }
230
-
231
- /**
232
- * @hidden
233
- */
234
- class PreventableEvent {
235
- constructor() {
236
- this.prevented = false;
237
- }
238
- /**
239
- * Prevents the default action for a specified event.
240
- * In this way, the source component suppresses the built-in behavior that follows the event.
241
- */
242
- preventDefault() {
243
- this.prevented = true;
244
- }
245
- /**
246
- * If the event is prevented by any of its subscribers, returns `true`.
247
- *
248
- * @returns `true` if the default action was prevented. Otherwise, returns `false`.
249
- */
250
- isDefaultPrevented() {
251
- return this.prevented;
252
- }
253
- }
254
-
255
- /**
256
- * Arguments for the `clear` event. The `clear` event fires when
257
- * the **Clear** button is clicked. At this point, the selected files are about to be cleared.
258
- *
259
- * ```ts-no-run
260
- * @Component({
261
- * selector: 'my-upload',
262
- * template: `
263
- * <kendo-upload
264
- * [autoUpload]="false"
265
- * [saveUrl]="uploadSaveUrl"
266
- * [removeUrl]="uploadRemoveUrl"
267
- * (clear)="clearEventHandler($event)">
268
- * </kendo-upload>
269
- * `
270
- * })
271
- * export class UploadComponent {
272
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
273
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
274
- *
275
- * clearEventHandler(e: ClearEvent) {
276
- * console.log('Clearing the file upload');
277
- * }
278
- * }
279
- * ```
280
- */
281
- class ClearEvent extends PreventableEvent {
282
- /**
283
- * @hidden
284
- * Constructs the event arguments for the `clear` event.
285
- */
286
- constructor() { super(); }
287
- }
288
-
289
- /**
290
- * Arguments for the `error` event. The `error` event fires when
291
- * an `upload` or `remove` operation fails.
292
- *
293
- * ```ts-no-run
294
- * @Component({
295
- * selector: 'my-upload',
296
- * template: `
297
- * <kendo-upload
298
- * [saveUrl]="uploadSaveUrl"
299
- * [removeUrl]="uploadRemoveUrl"
300
- * (error)="errorEventHandler($event)">
301
- * </kendo-upload>
302
- * `
303
- * })
304
- * export class UploadComponent {
305
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
306
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
307
- *
308
- * errorEventHandler(e: ErrorEvent) {
309
- * console.log('An error occurred');
310
- * }
311
- * }
312
- * ```
313
- */
314
- class ErrorEvent {
315
- /**
316
- * @hidden
317
- * Constructs the event arguments for the `error` event.
318
- *
319
- * @param files - The list of the files that failed to be uploaded or removed.
320
- * @param operation - The operation type (`upload` or `remove`).
321
- * @param response - The response object returned by the server.
322
- */
323
- constructor(files, operation, response) {
324
- this.files = files;
325
- this.operation = operation;
326
- this.response = response;
327
- }
328
- }
329
-
330
- /**
331
- * Arguments for the `pause` event. The `pause` event fires when the user
332
- * pauses a file that is currently uploading.
333
- *
334
- * ```ts-no-run
335
- * @Component({
336
- * selector: 'my-upload',
337
- * template: `
338
- * <kendo-upload
339
- * [chunkable]="true"
340
- * [saveUrl]="uploadSaveUrl"
341
- * [removeUrl]="uploadRemoveUrl"
342
- * (pause)="pauseEventHandler($event)">
343
- * </kendo-upload>
344
- * `
345
- * })
346
- * export class UploadComponent {
347
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
348
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
349
- *
350
- * pauseEventHandler(ev: PauseEvent) {
351
- * console.log('File paused');
352
- * }
353
- * }
354
- * ```
355
- *
356
- */
357
- class PauseEvent {
358
- /**
359
- * @hidden
360
- * Constructs the event arguments for the `pause` event.
361
- * @param file - The file that is going to be paused.
362
- */
363
- constructor(file) {
364
- this.file = file;
365
- }
366
- }
367
-
368
- /**
369
- * Arguments for the `remove` event. The `remove` event fires when an uploaded
370
- * or selected file is about to be removed. If you cancel the event, the removal is prevented.
371
- *
372
- * ```ts-no-run
373
- * @Component({
374
- * selector: 'my-upload',
375
- * template: `
376
- * <kendo-upload
377
- * [saveUrl]="uploadSaveUrl"
378
- * [removeUrl]="uploadRemoveUrl"
379
- * (remove)="removeEventHandler($event)">
380
- * </kendo-upload>
381
- * `
382
- * })
383
- * export class UploadComponent {
384
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
385
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
386
- *
387
- * removeEventHandler(e: RemoveEvent) {
388
- * console.log('Removing a file');
389
- * }
390
- * }
391
- * ```
392
- */
393
- class RemoveEvent extends PreventableEvent {
394
- /**
395
- * @hidden
396
- * Constructs the event arguments for the `remove` event.
397
- * @param files - The list of the files that will be removed.
398
- * @param headers - The headers of the request.
399
- */
400
- constructor(files, headers) {
401
- super();
402
- this.files = files;
403
- this.headers = headers;
404
- }
405
- }
406
-
407
- /**
408
- * Arguments for the `resume` event. The `resume` event fires when the user
409
- * resumes the upload of a file that has been previously paused.
410
- *
411
- * ```ts-no-run
412
- * @Component({
413
- * selector: 'my-upload',
414
- * template: `
415
- * <kendo-upload
416
- * [chunkable]="true"
417
- * [saveUrl]="uploadSaveUrl"
418
- * [removeUrl]="uploadRemoveUrl"
419
- * (resume)="resumeEventHandler($event)">
420
- * </kendo-upload>
421
- * `
422
- * })
423
- * export class UploadComponent {
424
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
425
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
426
- *
427
- * resumeEventHandler(ev: ResumeEvent) {
428
- * console.log('File resumed');
429
- * }
430
- * }
431
- * ```
432
- *
433
- */
434
- class ResumeEvent {
435
- /**
436
- * @hidden
437
- * Constructs the event arguments for the `resume` event.
438
- * @param file - The file that is going to be resumed.
439
- */
440
- constructor(file) {
441
- this.file = file;
442
- }
443
- }
444
-
445
- /**
446
- * Arguments for the `select` event. The `select` event fires when the user
447
- * selects a file or multiple files for upload. If you cancel the event, the selection is prevented.
448
- *
449
- * ```ts-no-run
450
- * @Component({
451
- * selector: 'my-upload',
452
- * template: `
453
- * <kendo-upload
454
- * [saveUrl]="uploadSaveUrl"
455
- * [removeUrl]="uploadRemoveUrl"
456
- * (select)="selectEventHandler($event)">
457
- * </kendo-upload>
458
- * `
459
- * })
460
- * export class UploadComponent {
461
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
462
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
463
- *
464
- * selectEventHandler(e: SelectEvent) {
465
- * console.log('File selected');
466
- * }
467
- * }
468
- * ```
469
- */
470
- class SelectEvent extends PreventableEvent {
471
- /**
472
- * @hidden
473
- * Constructs the event arguments for the `select` event.
474
- * @param files - The list of the selected files.
475
- */
476
- constructor(files) {
477
- super();
478
- this.files = files;
479
- }
480
- }
481
-
482
- /**
483
- * Arguments for the `success` event. The `success` event fires when
484
- * the selected files are successfully uploaded or removed.
485
- *
486
- * ```ts-no-run
487
- * @Component({
488
- * selector: 'my-upload',
489
- * template: `
490
- * <kendo-upload
491
- * [saveUrl]="uploadSaveUrl"
492
- * [removeUrl]="uploadRemoveUrl"
493
- * (success)="successEventHandler($event)">
494
- * </kendo-upload>
495
- * `
496
- * })
497
- * export class UploadComponent {
498
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
499
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
500
- *
501
- * successEventHandler(e: SuccessEvent) {
502
- * console.log('The ' + e.operation + ' was successful!');
503
- * }
504
- * }
505
- * ```
506
- */
507
- class SuccessEvent extends PreventableEvent {
508
- /**
509
- * @hidden
510
- * Constructs the event arguments for the `success` event.
511
- * @param files - The list of the files that were uploaded or removed.
512
- * @param operation - The operation type (`upload` or `remove`).
513
- * @param response - The response object returned by the server.
514
- */
515
- constructor(files, operation, response) {
516
- super();
517
- this.files = files;
518
- this.operation = operation;
519
- this.response = response;
520
- }
521
- }
522
-
523
- /**
524
- * Arguments for the `upload` event. The `upload` event fires when one or more files are about
525
- * to be uploaded. If you cancel the event, the upload is prevented. You can add headers to the request.
526
- *
527
- * ```ts-no-run
528
- * @Component({
529
- * selector: 'my-upload',
530
- * template: `
531
- * <kendo-upload
532
- * [saveUrl]="uploadSaveUrl"
533
- * [removeUrl]="uploadRemoveUrl"
534
- * (upload)="uploadEventHandler($event)">
535
- * </kendo-upload>
536
- * `
537
- * })
538
- * export class UploadComponent {
539
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
540
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
541
- *
542
- * uploadEventHandler(e: UploadEvent) {
543
- * e.headers = e.headers.append('X-Foo', 'Bar');
544
- * }
545
- * }
546
- * ```
547
- */
548
- class UploadEvent extends PreventableEvent {
549
- /**
550
- * @hidden
551
- * Constructs the event arguments for the `upload` event.
552
- * @param files - The list of the files that will be uploaded.
553
- * @param headers - The headers of the request.
554
- */
555
- constructor(files, headers) {
556
- super();
557
- this.files = files;
558
- this.headers = headers;
559
- }
560
- }
561
-
562
- /**
563
- * Arguments for the `uploadprogress` event. The `uploadprogress` event
564
- * fires when the files are in the process of uploading.
565
- *
566
- * ```ts-no-run
567
- * @Component({
568
- * selector: 'my-upload',
569
- * template: `
570
- * <kendo-upload
571
- * [saveUrl]="uploadSaveUrl"
572
- * [removeUrl]="uploadRemoveUrl"
573
- * (uploadProgress)="uploadProgressEventHandler($event)">
574
- * </kendo-upload>
575
- * `
576
- * })
577
- * export class UploadComponent {
578
- * uploadSaveUrl = 'saveUrl'; // should represent an actual API endpoint
579
- * uploadRemoveUrl = 'removeUrl'; // should represent an actual API endpoint
580
- *
581
- * uploadProgressEventHandler(e: UploadProgressEvent) {
582
- * console.log(e.files[0].name + ' is ' + e.percentComplete + ' uploaded');
583
- * }
584
- * }
585
- * ```
586
- */
587
- class UploadProgressEvent {
588
- /**
589
- * @hidden
590
- * Constructs the event arguments for the `uploadprogress` event.
591
- * @param files - The list of files that are being uploaded.
592
- * @param percentComplete - The portion that has been uploaded.
593
- */
594
- constructor(files, percentComplete) {
595
- this.files = files;
596
- this.percentComplete = percentComplete;
597
- }
598
- }
599
-
600
- /**
601
- * @hidden
602
- */
603
- const fileGroupMap = {
604
- audio: [
605
- ".aif", ".iff", ".m3u", ".m4a", ".mid", ".mp3", ".mpa", ".wav", ".wma", ".ogg", ".wav", ".wma", ".wpl"
606
- ],
607
- video: [
608
- ".3g2", ".3gp", ".avi", ".asf", ".flv", ".m4u", ".rm", ".h264", ".m4v", ".mkv", ".mov", ".mp4", ".mpg", ".rm", ".swf", ".vob", ".wmv"
609
- ],
610
- image: [
611
- ".ai", ".dds", ".heic", ".jpe", "jfif", ".jif", ".jp2", ".jps", ".eps", ".bmp", ".gif", ".jpeg", ".jpg", ".png", ".ps", ".psd", ".svg", ".svgz", ".tif", ".tiff"
612
- ],
613
- txt: [
614
- ".doc", ".docx", ".log", ".pages", ".tex", ".wpd", ".wps", ".odt", ".rtf", ".text", ".txt", ".wks"
615
- ],
616
- presentation: [
617
- ".key", ".odp", ".pps", ".ppt", ".pptx"
618
- ],
619
- data: [
620
- ".xlr", ".xls", ".xlsx"
621
- ],
622
- programming: [
623
- ".tmp", ".bak", ".msi", ".cab", ".cpl", ".cur", ".dll", ".dmp", ".drv", ".icns", ".ico", ".link", ".sys", ".cfg",
624
- ".ini", ".asp", ".aspx", ".cer", ".csr", ".css", ".dcr", ".htm", ".html", ".js", ".php", ".rss", ".xhtml"
625
- ],
626
- pdf: [
627
- ".pdf"
628
- ],
629
- config: [
630
- ".apk", ".app", ".bat", ".cgi", ".com", ".exe", ".gadget", ".jar", ".wsf"
631
- ],
632
- zip: [
633
- ".7z", ".cbr", ".gz", ".sitx", ".arj", ".deb", ".pkg", ".rar", ".rpm", ".tar.gz", ".z", ".zip", ".zipx"
634
- ],
635
- discImage: [
636
- ".dmg", ".iso", ".toast", ".vcd", ".bin", ".cue", ".mdf"
637
- ]
638
- };
639
- /**
640
- * @hidden
641
- */
642
- const fileSVGGroupMap = {
643
- audio: fileAudioIcon,
644
- video: fileVideoIcon,
645
- image: fileImageIcon,
646
- txt: fileTxtIcon,
647
- presentation: filePresentationIcon,
648
- data: fileDataIcon,
649
- programming: fileProgrammingIcon,
650
- pdf: filePdfIcon,
651
- config: fileConfigIcon,
652
- zip: fileZipIcon,
653
- discImage: fileDiscImageIcon
654
- };
655
-
656
- /* eslint-disable no-bitwise */
657
- /**
658
- * @hidden
659
- */
660
- const getTotalFilesSizeMessage = (files) => {
661
- let totalSize = 0;
662
- let i;
663
- if (typeof files[0].size === "number") {
664
- for (i = 0; i < files.length; i++) {
665
- if (files[i].size) {
666
- totalSize += files[i].size;
667
- }
668
- }
669
- }
670
- else {
671
- return "";
672
- }
673
- totalSize /= 1024;
674
- if (totalSize < 1024) {
675
- return totalSize.toFixed(2) + " KB";
676
- }
677
- else {
678
- return (totalSize / 1024).toFixed(2) + " MB";
679
- }
680
- };
681
- const stripPath = (name) => {
682
- const slashIndex = name.lastIndexOf("\\");
683
- return (slashIndex !== -1) ? name.substr(slashIndex + 1) : name;
684
- };
685
- const getFileExtension = (fileName) => {
686
- const rFileExtension = /\.([^\.]+)$/;
687
- const matches = fileName.match(rFileExtension);
688
- return matches ? matches[0] : "";
689
- };
690
- /**
691
- * @hidden
692
- */
693
- const validateInitialFileInfo = (file) => {
694
- if (file instanceof Object && file.hasOwnProperty("name")) {
695
- return true;
696
- }
697
- return false;
698
- };
699
- /**
700
- * @hidden
701
- */
702
- const validateInitialFileSelectFile = (file) => {
703
- if (file instanceof File || validateInitialFileInfo(file)) {
704
- return true;
705
- }
706
- return false;
707
- };
708
- /**
709
- * @hidden
710
- */
711
- const getInitialFileInfo = (fakeFile) => {
712
- fakeFile.extension = fakeFile.extension || getFileExtension(fakeFile.name);
713
- fakeFile.name = fakeFile.name; // eslint-disable-line no-self-assign
714
- fakeFile.size = fakeFile.size || 0;
715
- if (!fakeFile.hasOwnProperty("state")) {
716
- fakeFile.state = FileState.Initial;
717
- }
718
- if (!fakeFile.hasOwnProperty("uid")) {
719
- fakeFile.uid = guid();
720
- }
721
- return fakeFile;
722
- };
723
- /**
724
- * @hidden
725
- */
726
- const convertFileToFileInfo = (file) => {
727
- const fileInfo = getFileInfo(file);
728
- fileInfo.uid = guid();
729
- // Used to differentiate initial FileInfo objects and actual Files
730
- fileInfo.state = FileState.Selected;
731
- return fileInfo;
732
- };
733
- const getFileInfo = (rawFile) => {
734
- const fileName = rawFile.name;
735
- const fileSize = rawFile.size;
736
- return {
737
- extension: getFileExtension(fileName),
738
- name: fileName,
739
- rawFile: rawFile,
740
- size: fileSize,
741
- state: FileState.Selected
742
- };
743
- };
744
- /**
745
- * @hidden
746
- */
747
- const getAllFileInfo = (rawFiles) => {
748
- const allFileInfo = new Array();
749
- let i;
750
- for (i = 0; i < rawFiles.length; i++) {
751
- allFileInfo.push(getFileInfo(rawFiles[i]));
752
- }
753
- return allFileInfo;
754
- };
755
- /**
756
- * @hidden
757
- */
758
- const fileHasValidationErrors = (file) => {
759
- if (file.validationErrors && file.validationErrors.length > 0) {
760
- return true;
761
- }
762
- return false;
763
- };
764
- /**
765
- * @hidden
766
- */
767
- const filesHaveValidationErrors = (files) => {
768
- for (const file of files) {
769
- if (fileHasValidationErrors(file)) {
770
- return true;
771
- }
772
- }
773
- return false;
774
- };
775
- /**
776
- * @hidden
777
- */
778
- const inputFiles = (input) => {
779
- if (input.files) {
780
- return getAllFileInfo(input.files);
781
- }
782
- else {
783
- //Required for testing
784
- const fileNames = input.value.split("|").map((file, index) => {
785
- const fileName = file.trim();
786
- return {
787
- extension: getFileExtension(fileName),
788
- name: stripPath(fileName),
789
- rawFile: null,
790
- size: (index + 1) * 1000,
791
- state: FileState.Selected
792
- };
793
- });
794
- return fileNames;
795
- }
796
- };
797
- /**
798
- * @hidden
799
- */
800
- const assignGuidToFiles = (files, isUnique) => {
801
- const uid = guid();
802
- return files.map((file) => {
803
- file.uid = isUnique ? guid() : uid;
804
- return file;
805
- });
806
- };
807
- /**
808
- * @hidden
809
- */
810
- const supportsFormData = () => {
811
- return typeof (FormData) !== "undefined";
812
- };
813
- /**
814
- * @hidden
815
- */
816
- const userAgent = () => {
817
- return navigator.userAgent;
818
- };
819
- const focusableRegex = /^(?:a|input|select|textarea|button|object)$/i;
820
- /**
821
- * @hidden
822
- */
823
- const IGNORE_TARGET_CLASSES = 'k-icon k-select k-input k-multiselect-wrap';
824
- /**
825
- * @hidden
826
- */
827
- const UPLOAD_CLASSES = 'k-upload-button k-clear-selected k-upload-selected k-upload-action k-file';
828
- const isVisible = (element) => {
829
- const rect = element.getBoundingClientRect();
830
- return !!(rect.width && rect.height) && window.getComputedStyle(element).visibility !== 'hidden';
831
- };
832
- const toClassList = (classNames) => String(classNames).trim().split(' ');
833
- /**
834
- * @hidden
835
- */
836
- const hasClasses = (element, classNames) => {
837
- const namesList = toClassList(classNames);
838
- return Boolean(toClassList(element.className).find((className) => namesList.indexOf(className) >= 0));
839
- };
840
- /**
841
- * @hidden
842
- */
843
- const isFocusable = (element, checkVisibility = true) => {
844
- if (element.tagName) {
845
- const tagName = element.tagName.toLowerCase();
846
- const tabIndex = element.getAttribute('tabIndex');
847
- const validTabIndex = tabIndex !== null && !isNaN(tabIndex) && tabIndex > -1;
848
- let focusable = false;
849
- if (focusableRegex.test(tagName)) {
850
- focusable = !element.disabled;
851
- }
852
- else {
853
- focusable = validTabIndex;
854
- }
855
- return focusable && (!checkVisibility || isVisible(element));
856
- }
857
- return false;
858
- };
859
- /**
860
- * @hidden
861
- */
862
- const getFileGroupCssClass = (fileExtension) => {
863
- const initial = 'file';
864
- for (const group in fileGroupMap) {
865
- if (fileGroupMap[group].indexOf(fileExtension) >= 0) {
866
- if (group === 'discImage') {
867
- return `${initial}-disc-image`;
868
- }
869
- return `${initial}-${group}`;
870
- }
871
- }
872
- return initial;
873
- };
874
- /**
875
- * @hidden
876
- */
877
- const isPresent = (value) => value !== null && value !== undefined;
878
-
879
- /**
880
- * @hidden
881
- */
882
- class ChunkMap {
883
- constructor() {
884
- this._files = {};
885
- }
886
- add(uid, totalChunks) {
887
- const initialChunkInfo = {
888
- index: 0,
889
- position: 0,
890
- retries: 0,
891
- totalChunks: totalChunks
892
- };
893
- this._files[uid] = initialChunkInfo;
894
- return initialChunkInfo;
895
- }
896
- remove(uid) {
897
- if (this.has(uid)) {
898
- this._files[uid] = null;
899
- delete this._files[uid];
900
- }
901
- }
902
- has(uid) {
903
- return uid in this._files;
904
- }
905
- get(uid) {
906
- return this._files[uid];
907
- }
908
- }
909
-
910
- /**
911
- * @hidden
912
- */
913
- class UploadService {
914
- constructor(http) {
915
- this.http = http;
916
- this.cancelEvent = new EventEmitter();
917
- this.clearEvent = new EventEmitter();
918
- this.completeEvent = new EventEmitter();
919
- this.errorEvent = new EventEmitter();
920
- this.pauseEvent = new EventEmitter();
921
- this.removeEvent = new EventEmitter();
922
- this.resumeEvent = new EventEmitter();
923
- this.selectEvent = new EventEmitter();
924
- this.successEvent = new EventEmitter();
925
- this.uploadEvent = new EventEmitter();
926
- this.uploadProgressEvent = new EventEmitter();
927
- /**
928
- * Required for the `ControlValueAccessor` integration
929
- */
930
- this.changeEvent = new EventEmitter();
931
- /**
932
- * Default async settings
933
- */
934
- this.async = {
935
- autoUpload: true,
936
- batch: false,
937
- chunk: false,
938
- concurrent: true,
939
- removeField: "fileNames",
940
- removeHeaders: new HttpHeaders(),
941
- removeMethod: "POST",
942
- removeUrl: "",
943
- responseType: "json",
944
- saveField: "files",
945
- saveHeaders: new HttpHeaders(),
946
- saveMethod: "POST",
947
- saveUrl: "",
948
- withCredentials: true
949
- };
950
- /**
951
- * Default chunk settings
952
- */
953
- this.chunk = {
954
- autoRetryAfter: 100,
955
- size: 1024 * 1024,
956
- maxAutoRetries: 1,
957
- resumable: true
958
- };
959
- this.component = 'Upload';
960
- this.chunkMap = new ChunkMap();
961
- this.fileList = new FileMap();
962
- }
963
- get files() {
964
- return this.fileList;
965
- }
966
- setChunkSettings(settings) {
967
- if (settings !== false) {
968
- this.async.chunk = true;
969
- if (typeof settings === "object") {
970
- this.chunk = Object.assign({}, this.chunk, settings);
971
- }
972
- }
973
- }
974
- onChange() {
975
- const files = this.fileList.filesFlat.filter((file) => {
976
- return file.state === FileState.Initial ||
977
- file.state === FileState.Uploaded;
978
- });
979
- this.changeEvent.emit(files.length > 0 ? files : null);
980
- }
981
- addFiles(files) {
982
- const selectEventArgs = new SelectEvent(files);
983
- this.selectEvent.emit(selectEventArgs);
984
- if (!selectEventArgs.isDefaultPrevented()) {
985
- for (const file of files) {
986
- this.fileList.add(file);
987
- }
988
- if (this.async.autoUpload) {
989
- this.uploadFiles();
990
- }
991
- }
992
- if (this.component === 'FileSelect') {
993
- const flatFiles = this.fileList.filesFlat;
994
- this.changeEvent.emit(flatFiles.length > 0 ? flatFiles : null);
995
- }
996
- }
997
- addInitialFiles(initialFiles) {
998
- this.fileList.clear();
999
- initialFiles.forEach((file) => {
1000
- const fakeFile = getInitialFileInfo(file);
1001
- this.fileList.add(fakeFile);
1002
- });
1003
- }
1004
- addInitialFileSelectFiles(initialFiles) {
1005
- this.fileList.clear();
1006
- initialFiles.forEach((file) => {
1007
- if (file instanceof File) {
1008
- this.fileList.add(convertFileToFileInfo(file));
1009
- }
1010
- else {
1011
- this.fileList.add(getInitialFileInfo(file));
1012
- }
1013
- });
1014
- }
1015
- resumeFile(uid) {
1016
- const fileToResume = this.fileList.get(uid);
1017
- this.resumeEvent.emit(new ResumeEvent(fileToResume[0]));
1018
- this.fileList.setFilesStateByUid(uid, FileState.Uploading);
1019
- this._uploadFiles([fileToResume]);
1020
- }
1021
- pauseFile(uid) {
1022
- const pausedFile = this.fileList.get(uid)[0];
1023
- this.pauseEvent.emit(new PauseEvent(pausedFile));
1024
- this.fileList.setFilesStateByUid(uid, FileState.Paused);
1025
- }
1026
- removeFiles(uid) {
1027
- const removedFiles = this.fileList.get(uid);
1028
- // Clone the Headers so that the default ones are not overridden
1029
- const removeEventArgs = new RemoveEvent(removedFiles, this.cloneRequestHeaders(this.async.removeHeaders));
1030
- this.removeEvent.emit(removeEventArgs);
1031
- if (!removeEventArgs.isDefaultPrevented()) {
1032
- if (this.component === 'Upload' &&
1033
- (removedFiles[0].state === FileState.Uploaded ||
1034
- removedFiles[0].state === FileState.Initial)) {
1035
- this.performRemove(removedFiles, removeEventArgs);
1036
- }
1037
- else {
1038
- this.fileList.remove(uid);
1039
- if (this.component === 'FileSelect') {
1040
- const flatFiles = this.fileList.filesFlat;
1041
- this.changeEvent.emit(flatFiles.length > 0 ? flatFiles : null);
1042
- }
1043
- }
1044
- }
1045
- }
1046
- cancelFiles(uid) {
1047
- const canceledFiles = this.fileList.get(uid);
1048
- const cancelEventArgs = new CancelEvent(canceledFiles);
1049
- this.cancelEvent.emit(cancelEventArgs);
1050
- for (const file of canceledFiles) {
1051
- if (file.httpSubscription) {
1052
- file.httpSubscription.unsubscribe();
1053
- }
1054
- }
1055
- this.fileList.remove(uid);
1056
- this.checkAllComplete();
1057
- }
1058
- clearFiles() {
1059
- const clearEventArgs = new ClearEvent();
1060
- this.clearEvent.emit(clearEventArgs);
1061
- if (!clearEventArgs.isDefaultPrevented()) {
1062
- const triggerChange = this.fileList.hasFileWithState([
1063
- FileState.Initial,
1064
- FileState.Uploaded
1065
- ]);
1066
- this.fileList.clear();
1067
- if (triggerChange) {
1068
- this.onChange();
1069
- }
1070
- }
1071
- }
1072
- uploadFiles() {
1073
- let filesToUpload = [];
1074
- if (this.async.concurrent) {
1075
- filesToUpload = this.fileList.filesToUpload;
1076
- }
1077
- if (!this.async.concurrent && !this.fileList.hasFileWithState([FileState.Uploading])) {
1078
- filesToUpload = this.fileList.firstFileToUpload ? [this.fileList.firstFileToUpload] : [];
1079
- }
1080
- if (filesToUpload && filesToUpload.length > 0) {
1081
- this._uploadFiles(filesToUpload);
1082
- }
1083
- }
1084
- retryFiles(uid) {
1085
- const filesToRetry = [this.fileList.get(uid)];
1086
- if (filesToRetry) {
1087
- this._uploadFiles(filesToRetry);
1088
- }
1089
- }
1090
- _uploadFiles(allFiles) {
1091
- for (const filesToUpload of allFiles) {
1092
- if (filesToUpload[0].state === FileState.Paused) {
1093
- return;
1094
- }
1095
- // Clone the Headers so that the default ones are not overridden
1096
- const uploadEventArgs = new UploadEvent(filesToUpload, this.cloneRequestHeaders(this.async.saveHeaders));
1097
- this.uploadEvent.emit(uploadEventArgs);
1098
- if (!uploadEventArgs.isDefaultPrevented()) {
1099
- this.fileList.setFilesState(filesToUpload, FileState.Uploading);
1100
- const httpSubcription = this.performUpload(filesToUpload, uploadEventArgs);
1101
- filesToUpload.forEach((file) => {
1102
- file.httpSubscription = httpSubcription;
1103
- });
1104
- }
1105
- else {
1106
- this.fileList.remove(filesToUpload[0].uid);
1107
- }
1108
- }
1109
- }
1110
- performRemove(files, removeEventArgs) {
1111
- const async = this.async;
1112
- const fileNames = files.map((file) => {
1113
- return file.name;
1114
- });
1115
- const formData = this.populateRemoveFormData(fileNames, removeEventArgs.data);
1116
- const options = this.populateRequestOptions(removeEventArgs.headers, false);
1117
- const removeRequest = new HttpRequest(async.removeMethod, async.removeUrl, formData, options);
1118
- this.http.request(removeRequest)
1119
- .subscribe(success => {
1120
- this.onSuccess(success, files, "remove");
1121
- }, error => {
1122
- this.onError(error, files, "remove");
1123
- });
1124
- }
1125
- performUpload(files, uploadEventArgs) {
1126
- const async = this.async;
1127
- const formData = this.populateUploadFormData(files, uploadEventArgs.data);
1128
- const options = this.populateRequestOptions(uploadEventArgs.headers);
1129
- const uploadRequest = new HttpRequest(async.saveMethod, async.saveUrl, formData, options);
1130
- const httpSubscription = this.http.request(uploadRequest)
1131
- .subscribe(event => {
1132
- if (event.type === HttpEventType.UploadProgress && !this.async.chunk) {
1133
- this.onProgress(event, files);
1134
- }
1135
- else if (event instanceof HttpResponse) {
1136
- this.onSuccess(event, files, "upload");
1137
- this.checkAllComplete();
1138
- }
1139
- }, error => {
1140
- this.onError(error, files, "upload");
1141
- this.checkAllComplete();
1142
- });
1143
- return httpSubscription;
1144
- }
1145
- onSuccess(successResponse, files, operation) {
1146
- if (operation === "upload" && this.async.chunk) {
1147
- this.onChunkProgress(files);
1148
- if (this.isChunkUploadComplete(files[0].uid)) {
1149
- this.removeChunkInfo(files[0].uid);
1150
- }
1151
- else {
1152
- this.updateChunkInfo(files[0].uid);
1153
- this._uploadFiles([files]);
1154
- return;
1155
- }
1156
- }
1157
- const successArgs = new SuccessEvent(files, operation, successResponse);
1158
- this.successEvent.emit(successArgs);
1159
- if (operation === "upload") {
1160
- this.fileList.setFilesState(files, successArgs.isDefaultPrevented() ? FileState.Failed : FileState.Uploaded);
1161
- }
1162
- else {
1163
- if (!successArgs.isDefaultPrevented()) {
1164
- this.fileList.remove(files[0].uid);
1165
- }
1166
- }
1167
- if (!successArgs.isDefaultPrevented()) {
1168
- this.onChange();
1169
- }
1170
- }
1171
- onError(errorResponse, files, operation) {
1172
- if (operation === "upload" && this.async.chunk) {
1173
- const maxRetries = this.chunk.maxAutoRetries;
1174
- const chunkInfo = this.chunkMap.get(files[0].uid);
1175
- if (chunkInfo.retries < maxRetries) {
1176
- chunkInfo.retries += 1;
1177
- setTimeout(() => {
1178
- this.retryFiles(files[0].uid);
1179
- }, this.chunk.autoRetryAfter);
1180
- return;
1181
- }
1182
- }
1183
- const errorArgs = new ErrorEvent(files, operation, errorResponse);
1184
- this.errorEvent.emit(errorArgs);
1185
- if (operation === "upload") {
1186
- this.fileList.setFilesState(files, FileState.Failed);
1187
- }
1188
- }
1189
- onProgress(event, files) {
1190
- const percentComplete = Math.round(100 * event.loaded / event.total);
1191
- const progressArgs = new UploadProgressEvent(files, percentComplete < 100 ? percentComplete : 100);
1192
- this.uploadProgressEvent.emit(progressArgs);
1193
- }
1194
- onChunkProgress(files) {
1195
- const chunkInfo = this.chunkMap.get(files[0].uid);
1196
- let percentComplete = 0;
1197
- if (chunkInfo) {
1198
- if (chunkInfo.index === chunkInfo.totalChunks - 1) {
1199
- percentComplete = 100;
1200
- }
1201
- else {
1202
- percentComplete = Math.round(((chunkInfo.index + 1) / chunkInfo.totalChunks) * 100);
1203
- }
1204
- }
1205
- const progressArgs = new UploadProgressEvent(files, percentComplete < 100 ? percentComplete : 100);
1206
- this.uploadProgressEvent.emit(progressArgs);
1207
- }
1208
- checkAllComplete() {
1209
- if (!this.fileList.hasFileWithState([
1210
- FileState.Uploading,
1211
- FileState.Paused
1212
- ]) && this.areAllSelectedFilesHandled()) {
1213
- this.completeEvent.emit();
1214
- }
1215
- else if (this.shouldUploadNextFile()) {
1216
- this.uploadFiles();
1217
- }
1218
- }
1219
- shouldUploadNextFile() {
1220
- return !this.async.concurrent &&
1221
- this.fileList.hasFileWithState([FileState.Selected]) &&
1222
- !this.fileList.hasFileWithState([FileState.Uploading]);
1223
- }
1224
- areAllSelectedFilesHandled() {
1225
- const validSelectedFiles = this.fileList.getFilesWithState(FileState.Selected).filter(file => !file.validationErrors);
1226
- return validSelectedFiles.length === 0;
1227
- }
1228
- cloneRequestHeaders(headers) {
1229
- const cloned = {};
1230
- if (headers) {
1231
- headers.keys().forEach((key) => {
1232
- cloned[key] = headers.get(key);
1233
- });
1234
- }
1235
- return new HttpHeaders(cloned);
1236
- }
1237
- populateRequestOptions(headers, reportProgress = true) {
1238
- return {
1239
- headers: headers,
1240
- reportProgress: reportProgress,
1241
- responseType: this.async.responseType,
1242
- withCredentials: this.async.withCredentials
1243
- };
1244
- }
1245
- populateUploadFormData(files, clientData) {
1246
- const saveField = this.async.saveField;
1247
- const data = new FormData();
1248
- this.populateClientFormData(data, clientData);
1249
- if (this.async.chunk) {
1250
- data.append(saveField, this.getNextChunk(files[0]));
1251
- data.append("metadata", this.getChunkMetadata(files[0]));
1252
- }
1253
- else {
1254
- for (const file of files) {
1255
- data.append(saveField, file.rawFile);
1256
- }
1257
- }
1258
- return data;
1259
- }
1260
- populateRemoveFormData(fileNames, clientData) {
1261
- const data = new FormData();
1262
- this.populateClientFormData(data, clientData);
1263
- for (const fileName of fileNames) {
1264
- data.append(this.async.removeField, fileName);
1265
- }
1266
- return data;
1267
- }
1268
- populateClientFormData(data, clientData) {
1269
- for (const key in clientData) {
1270
- if (clientData.hasOwnProperty(key)) {
1271
- data.append(key, clientData[key]);
1272
- }
1273
- }
1274
- }
1275
- /* Chunking Helper Methods Section */
1276
- getNextChunk(file) {
1277
- const info = this.getChunkInfo(file);
1278
- const newPosition = info.position + this.chunk.size;
1279
- return file.rawFile.slice(info.position, newPosition);
1280
- }
1281
- getChunkInfo(file) {
1282
- let chunkInfo = this.chunkMap.get(file.uid);
1283
- if (!chunkInfo) {
1284
- const totalChunks = file.size > 0 ? Math.ceil(file.size / this.chunk.size) : 1;
1285
- chunkInfo = this.chunkMap.add(file.uid, totalChunks);
1286
- }
1287
- return chunkInfo;
1288
- }
1289
- updateChunkInfo(uid) {
1290
- const chunkInfo = this.chunkMap.get(uid);
1291
- if (chunkInfo.index < chunkInfo.totalChunks - 1) {
1292
- chunkInfo.index += 1;
1293
- chunkInfo.position += this.chunk.size;
1294
- chunkInfo.retries = 0;
1295
- }
1296
- }
1297
- removeChunkInfo(uid) {
1298
- this.chunkMap.remove(uid);
1299
- }
1300
- getChunkMetadata(file) {
1301
- const chunkInfo = this.chunkMap.get(file.uid);
1302
- const chunkMetadata = {
1303
- chunkIndex: chunkInfo.index,
1304
- contentType: file.rawFile.type,
1305
- fileName: file.name,
1306
- fileSize: file.size,
1307
- fileUid: file.uid,
1308
- totalChunks: chunkInfo.totalChunks
1309
- };
1310
- return JSON.stringify(chunkMetadata);
1311
- }
1312
- isChunkUploadComplete(uid) {
1313
- const chunkInfo = this.chunkMap.get(uid);
1314
- if (chunkInfo) {
1315
- return chunkInfo.index + 1 === chunkInfo.totalChunks;
1316
- }
1317
- return false;
1318
- }
1319
- }
1320
- UploadService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadService, deps: [{ token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
1321
- UploadService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadService });
1322
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadService, decorators: [{
1323
- type: Injectable
1324
- }], ctorParameters: function () { return [{ type: i1.HttpClient }]; } });
1325
-
1326
- /**
1327
- * @hidden
1328
- */
1329
- class NavigationService {
1330
- constructor(uploadService, zone) {
1331
- this.uploadService = uploadService;
1332
- this.zone = zone;
1333
- this.onActionButtonFocus = new EventEmitter();
1334
- this.onFileAction = new EventEmitter();
1335
- this.onFileFocus = new EventEmitter();
1336
- this.onTabOut = new EventEmitter();
1337
- this.onWrapperFocus = new EventEmitter();
1338
- this.onSelectButtonFocus = new EventEmitter();
1339
- this.actionButtonsVisible = false;
1340
- this.fileListVisible = false;
1341
- this.focused = false;
1342
- this.focusedFileIndex = 0;
1343
- this._focusedIndex = -1;
1344
- }
1345
- action(event) {
1346
- const key = event.keyCode;
1347
- return this.keyBindings[key];
1348
- }
1349
- process(event, component) {
1350
- const handler = this.action(event);
1351
- if (handler) {
1352
- handler(event, component);
1353
- }
1354
- }
1355
- computeKeys() {
1356
- this.keyBindings = {
1357
- [Keys.Space]: () => this.handleSpace(),
1358
- [Keys.Enter]: () => this.handleEnter(),
1359
- [Keys.Escape]: () => this.handleEscape(),
1360
- [Keys.Delete]: () => this.handleDelete(),
1361
- [Keys.Tab]: (event, component) => this.handleTab(event, component),
1362
- [Keys.ArrowUp]: (event) => this.handleUpDown(event, -1),
1363
- [Keys.ArrowDown]: (event) => this.handleUpDown(event, 1)
1364
- };
1365
- }
1366
- focusSelectButton() {
1367
- this.focused = true;
1368
- this._focusedIndex = -1;
1369
- this.onSelectButtonFocus.emit();
1370
- }
1371
- handleEnter() {
1372
- if (this.lastIndex >= 0 && this.focusedIndex >= 0 && this.focusedIndex <= this.lastFileIndex) {
1373
- this.zone.run(() => this.onFileAction.emit(Keys.Enter));
1374
- }
1375
- }
1376
- handleSpace() {
1377
- if (this.lastIndex >= 0 && this.focusedIndex >= 0 && this.focusedIndex <= this.lastFileIndex) {
1378
- this.zone.run(() => this.onFileAction.emit(Keys.Space));
1379
- }
1380
- }
1381
- handleDelete() {
1382
- if (this.focusedIndex >= 0 && this.focusedIndex <= this.lastFileIndex) {
1383
- this.zone.run(() => this.onFileAction.emit(Keys.Delete));
1384
- }
1385
- }
1386
- handleEscape() {
1387
- if (this.focusedIndex >= 0 && this.focusedIndex <= this.lastFileIndex) {
1388
- this.zone.run(() => this.onFileAction.emit(Keys.Escape));
1389
- }
1390
- }
1391
- handleTab(event, component) {
1392
- const shifted = event.shiftKey;
1393
- /* Select Files button is focused */
1394
- if (this.focusedIndex === -1 && this.fileListVisible && !shifted) {
1395
- this.focusedIndex = this.focusedFileIndex;
1396
- event.preventDefault();
1397
- this.onFileFocus.emit(this.focusedFileIndex);
1398
- return;
1399
- }
1400
- /* File in the list is focused */
1401
- if (this.focusedIndex > -1 && this.focusedIndex <= this.lastFileIndex) {
1402
- if (shifted) {
1403
- this.focusedIndex = -1;
1404
- }
1405
- else if (component !== 'fileselect' && this.actionButtonsVisible) {
1406
- this.focusedIndex = this.lastFileIndex + 1;
1407
- return;
1408
- }
1409
- }
1410
- /* Clear button is focused */
1411
- if (this.focusedIndex === this.lastFileIndex + 1) {
1412
- this.focusedIndex = shifted ? this.focusedFileIndex : this.lastIndex;
1413
- if (shifted) {
1414
- event.preventDefault();
1415
- this.onFileFocus.emit(this.focusedFileIndex);
1416
- }
1417
- return;
1418
- }
1419
- /* Upload button is focused */
1420
- if (this.focusedIndex === this.lastIndex && this.actionButtonsVisible && shifted) {
1421
- this.focusedIndex -= 1;
1422
- return;
1423
- }
1424
- this.onTabOut.emit();
1425
- }
1426
- handleUpDown(event, direction) {
1427
- const focusOnFileList = this.focusedIndex > -1 && this.uploadService.files.count >= 0;
1428
- const nextFocusableIndexInBoundaries = direction > 0 ? this.focusedFileIndex < this.lastFileIndex : this.focusedFileIndex > 0;
1429
- const focusNextFile = focusOnFileList && nextFocusableIndexInBoundaries;
1430
- if (focusNextFile) {
1431
- event.preventDefault();
1432
- this.zone.run(() => {
1433
- this.focusedIndex += direction;
1434
- this.focusedFileIndex += direction;
1435
- });
1436
- }
1437
- }
1438
- get focusedIndex() {
1439
- return this._focusedIndex;
1440
- }
1441
- set focusedIndex(index) {
1442
- if (!this.focused) {
1443
- this.onWrapperFocus.emit();
1444
- }
1445
- this._focusedIndex = index;
1446
- this.focused = true;
1447
- if (this._focusedIndex >= 0 && this._focusedIndex <= this.lastFileIndex) {
1448
- this.onFileFocus.emit(index);
1449
- }
1450
- }
1451
- get lastFileIndex() {
1452
- return this.actionButtonsVisible ? this.lastIndex - 2 : this.lastIndex;
1453
- }
1454
- get lastIndex() {
1455
- const fileCount = this.uploadService.files.count;
1456
- return this.actionButtonsVisible ? fileCount + 1 : fileCount - 1;
1457
- }
1458
- }
1459
- NavigationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NavigationService, deps: [{ token: UploadService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
1460
- NavigationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NavigationService });
1461
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: NavigationService, decorators: [{
1462
- type: Injectable
1463
- }], ctorParameters: function () { return [{ type: UploadService }, { type: i0.NgZone }]; } });
1464
-
1465
- const components = {};
1466
- /**
1467
- * @hidden
1468
- */
1469
- class DropZoneService {
1470
- addComponent(component, zoneId) {
1471
- if (this.has(zoneId)) {
1472
- components[zoneId].push(component);
1473
- }
1474
- else {
1475
- components[zoneId] = [component];
1476
- }
1477
- }
1478
- clearComponent(component, zoneId) {
1479
- if (this.has(zoneId)) {
1480
- const componentIdx = components[zoneId].indexOf(component);
1481
- components[zoneId].splice(componentIdx, 1);
1482
- }
1483
- }
1484
- getComponents(zoneId) {
1485
- return components[zoneId];
1486
- }
1487
- has(id) {
1488
- return id in components;
1489
- }
1490
- }
1491
- DropZoneService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DropZoneService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1492
- DropZoneService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DropZoneService });
1493
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DropZoneService, decorators: [{
1494
- type: Injectable
1495
- }] });
1496
-
1497
- /**
1498
- * @hidden
1499
- */
1500
- const INVALIDMAXFILESIZE = "invalidMaxFileSize";
1501
- /**
1502
- * @hidden
1503
- */
1504
- const INVALIDMINFILESIZE = "invalidMinFileSize";
1505
- /**
1506
- * @hidden
1507
- */
1508
- const INVALIDFILEEXTENSION = "invalidFileExtension";
1509
- const validateFileExtension = (file, allowedExtensions) => {
1510
- if (allowedExtensions.length > 0) {
1511
- if (allowedExtensions.indexOf(file.extension.toLowerCase()) < 0) {
1512
- file.validationErrors = file.validationErrors || [];
1513
- if (file.validationErrors.indexOf(INVALIDFILEEXTENSION) < 0) {
1514
- file.validationErrors.push(INVALIDFILEEXTENSION);
1515
- }
1516
- }
1517
- }
1518
- };
1519
- const validateFileSize = (file, minFileSize, maxFileSize) => {
1520
- if (minFileSize !== 0 && file.size < minFileSize) {
1521
- file.validationErrors = file.validationErrors || [];
1522
- if (file.validationErrors.indexOf(INVALIDMINFILESIZE) < 0) {
1523
- file.validationErrors.push(INVALIDMINFILESIZE);
1524
- }
1525
- }
1526
- if (maxFileSize !== 0 && file.size > maxFileSize) {
1527
- file.validationErrors = file.validationErrors || [];
1528
- if (file.validationErrors.indexOf(INVALIDMAXFILESIZE) < 0) {
1529
- file.validationErrors.push(INVALIDMAXFILESIZE);
1530
- }
1531
- }
1532
- };
1533
- const parseAllowedExtensions = (extensions) => {
1534
- const allowedExtensions = extensions.map((ext) => {
1535
- const parsedExt = (ext.substring(0, 1) === ".") ? ext : ("." + ext);
1536
- return parsedExt.toLowerCase();
1537
- });
1538
- return allowedExtensions;
1539
- };
1540
- /**
1541
- * @hidden
1542
- */
1543
- const validateFiles = (files, restrictionInfo) => {
1544
- const allowedExtensions = parseAllowedExtensions(restrictionInfo.allowedExtensions);
1545
- const maxFileSize = restrictionInfo.maxFileSize;
1546
- const minFileSize = restrictionInfo.minFileSize;
1547
- let i;
1548
- for (i = 0; i < files.length; i++) {
1549
- validateFileExtension(files[i], allowedExtensions);
1550
- validateFileSize(files[i], minFileSize, maxFileSize);
1551
- }
1552
- };
1553
-
1554
- /**
1555
- * @hidden
1556
- */
1557
- const packageMetadata = {
1558
- name: '@progress/kendo-angular-upload',
1559
- productName: 'Kendo UI for Angular',
1560
- productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
1561
- publishDate: 1729174367,
1562
- version: '17.0.0-develop.9',
1563
- licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
1564
- };
1565
-
1566
- /**
1567
- * Used to customize the rendering of the files in the list ([see example]({% slug templates_upload %}#toc-file-template)).
1568
- */
1569
- class FileTemplateDirective {
1570
- constructor(templateRef) {
1571
- this.templateRef = templateRef;
1572
- }
1573
- }
1574
- FileTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1575
- FileTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: FileTemplateDirective, isStandalone: true, selector: "[kendoUploadFileTemplate], [kendoFileSelectFileTemplate]", ngImport: i0 });
1576
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileTemplateDirective, decorators: [{
1577
- type: Directive,
1578
- args: [{
1579
- selector: '[kendoUploadFileTemplate], [kendoFileSelectFileTemplate]',
1580
- standalone: true
1581
- }]
1582
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
1583
-
1584
- /**
1585
- * Used to customize the rendering of the file info section in the list. All other elements of the default template, such as file icon, action buttons, upload progress etc. will be preserved in place. ([see example]({% slug templates_upload %}#toc-file-info-template)).
1586
- */
1587
- class FileInfoTemplateDirective {
1588
- constructor(templateRef) {
1589
- this.templateRef = templateRef;
1590
- }
1591
- }
1592
- FileInfoTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileInfoTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
1593
- FileInfoTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: FileInfoTemplateDirective, isStandalone: true, selector: "[kendoUploadFileInfoTemplate], [kendoFileSelectFileInfoTemplate]", ngImport: i0 });
1594
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileInfoTemplateDirective, decorators: [{
1595
- type: Directive,
1596
- args: [{
1597
- selector: '[kendoUploadFileInfoTemplate], [kendoFileSelectFileInfoTemplate]',
1598
- standalone: true
1599
- }]
1600
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
1601
-
1602
- /**
1603
- * @hidden
1604
- */
1605
- class UploadFileSelectBase {
1606
- constructor(uploadService, navigation, cdr, injector, zone) {
1607
- this.uploadService = uploadService;
1608
- this.navigation = navigation;
1609
- this.cdr = cdr;
1610
- this.injector = injector;
1611
- this.zone = zone;
1612
- /**
1613
- * Disables the component.
1614
- *
1615
- * @default false
1616
- */
1617
- this.disabled = false;
1618
- /**
1619
- * Enables the selection of multiple files
1620
- * If set to `false`, only one file can be selected at a time.
1621
- * @default true
1622
- */
1623
- this.multiple = true;
1624
- /**
1625
- * Toggles the visibility of the file list.
1626
- * @default true
1627
- */
1628
- this.showFileList = true;
1629
- /**
1630
- * Specifies the [`tabindex`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex) of the component.
1631
- * @default 0
1632
- */
1633
- this.tabindex = 0;
1634
- /**
1635
- * @hidden
1636
- */
1637
- this.focusableId = `k-${guid()}`;
1638
- /**
1639
- * @hidden
1640
- */
1641
- this.hostDefaultClasses = true;
1642
- /**
1643
- * Fires when the user navigates outside the component.
1644
- */
1645
- this.onBlur = new EventEmitter();
1646
- /**
1647
- * Fires when the component is focused.
1648
- */
1649
- this.onFocus = new EventEmitter();
1650
- /**
1651
- * Fires when files are selected. If prevented, the selected files will not be added to the list.
1652
- */
1653
- this.select = new EventEmitter();
1654
- /**
1655
- * Fires when a file is about to be removed. If prevented, the file will remain in the list.
1656
- */
1657
- this.remove = new EventEmitter();
1658
- /**
1659
- * @hidden
1660
- */
1661
- this._restrictions = {
1662
- allowedExtensions: [],
1663
- maxFileSize: 0,
1664
- minFileSize: 0
1665
- };
1666
- this.onTouchedCallback = (_) => { };
1667
- this.onChangeCallback = (_) => { };
1668
- this.fileList = this.uploadService.files;
1669
- }
1670
- /**
1671
- * Sets the restrictions for selected files.
1672
- */
1673
- set restrictions(restrictions) {
1674
- const parsedRestrictions = Object.assign({}, this.restrictions, restrictions);
1675
- this._restrictions = parsedRestrictions;
1676
- }
1677
- get restrictions() {
1678
- return this._restrictions;
1679
- }
1680
- /**
1681
- * @hidden
1682
- */
1683
- get hostDisabledClass() {
1684
- return this.disabled;
1685
- }
1686
- /**
1687
- * @hidden
1688
- */
1689
- get formControl() {
1690
- const ngControl = this.injector.get(NgControl, null);
1691
- return (ngControl === null || ngControl === void 0 ? void 0 : ngControl.control) || null;
1692
- }
1693
- /**
1694
- * @hidden
1695
- */
1696
- get isControlRequired() {
1697
- return isControlRequired(this.formControl);
1698
- }
1699
- /**
1700
- * @hidden
1701
- */
1702
- get hasFileList() {
1703
- const hasFileList = this.showFileList && this.fileList.count > 0;
1704
- this.navigation.fileListVisible = hasFileList;
1705
- return hasFileList;
1706
- }
1707
- /**
1708
- * @hidden
1709
- */
1710
- writeValue(newValue, validation, callback) {
1711
- let isValid = true;
1712
- if (newValue instanceof Array) {
1713
- newValue.forEach((file) => {
1714
- if (!validation(file)) {
1715
- isValid = false;
1716
- }
1717
- });
1718
- if (isValid) {
1719
- this.uploadService[callback](newValue);
1720
- }
1721
- }
1722
- if (newValue === null) {
1723
- this.fileList.clear();
1724
- }
1725
- this.cdr.markForCheck();
1726
- }
1727
- /**
1728
- * @hidden
1729
- */
1730
- registerOnChange(fn) {
1731
- this.onChangeCallback = fn;
1732
- }
1733
- /**
1734
- * @hidden
1735
- */
1736
- registerOnTouched(fn) {
1737
- this.onTouchedCallback = fn;
1738
- }
1739
- /**
1740
- * @hidden
1741
- */
1742
- setDisabledState(isDisabled) {
1743
- this.disabled = isDisabled;
1744
- }
1745
- /**
1746
- * @hidden
1747
- */
1748
- onFileSelectButtonFocus() {
1749
- if (!this.navigation.focused) {
1750
- this.navigation.focusedIndex = -1;
1751
- }
1752
- }
1753
- /**
1754
- * Focuses the component's `Select files` button.
1755
- */
1756
- focus() {
1757
- this.zone.runOutsideAngular(() => {
1758
- setTimeout(() => {
1759
- this.fileSelectButton.nativeElement.focus();
1760
- this.navigation.focused = true;
1761
- });
1762
- });
1763
- }
1764
- /**
1765
- * @hidden
1766
- * @deprecated
1767
- */
1768
- focusComponent() {
1769
- this.focus();
1770
- }
1771
- /**
1772
- * Blurs the component if it was previously focused.
1773
- */
1774
- blur() {
1775
- if (this.navigation.focused) {
1776
- this.navigation.focused = false;
1777
- document.activeElement.blur();
1778
- }
1779
- }
1780
- /**
1781
- * @hidden
1782
- * @deprecated
1783
- */
1784
- blurComponent() {
1785
- this.blur();
1786
- }
1787
- }
1788
- UploadFileSelectBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadFileSelectBase, deps: [{ token: UploadService }, { token: NavigationService }, { token: i0.ChangeDetectorRef }, { token: i0.Injector }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
1789
- UploadFileSelectBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: UploadFileSelectBase, inputs: { accept: "accept", disabled: "disabled", multiple: "multiple", showFileList: "showFileList", tabindex: "tabindex", restrictions: "restrictions", zoneId: "zoneId", focusableId: "focusableId" }, outputs: { onBlur: "blur", onFocus: "focus", select: "select", remove: "remove" }, host: { properties: { "class.k-upload": "this.hostDefaultClasses", "class.k-disabled": "this.hostDisabledClass" } }, queries: [{ propertyName: "fileTemplate", first: true, predicate: FileTemplateDirective, descendants: true }, { propertyName: "fileInfoTemplate", first: true, predicate: FileInfoTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "fileSelectButton", first: true, predicate: ["fileSelectButton"], descendants: true, read: ElementRef, static: true }], ngImport: i0 });
1790
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadFileSelectBase, decorators: [{
1791
- type: Directive,
1792
- args: [{}]
1793
- }], ctorParameters: function () { return [{ type: UploadService }, { type: NavigationService }, { type: i0.ChangeDetectorRef }, { type: i0.Injector }, { type: i0.NgZone }]; }, propDecorators: { fileTemplate: [{
1794
- type: ContentChild,
1795
- args: [FileTemplateDirective]
1796
- }], fileInfoTemplate: [{
1797
- type: ContentChild,
1798
- args: [FileInfoTemplateDirective]
1799
- }], fileSelectButton: [{
1800
- type: ViewChild,
1801
- args: ['fileSelectButton', { static: true, read: ElementRef }]
1802
- }], accept: [{
1803
- type: Input
1804
- }], disabled: [{
1805
- type: Input
1806
- }], multiple: [{
1807
- type: Input
1808
- }], showFileList: [{
1809
- type: Input
1810
- }], tabindex: [{
1811
- type: Input
1812
- }], restrictions: [{
1813
- type: Input
1814
- }], zoneId: [{
1815
- type: Input
1816
- }], focusableId: [{
1817
- type: Input
1818
- }], hostDefaultClasses: [{
1819
- type: HostBinding,
1820
- args: ['class.k-upload']
1821
- }], hostDisabledClass: [{
1822
- type: HostBinding,
1823
- args: ['class.k-disabled']
1824
- }], onBlur: [{
1825
- type: Output,
1826
- args: ['blur']
1827
- }], onFocus: [{
1828
- type: Output,
1829
- args: ['focus']
1830
- }], select: [{
1831
- type: Output
1832
- }], remove: [{
1833
- type: Output
1834
- }] } });
1835
-
1836
- /* eslint-disable no-debugger */
1837
- /**
1838
- * @hidden
1839
- */
1840
- class UploadActionButtonsComponent {
1841
- constructor(uploadService, localization, navigation) {
1842
- this.uploadService = uploadService;
1843
- this.localization = localization;
1844
- this.navigation = navigation;
1845
- this.hostDefaultClass = true;
1846
- }
1847
- get actionButtonsEndClassName() {
1848
- return this.actionsLayout === 'end';
1849
- }
1850
- get actionButtonsStretchedClassName() {
1851
- return this.actionsLayout === 'stretched';
1852
- }
1853
- get actionButtonsStartClassName() {
1854
- return this.actionsLayout === 'start';
1855
- }
1856
- get actionButtonsCenterClassName() {
1857
- return this.actionsLayout === 'center';
1858
- }
1859
- onUploadButtonFocus() {
1860
- if (!this.navigation.focused) {
1861
- this.navigation.focusedIndex = this.navigation.lastIndex;
1862
- }
1863
- }
1864
- onUploadButtonClick(event) {
1865
- event.stopImmediatePropagation();
1866
- this.performUpload();
1867
- }
1868
- performUpload() {
1869
- if (!this.disabled) {
1870
- this.uploadService.uploadFiles();
1871
- this.navigation.focusSelectButton();
1872
- }
1873
- }
1874
- onClearButtonClick(event) {
1875
- event.stopImmediatePropagation();
1876
- this.clearFiles();
1877
- }
1878
- clearFiles() {
1879
- if (!this.disabled) {
1880
- this.uploadService.clearFiles();
1881
- this.navigation.focusSelectButton();
1882
- }
1883
- }
1884
- textFor(key) {
1885
- return this.localization.get(key);
1886
- }
1887
- }
1888
- UploadActionButtonsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadActionButtonsComponent, deps: [{ token: UploadService }, { token: i1$1.LocalizationService }, { token: NavigationService }], target: i0.ɵɵFactoryTarget.Component });
1889
- UploadActionButtonsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UploadActionButtonsComponent, isStandalone: true, selector: "kendo-upload-action-buttons", inputs: { disabled: "disabled", actionsLayout: "actionsLayout" }, host: { properties: { "class.k-actions": "this.hostDefaultClass", "class.k-actions-end": "this.actionButtonsEndClassName", "class.k-actions-stretched": "this.actionButtonsStretchedClassName", "class.k-actions-start": "this.actionButtonsStartClassName", "class.k-actions-center": "this.actionButtonsCenterClassName" } }, viewQueries: [{ propertyName: "clearButton", first: true, predicate: ["clearButton"], descendants: true, static: true }, { propertyName: "uploadButton", first: true, predicate: ["uploadButton"], descendants: true, static: true }], ngImport: i0, template: `
1890
- <button #clearButton role="button" class="k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-clear-selected"
1891
- (click)="onClearButtonClick($event)">
1892
- {{textFor('clearSelectedFiles')}}
1893
- </button>
1894
- <button #uploadButton role="button" class="k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary k-upload-selected"
1895
- (focus)="onUploadButtonFocus()"
1896
- (click)="onUploadButtonClick($event)">
1897
- {{textFor('uploadSelectedFiles')}}
1898
- </button>
1899
- `, isInline: true });
1900
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadActionButtonsComponent, decorators: [{
1901
- type: Component,
1902
- args: [{
1903
- selector: 'kendo-upload-action-buttons',
1904
- template: `
1905
- <button #clearButton role="button" class="k-button k-button-md k-rounded-md k-button-solid k-button-solid-base k-clear-selected"
1906
- (click)="onClearButtonClick($event)">
1907
- {{textFor('clearSelectedFiles')}}
1908
- </button>
1909
- <button #uploadButton role="button" class="k-button k-button-md k-rounded-md k-button-solid k-button-solid-primary k-upload-selected"
1910
- (focus)="onUploadButtonFocus()"
1911
- (click)="onUploadButtonClick($event)">
1912
- {{textFor('uploadSelectedFiles')}}
1913
- </button>
1914
- `,
1915
- standalone: true
1916
- }]
1917
- }], ctorParameters: function () { return [{ type: UploadService }, { type: i1$1.LocalizationService }, { type: NavigationService }]; }, propDecorators: { disabled: [{
1918
- type: Input
1919
- }], actionsLayout: [{
1920
- type: Input
1921
- }], clearButton: [{
1922
- type: ViewChild,
1923
- args: ['clearButton', { static: true }]
1924
- }], uploadButton: [{
1925
- type: ViewChild,
1926
- args: ['uploadButton', { static: true }]
1927
- }], hostDefaultClass: [{
1928
- type: HostBinding,
1929
- args: ['class.k-actions']
1930
- }], actionButtonsEndClassName: [{
1931
- type: HostBinding,
1932
- args: ['class.k-actions-end']
1933
- }], actionButtonsStretchedClassName: [{
1934
- type: HostBinding,
1935
- args: ['class.k-actions-stretched']
1936
- }], actionButtonsStartClassName: [{
1937
- type: HostBinding,
1938
- args: ['class.k-actions-start']
1939
- }], actionButtonsCenterClassName: [{
1940
- type: HostBinding,
1941
- args: ['class.k-actions-center']
1942
- }] } });
1943
-
1944
- /**
1945
- * @hidden
1946
- */
1947
- class FileListItemDirective {
1948
- constructor(el, navigationService, uploadService) {
1949
- this.navigationService = navigationService;
1950
- this.uploadService = uploadService;
1951
- this.fileClass = true;
1952
- this.focused = false;
1953
- this.element = el;
1954
- }
1955
- focus() {
1956
- this.element.nativeElement.focus();
1957
- }
1958
- get uidAttribute() {
1959
- return this.files[0].uid;
1960
- }
1961
- get tabIndex() {
1962
- return this.navigationService.focusedFileIndex === this.index ? '0' : '-1';
1963
- }
1964
- get kFileError() {
1965
- return this.files[0].state === FileState.Failed;
1966
- }
1967
- get kFileInvalid() {
1968
- return filesHaveValidationErrors(this.files);
1969
- }
1970
- get kFileProgress() {
1971
- return this.files[0].state === FileState.Uploading ||
1972
- this.files[0].state === FileState.Paused;
1973
- }
1974
- get kFileSuccess() {
1975
- if (this.uploadService.component === 'Upload') {
1976
- return this.files[0].state === FileState.Uploaded ||
1977
- this.files[0].state === FileState.Initial;
1978
- }
1979
- return false;
1980
- }
1981
- get kStateFocused() {
1982
- return this.focused;
1983
- }
1984
- onFocus() {
1985
- this.focused = true;
1986
- }
1987
- onBlur() {
1988
- this.focused = false;
1989
- }
1990
- onClick(event) {
1991
- if ((!isFocusable(event.target) && !hasClasses(event.target, IGNORE_TARGET_CLASSES)) || !!event.target.closest('.k-upload-action')) {
1992
- this.navigationService.focusedIndex = this.navigationService.focusedFileIndex = this.index;
1993
- }
1994
- }
1995
- }
1996
- FileListItemDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListItemDirective, deps: [{ token: i0.ElementRef }, { token: NavigationService }, { token: UploadService }], target: i0.ɵɵFactoryTarget.Directive });
1997
- FileListItemDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: FileListItemDirective, isStandalone: true, selector: "[kendoUploadFileListItem]", inputs: { files: "files", index: "index" }, host: { listeners: { "focus": "onFocus()", "blur": "onBlur()", "click": "onClick($event)" }, properties: { "class.k-file": "this.fileClass", "attr.data-uid": "this.uidAttribute", "attr.tabIndex": "this.tabIndex", "class.k-file-error": "this.kFileError", "class.k-file-invalid": "this.kFileInvalid", "class.k-file-progress": "this.kFileProgress", "class.k-file-success": "this.kFileSuccess", "class.k-focus": "this.kStateFocused" } }, ngImport: i0 });
1998
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListItemDirective, decorators: [{
1999
- type: Directive,
2000
- args: [{
2001
- selector: '[kendoUploadFileListItem]',
2002
- standalone: true
2003
- }]
2004
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: NavigationService }, { type: UploadService }]; }, propDecorators: { files: [{
2005
- type: Input
2006
- }], index: [{
2007
- type: Input
2008
- }], fileClass: [{
2009
- type: HostBinding,
2010
- args: ['class.k-file']
2011
- }], uidAttribute: [{
2012
- type: HostBinding,
2013
- args: ['attr.data-uid']
2014
- }], tabIndex: [{
2015
- type: HostBinding,
2016
- args: ['attr.tabIndex']
2017
- }], kFileError: [{
2018
- type: HostBinding,
2019
- args: ['class.k-file-error']
2020
- }], kFileInvalid: [{
2021
- type: HostBinding,
2022
- args: ['class.k-file-invalid']
2023
- }], kFileProgress: [{
2024
- type: HostBinding,
2025
- args: ['class.k-file-progress']
2026
- }], kFileSuccess: [{
2027
- type: HostBinding,
2028
- args: ['class.k-file-success']
2029
- }], kStateFocused: [{
2030
- type: HostBinding,
2031
- args: ['class.k-focus']
2032
- }], onFocus: [{
2033
- type: HostListener,
2034
- args: ['focus']
2035
- }], onBlur: [{
2036
- type: HostListener,
2037
- args: ['blur']
2038
- }], onClick: [{
2039
- type: HostListener,
2040
- args: ['click', ['$event']]
2041
- }] } });
2042
-
2043
- /**
2044
- * @hidden
2045
- */
2046
- class FileListItemBase {
2047
- constructor(uploadService) {
2048
- this.uploadService = uploadService;
2049
- this.progressComplete = 0;
2050
- }
2051
- subscribeUploadProgress(uploadProgressHandler) {
2052
- this.uploadProgressSubscription = this.uploadService.uploadProgressEvent.subscribe(uploadProgressHandler);
2053
- }
2054
- fileHasValidationErrors(file) {
2055
- return fileHasValidationErrors(file);
2056
- }
2057
- filesHaveValidationErrors(files) {
2058
- return filesHaveValidationErrors(files);
2059
- }
2060
- ngOnDestroy() {
2061
- this.uploadProgressSubscription.unsubscribe();
2062
- }
2063
- getFileValidationMessage(file) {
2064
- let validationMessage;
2065
- if (file.validationErrors && file.validationErrors.length > 0) {
2066
- validationMessage = this.localization.get(file.validationErrors[0]);
2067
- }
2068
- return validationMessage;
2069
- }
2070
- getTotalFilesSizeMessage(files) {
2071
- return getTotalFilesSizeMessage(files);
2072
- }
2073
- textFor(key) {
2074
- return this.localization.get(key);
2075
- }
2076
- }
2077
- FileListItemBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListItemBase, deps: [{ token: UploadService }], target: i0.ɵɵFactoryTarget.Component });
2078
- FileListItemBase.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileListItemBase, selector: "ng-component", ngImport: i0, template: '', isInline: true });
2079
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListItemBase, decorators: [{
2080
- type: Component,
2081
- args: [{ template: '' }]
2082
- }], ctorParameters: function () { return [{ type: UploadService }]; } });
2083
-
2084
- /**
2085
- * @hidden
2086
- */
2087
- class FileListItemActionButtonComponent {
2088
- constructor(uploadService, localization, navigation) {
2089
- this.uploadService = uploadService;
2090
- this.localization = localization;
2091
- this.navigation = navigation;
2092
- this.retrySVGIcon = arrowRotateCwSmallIcon;
2093
- this.playSVGIcon = playSmIcon;
2094
- this.pauseSVGIcon = pauseSmIcon;
2095
- this.cancelSVGIcon = cancelIcon;
2096
- this.deleteSVGIcon = xIcon;
2097
- }
2098
- onRetryClick() {
2099
- if (this.disabled) {
2100
- return;
2101
- }
2102
- this.uploadService.retryFiles(this.file.uid);
2103
- }
2104
- onRemoveCancelClick(event) {
2105
- if (this.disabled) {
2106
- return;
2107
- }
2108
- event.stopImmediatePropagation();
2109
- const uid = this.file.uid;
2110
- if (this.file.state === FileState.Uploading) {
2111
- this.uploadService.cancelFiles(uid);
2112
- }
2113
- else {
2114
- this.uploadService.removeFiles(uid);
2115
- }
2116
- this.navigation.focusSelectButton();
2117
- }
2118
- onPauseResumeClick() {
2119
- if (this.disabled) {
2120
- return;
2121
- }
2122
- const uid = this.file.uid;
2123
- if (this.file.state === FileState.Paused) {
2124
- this.uploadService.resumeFile(uid);
2125
- }
2126
- else {
2127
- this.uploadService.pauseFile(uid);
2128
- }
2129
- }
2130
- get actionButtonTitle() {
2131
- if (this.file.state === FileState.Uploading) {
2132
- return this.localization.get('cancel');
2133
- }
2134
- return this.localization.get('remove');
2135
- }
2136
- get retryButtonTitle() {
2137
- return this.localization.get('retry');
2138
- }
2139
- get pauseResumeButtonTitle() {
2140
- if (this.file.state === FileState.Uploading) {
2141
- return this.localization.get('pause');
2142
- }
2143
- return this.localization.get('resume');
2144
- }
2145
- get isUploading() {
2146
- return this.file.state === FileState.Uploading;
2147
- }
2148
- get isFailed() {
2149
- return this.file.state === FileState.Failed;
2150
- }
2151
- get isPaused() {
2152
- return this.file.state === FileState.Paused;
2153
- }
2154
- get isResumable() {
2155
- const service = this.uploadService;
2156
- const isResumable = service.async.chunk && service.chunk.resumable;
2157
- const isUploading = (this.file.state === FileState.Paused) || (this.file.state === FileState.Uploading);
2158
- return isResumable && isUploading;
2159
- }
2160
- get isActionButtonVisible() {
2161
- if ((this.file.state === FileState.Uploaded || this.file.state === FileState.Initial) &&
2162
- !this.uploadService.async.removeUrl && this.uploadService.component === 'Upload') {
2163
- return false;
2164
- }
2165
- return true;
2166
- }
2167
- }
2168
- FileListItemActionButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListItemActionButtonComponent, deps: [{ token: UploadService }, { token: i1$1.LocalizationService }, { token: NavigationService }], target: i0.ɵɵFactoryTarget.Component });
2169
- FileListItemActionButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileListItemActionButtonComponent, isStandalone: true, selector: "kendo-upload-file-list-item-action-button", inputs: { file: "file", disabled: "disabled", progress: "progress" }, ngImport: i0, template: `
2170
- <span class="k-upload-actions">
2171
- <span class="k-upload-pct" *ngIf="isUploading || isPaused">{{progress}}%</span>
2172
-
2173
- <button
2174
- *ngIf="isFailed"
2175
- kendoButton
2176
- type="button"
2177
- class="k-upload-action k-retry"
2178
- fillMode="flat"
2179
- [attr.tabIndex]="-1"
2180
- [attr.aria-hidden]="true"
2181
- [attr.title]="retryButtonTitle"
2182
- [svgIcon]="retrySVGIcon"
2183
- icon="refresh-sm"
2184
- (pointerdown)="$event.preventDefault()"
2185
- (click)="onRetryClick()"
2186
- ></button>
2187
-
2188
- <button
2189
- *ngIf="isResumable"
2190
- kendoButton
2191
- type="button"
2192
- class="k-upload-action"
2193
- fillMode="flat"
2194
- [attr.tabIndex]="-1"
2195
- [attr.aria-hidden]="true"
2196
- [attr.title]="pauseResumeButtonTitle"
2197
- [svgIcon]="isPaused ? playSVGIcon : pauseSVGIcon"
2198
- [icon]="isPaused ? 'play-sm' : 'pause-sm'"
2199
- (pointerdown)="$event.preventDefault()"
2200
- (click)="onPauseResumeClick()"
2201
- ></button>
2202
-
2203
- <button
2204
- *ngIf="isActionButtonVisible"
2205
- kendoButton
2206
- class="k-upload-action"
2207
- [class.k-delete]="!isUploading"
2208
- fillMode="flat"
2209
- type="button"
2210
- [attr.tabIndex]="-1"
2211
- [attr.aria-hidden]="true"
2212
- [attr.title]="actionButtonTitle"
2213
- [svgIcon]="isUploading ? cancelSVGIcon : deleteSVGIcon"
2214
- [icon]="isUploading ? 'cancel' : 'x'"
2215
- (click)="onRemoveCancelClick($event)"
2216
- ></button>
2217
- </span>
2218
- `, isInline: true, dependencies: [{ kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }] });
2219
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListItemActionButtonComponent, decorators: [{
2220
- type: Component,
2221
- args: [{
2222
- selector: 'kendo-upload-file-list-item-action-button',
2223
- template: `
2224
- <span class="k-upload-actions">
2225
- <span class="k-upload-pct" *ngIf="isUploading || isPaused">{{progress}}%</span>
2226
-
2227
- <button
2228
- *ngIf="isFailed"
2229
- kendoButton
2230
- type="button"
2231
- class="k-upload-action k-retry"
2232
- fillMode="flat"
2233
- [attr.tabIndex]="-1"
2234
- [attr.aria-hidden]="true"
2235
- [attr.title]="retryButtonTitle"
2236
- [svgIcon]="retrySVGIcon"
2237
- icon="refresh-sm"
2238
- (pointerdown)="$event.preventDefault()"
2239
- (click)="onRetryClick()"
2240
- ></button>
2241
-
2242
- <button
2243
- *ngIf="isResumable"
2244
- kendoButton
2245
- type="button"
2246
- class="k-upload-action"
2247
- fillMode="flat"
2248
- [attr.tabIndex]="-1"
2249
- [attr.aria-hidden]="true"
2250
- [attr.title]="pauseResumeButtonTitle"
2251
- [svgIcon]="isPaused ? playSVGIcon : pauseSVGIcon"
2252
- [icon]="isPaused ? 'play-sm' : 'pause-sm'"
2253
- (pointerdown)="$event.preventDefault()"
2254
- (click)="onPauseResumeClick()"
2255
- ></button>
2256
-
2257
- <button
2258
- *ngIf="isActionButtonVisible"
2259
- kendoButton
2260
- class="k-upload-action"
2261
- [class.k-delete]="!isUploading"
2262
- fillMode="flat"
2263
- type="button"
2264
- [attr.tabIndex]="-1"
2265
- [attr.aria-hidden]="true"
2266
- [attr.title]="actionButtonTitle"
2267
- [svgIcon]="isUploading ? cancelSVGIcon : deleteSVGIcon"
2268
- [icon]="isUploading ? 'cancel' : 'x'"
2269
- (click)="onRemoveCancelClick($event)"
2270
- ></button>
2271
- </span>
2272
- `,
2273
- standalone: true,
2274
- imports: [NgIf, ButtonComponent]
2275
- }]
2276
- }], ctorParameters: function () { return [{ type: UploadService }, { type: i1$1.LocalizationService }, { type: NavigationService }]; }, propDecorators: { file: [{
2277
- type: Input
2278
- }], disabled: [{
2279
- type: Input
2280
- }], progress: [{
2281
- type: Input
2282
- }] } });
2283
-
2284
- /**
2285
- * @hidden
2286
- */
2287
- class FileListMultipleItemsComponent extends FileListItemBase {
2288
- constructor(localization, uploadService) {
2289
- super(uploadService);
2290
- this.localization = localization;
2291
- this.copySVGIcon = copyIcon;
2292
- this.subscribeUploadProgress((args) => {
2293
- if (args.files[0].uid === this.files[0].uid) {
2294
- this.progressComplete = args.percentComplete;
2295
- }
2296
- });
2297
- }
2298
- get showProgress() {
2299
- const showProgress = this.files[0].state === FileState.Uploading || this.files[0].state === FileState.Paused;
2300
- return showProgress ? 'active' : 'inactive';
2301
- }
2302
- ngOnInit() {
2303
- this.filesHaveErrors = super.filesHaveValidationErrors(this.files);
2304
- }
2305
- fileStatusText(file) {
2306
- const errors = file.validationErrors;
2307
- if (!isPresent(errors)) {
2308
- return this.getTotalFilesSizeMessage([file]);
2309
- }
2310
- return this.getFileValidationMessage(file);
2311
- }
2312
- get batchStatusText() {
2313
- const state = this.files[0].state;
2314
- const fileCount = this.files.length;
2315
- if (state === FileState.Uploaded) {
2316
- return `${fileCount} ${this.textFor('filesBatchStatusUploaded')}`;
2317
- }
2318
- if (state === FileState.Failed) {
2319
- return `${fileCount} ${this.textFor('filesBatchStatusFailed')}`;
2320
- }
2321
- return `${fileCount} ${this.textFor('filesBatchStatus')}`;
2322
- }
2323
- get isUploadSuccessful() {
2324
- return this.files[0].state === FileState.Uploaded;
2325
- }
2326
- get isUploadFailed() {
2327
- return this.files[0].state === FileState.Failed;
2328
- }
2329
- }
2330
- FileListMultipleItemsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListMultipleItemsComponent, deps: [{ token: i1$1.LocalizationService }, { token: UploadService }], target: i0.ɵɵFactoryTarget.Component });
2331
- FileListMultipleItemsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileListMultipleItemsComponent, isStandalone: true, selector: "kendo-upload-file-list-multiple-items", inputs: { disabled: "disabled", files: "files", fileInfoTemplate: "fileInfoTemplate" }, usesInheritance: true, ngImport: i0, template: `
2332
- <kendo-progressbar
2333
- [@progressState]="showProgress"
2334
- [value]="progressComplete"
2335
- [label]="{ visible: false }"
2336
- >
2337
- </kendo-progressbar>
2338
- <span class="k-file-icon-wrapper">
2339
- <kendo-icon-wrapper
2340
- name="copy"
2341
- size="xxlarge"
2342
- [svgIcon]="copySVGIcon"
2343
- innerCssClass="k-file-icon"
2344
- >
2345
- </kendo-icon-wrapper>
2346
- </span>
2347
- <span class="k-multiple-files-wrapper">
2348
- <ng-container *ngIf="!fileInfoTemplate">
2349
- <span *ngFor="let file of files" class="k-file-info">
2350
- <span [title]="file.name" class="k-file-name">
2351
- {{file.name}}
2352
- </span>
2353
- <span [attr.aria-live]="'polite'" [ngClass]="{
2354
- 'k-file-validation-message': file.validationErrors,
2355
- 'k-file-size': !file.validationErrors
2356
- }"
2357
- >{{fileStatusText(file)}}</span>
2358
- </span>
2359
- <span class="k-file-summary"
2360
- >{{batchStatusText}}</span>
2361
- </ng-container>
2362
- <ng-container
2363
- *ngIf="fileInfoTemplate"
2364
- [ngTemplateOutlet]="fileInfoTemplate.templateRef"
2365
- [ngTemplateOutletContext]="{
2366
- templateRef: fileInfoTemplate.templateRef,
2367
- state: files[0].state,
2368
- $implicit: files
2369
- }"></ng-container>
2370
- </span>
2371
- <kendo-upload-file-list-item-action-button
2372
- [file]='files[0]'
2373
- [disabled]='disabled'
2374
- [progress]='progressComplete'>
2375
- </kendo-upload-file-list-item-action-button>
2376
- `, isInline: true, dependencies: [{ kind: "component", type: ProgressBarComponent, selector: "kendo-progressbar", inputs: ["label", "progressCssStyle", "progressCssClass", "emptyCssStyle", "emptyCssClass", "animation"], outputs: ["animationEnd"], exportAs: ["kendoProgressBar"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FileListItemActionButtonComponent, selector: "kendo-upload-file-list-item-action-button", inputs: ["file", "disabled", "progress"] }], animations: [
2377
- trigger('progressState', [
2378
- state('active', style({ opacity: 1 })),
2379
- state('inactive', style({ opacity: 0 })),
2380
- transition('void => active', style({ opacity: 0 })),
2381
- transition('inactive => active', style({ opacity: 1 })),
2382
- transition('active => inactive', animate('1s 2s ease-out'))
2383
- ])
2384
- ] });
2385
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListMultipleItemsComponent, decorators: [{
2386
- type: Component,
2387
- args: [{
2388
- animations: [
2389
- trigger('progressState', [
2390
- state('active', style({ opacity: 1 })),
2391
- state('inactive', style({ opacity: 0 })),
2392
- transition('void => active', style({ opacity: 0 })),
2393
- transition('inactive => active', style({ opacity: 1 })),
2394
- transition('active => inactive', animate('1s 2s ease-out'))
2395
- ])
2396
- ],
2397
- selector: 'kendo-upload-file-list-multiple-items',
2398
- template: `
2399
- <kendo-progressbar
2400
- [@progressState]="showProgress"
2401
- [value]="progressComplete"
2402
- [label]="{ visible: false }"
2403
- >
2404
- </kendo-progressbar>
2405
- <span class="k-file-icon-wrapper">
2406
- <kendo-icon-wrapper
2407
- name="copy"
2408
- size="xxlarge"
2409
- [svgIcon]="copySVGIcon"
2410
- innerCssClass="k-file-icon"
2411
- >
2412
- </kendo-icon-wrapper>
2413
- </span>
2414
- <span class="k-multiple-files-wrapper">
2415
- <ng-container *ngIf="!fileInfoTemplate">
2416
- <span *ngFor="let file of files" class="k-file-info">
2417
- <span [title]="file.name" class="k-file-name">
2418
- {{file.name}}
2419
- </span>
2420
- <span [attr.aria-live]="'polite'" [ngClass]="{
2421
- 'k-file-validation-message': file.validationErrors,
2422
- 'k-file-size': !file.validationErrors
2423
- }"
2424
- >{{fileStatusText(file)}}</span>
2425
- </span>
2426
- <span class="k-file-summary"
2427
- >{{batchStatusText}}</span>
2428
- </ng-container>
2429
- <ng-container
2430
- *ngIf="fileInfoTemplate"
2431
- [ngTemplateOutlet]="fileInfoTemplate.templateRef"
2432
- [ngTemplateOutletContext]="{
2433
- templateRef: fileInfoTemplate.templateRef,
2434
- state: files[0].state,
2435
- $implicit: files
2436
- }"></ng-container>
2437
- </span>
2438
- <kendo-upload-file-list-item-action-button
2439
- [file]='files[0]'
2440
- [disabled]='disabled'
2441
- [progress]='progressComplete'>
2442
- </kendo-upload-file-list-item-action-button>
2443
- `,
2444
- standalone: true,
2445
- imports: [ProgressBarComponent, IconWrapperComponent, NgIf, NgFor, NgClass, NgTemplateOutlet, FileListItemActionButtonComponent]
2446
- }]
2447
- }], ctorParameters: function () { return [{ type: i1$1.LocalizationService }, { type: UploadService }]; }, propDecorators: { disabled: [{
2448
- type: Input
2449
- }], files: [{
2450
- type: Input
2451
- }], fileInfoTemplate: [{
2452
- type: Input
2453
- }] } });
2454
-
2455
- /**
2456
- * @hidden
2457
- */
2458
- class FileListSingleItemComponent extends FileListItemBase {
2459
- constructor(localization, uploadService) {
2460
- super(uploadService);
2461
- this.localization = localization;
2462
- this.subscribeUploadProgress((args) => {
2463
- if (args.files[0].uid === this.file.uid) {
2464
- this.progressComplete = args.percentComplete;
2465
- }
2466
- });
2467
- }
2468
- get fileStatusText() {
2469
- const errors = this.file.validationErrors;
2470
- if (this.file.state === FileState.Uploaded) {
2471
- return `${this.textFor('fileStatusUploaded')}`;
2472
- }
2473
- if (this.file.state === FileState.Failed) {
2474
- return `${this.textFor('fileStatusFailed')}`;
2475
- }
2476
- if (!isPresent(errors)) {
2477
- return this.getTotalFilesSizeMessage([this.file]);
2478
- }
2479
- return this.getFileValidationMessage(this.file);
2480
- }
2481
- get showProgress() {
2482
- const showProgress = this.file.state === FileState.Uploading || this.file.state === FileState.Paused;
2483
- return showProgress ? 'active' : 'inactive';
2484
- }
2485
- get fileGroupClass() {
2486
- return getFileGroupCssClass(this.file.extension ? this.file.extension : '');
2487
- }
2488
- get fileSVGGroupIcon() {
2489
- const initial = fileIcon;
2490
- if (this.file.extension) {
2491
- for (const group in fileGroupMap) {
2492
- if (fileGroupMap[group].indexOf(this.file.extension) >= 0) {
2493
- return fileSVGGroupMap[group];
2494
- }
2495
- }
2496
- }
2497
- return initial;
2498
- }
2499
- get isUploadSuccessful() {
2500
- return this.file.state === FileState.Uploaded;
2501
- }
2502
- get isUploadFailed() {
2503
- return this.file.state === FileState.Failed;
2504
- }
2505
- get isNotYetUploaded() {
2506
- return !this.isUploadFailed && !this.isUploadSuccessful;
2507
- }
2508
- }
2509
- FileListSingleItemComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListSingleItemComponent, deps: [{ token: i1$1.LocalizationService }, { token: UploadService }], target: i0.ɵɵFactoryTarget.Component });
2510
- FileListSingleItemComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileListSingleItemComponent, isStandalone: true, selector: "kendo-upload-file-list-single-item", inputs: { disabled: "disabled", file: "file", fileInfoTemplate: "fileInfoTemplate" }, usesInheritance: true, ngImport: i0, template: `
2511
- <kendo-progressbar
2512
- [@progressState]="showProgress"
2513
- [value]="progressComplete"
2514
- [label]="{ visible: false }"
2515
- >
2516
- </kendo-progressbar>
2517
- <span class="k-file-icon-wrapper">
2518
- <kendo-icon-wrapper
2519
- size="xxlarge"
2520
- [name]="fileGroupClass"
2521
- [svgIcon]="fileSVGGroupIcon"
2522
- innerCssClass="k-file-icon"
2523
- >
2524
- </kendo-icon-wrapper>
2525
- </span>
2526
- <span class="k-file-info">
2527
- <ng-container *ngIf="!fileInfoTemplate">
2528
- <span class="k-file-name" [title]="file.name">{{ file.name }}</span>
2529
- <span [attr.aria-live]="'polite'" [ngClass]="{
2530
- 'k-file-validation-message': file.validationErrors,
2531
- 'k-file-size': !file.validationErrors && isNotYetUploaded,
2532
- 'k-file-summary': isUploadSuccessful || isUploadFailed
2533
- }"
2534
- >{{fileStatusText}}</span>
2535
- </ng-container>
2536
- <ng-container *ngIf="fileInfoTemplate" [ngTemplateOutlet]="fileInfoTemplate.templateRef" [ngTemplateOutletContext]="{
2537
- templateRef: fileInfoTemplate.templateRef,
2538
- state: file.state,
2539
- $implicit: [file]
2540
- }"></ng-container>
2541
- </span>
2542
- <kendo-upload-file-list-item-action-button
2543
- [file]='file'
2544
- [disabled]='disabled'
2545
- [progress]='progressComplete'>
2546
- </kendo-upload-file-list-item-action-button>
2547
- `, isInline: true, dependencies: [{ kind: "component", type: ProgressBarComponent, selector: "kendo-progressbar", inputs: ["label", "progressCssStyle", "progressCssClass", "emptyCssStyle", "emptyCssClass", "animation"], outputs: ["animationEnd"], exportAs: ["kendoProgressBar"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: FileListItemActionButtonComponent, selector: "kendo-upload-file-list-item-action-button", inputs: ["file", "disabled", "progress"] }], animations: [
2548
- trigger('progressState', [
2549
- state('active', style({ opacity: 1 })),
2550
- state('inactive', style({ opacity: 0 })),
2551
- transition('void => active', style({ opacity: 0 })),
2552
- transition('inactive => active', style({ opacity: 1 })),
2553
- transition('active => inactive', animate('1s 2s ease-out'))
2554
- ])
2555
- ] });
2556
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListSingleItemComponent, decorators: [{
2557
- type: Component,
2558
- args: [{
2559
- animations: [
2560
- trigger('progressState', [
2561
- state('active', style({ opacity: 1 })),
2562
- state('inactive', style({ opacity: 0 })),
2563
- transition('void => active', style({ opacity: 0 })),
2564
- transition('inactive => active', style({ opacity: 1 })),
2565
- transition('active => inactive', animate('1s 2s ease-out'))
2566
- ])
2567
- ],
2568
- selector: 'kendo-upload-file-list-single-item',
2569
- template: `
2570
- <kendo-progressbar
2571
- [@progressState]="showProgress"
2572
- [value]="progressComplete"
2573
- [label]="{ visible: false }"
2574
- >
2575
- </kendo-progressbar>
2576
- <span class="k-file-icon-wrapper">
2577
- <kendo-icon-wrapper
2578
- size="xxlarge"
2579
- [name]="fileGroupClass"
2580
- [svgIcon]="fileSVGGroupIcon"
2581
- innerCssClass="k-file-icon"
2582
- >
2583
- </kendo-icon-wrapper>
2584
- </span>
2585
- <span class="k-file-info">
2586
- <ng-container *ngIf="!fileInfoTemplate">
2587
- <span class="k-file-name" [title]="file.name">{{ file.name }}</span>
2588
- <span [attr.aria-live]="'polite'" [ngClass]="{
2589
- 'k-file-validation-message': file.validationErrors,
2590
- 'k-file-size': !file.validationErrors && isNotYetUploaded,
2591
- 'k-file-summary': isUploadSuccessful || isUploadFailed
2592
- }"
2593
- >{{fileStatusText}}</span>
2594
- </ng-container>
2595
- <ng-container *ngIf="fileInfoTemplate" [ngTemplateOutlet]="fileInfoTemplate.templateRef" [ngTemplateOutletContext]="{
2596
- templateRef: fileInfoTemplate.templateRef,
2597
- state: file.state,
2598
- $implicit: [file]
2599
- }"></ng-container>
2600
- </span>
2601
- <kendo-upload-file-list-item-action-button
2602
- [file]='file'
2603
- [disabled]='disabled'
2604
- [progress]='progressComplete'>
2605
- </kendo-upload-file-list-item-action-button>
2606
- `,
2607
- standalone: true,
2608
- imports: [ProgressBarComponent, IconWrapperComponent, NgIf, NgClass, NgTemplateOutlet, FileListItemActionButtonComponent]
2609
- }]
2610
- }], ctorParameters: function () { return [{ type: i1$1.LocalizationService }, { type: UploadService }]; }, propDecorators: { disabled: [{
2611
- type: Input
2612
- }], file: [{
2613
- type: Input
2614
- }], fileInfoTemplate: [{
2615
- type: Input
2616
- }] } });
2617
-
2618
- /* eslint-disable @angular-eslint/component-selector */
2619
- /**
2620
- * @hidden
2621
- */
2622
- class FileListComponent {
2623
- constructor(uploadService, navigation) {
2624
- this.uploadService = uploadService;
2625
- this.navigation = navigation;
2626
- this.fileListRole = 'list';
2627
- this.onItemFocus();
2628
- this.onItemAction();
2629
- }
2630
- onItemFocus() {
2631
- this.focusSubscription = this.navigation.onFileFocus.subscribe((index) => {
2632
- this.fileListItems.toArray()[index].focus();
2633
- });
2634
- }
2635
- onItemAction() {
2636
- this.actionSubscription = this.navigation.onFileAction.subscribe((key) => {
2637
- this.itemActionHandler(key);
2638
- });
2639
- }
2640
- itemActionHandler(key) {
2641
- const index = this.navigation.focusedIndex;
2642
- const filesArray = this.fileListItems.toArray();
2643
- const numberOfFiles = filesArray.length;
2644
- const item = filesArray[index];
2645
- const uid = item.uidAttribute;
2646
- const files = this.uploadService.files.get(uid);
2647
- if (key === Keys.Escape && files[0].state === FileState.Uploading) {
2648
- this.uploadService.cancelFiles(uid);
2649
- this.navigation.focusSelectButton();
2650
- return;
2651
- }
2652
- if (key === Keys.Enter && files[0].state === FileState.Failed) {
2653
- this.uploadService.retryFiles(uid);
2654
- return;
2655
- }
2656
- if (key === Keys.Delete) {
2657
- if (files[0].state === FileState.Uploading) {
2658
- this.uploadService.cancelFiles(uid);
2659
- }
2660
- else if (this.hasDelete(item)) {
2661
- this.uploadService.removeFiles(uid);
2662
- }
2663
- if (index < numberOfFiles - 1) {
2664
- filesArray[index + 1].focus();
2665
- }
2666
- else if (numberOfFiles === 1) {
2667
- this.navigation.focusSelectButton();
2668
- }
2669
- else if (index === numberOfFiles - 1) {
2670
- this.navigation.focusedIndex = this.navigation.focusedFileIndex = index - 1;
2671
- filesArray[index - 1].focus();
2672
- }
2673
- }
2674
- const isUploadChunk = this.uploadService.async.chunk;
2675
- const canTogglePauseResume = key === Keys.Space && files[0].state !== FileState.Uploaded;
2676
- if (canTogglePauseResume && isUploadChunk) {
2677
- if (files[0].state === FileState.Paused) {
2678
- this.uploadService.resumeFile(uid);
2679
- }
2680
- else {
2681
- this.uploadService.pauseFile(uid);
2682
- }
2683
- }
2684
- }
2685
- hasDelete(item) {
2686
- return item.element.nativeElement.getElementsByClassName('k-svg-i-x').length > 0;
2687
- }
2688
- ngOnDestroy() {
2689
- this.focusSubscription.unsubscribe();
2690
- this.actionSubscription.unsubscribe();
2691
- }
2692
- }
2693
- FileListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListComponent, deps: [{ token: UploadService }, { token: NavigationService }], target: i0.ɵɵFactoryTarget.Component });
2694
- FileListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileListComponent, isStandalone: true, selector: "[kendo-upload-file-list]", inputs: { disabled: "disabled", fileList: "fileList", fileTemplate: "fileTemplate", fileInfoTemplate: "fileInfoTemplate" }, host: { properties: { "attr.role": "this.fileListRole" } }, viewQueries: [{ propertyName: "fileListItems", predicate: FileListItemDirective, descendants: true }], ngImport: i0, template: `
2695
- <ng-template ngFor
2696
- [ngForOf]="fileList"
2697
- let-files
2698
- let-index="index">
2699
- <li kendoUploadFileListItem [files]='files' [index]='index' role="listitem">
2700
- <kendo-upload-file-list-single-item
2701
- class='k-file-single'
2702
- *ngIf='files.length === 1 && !fileTemplate'
2703
- [disabled]='disabled'
2704
- [file]='files[0]'
2705
- [fileInfoTemplate]="fileInfoTemplate"></kendo-upload-file-list-single-item>
2706
- <kendo-upload-file-list-multiple-items
2707
- class='k-file-multiple'
2708
- *ngIf='files.length > 1 && !fileTemplate'
2709
- [disabled]='disabled'
2710
- [files]='files'
2711
- [fileInfoTemplate]="fileInfoTemplate"></kendo-upload-file-list-multiple-items>
2712
- <ng-container
2713
- *ngIf="fileTemplate" [ngTemplateOutlet]="fileTemplate.templateRef" [ngTemplateOutletContext]="{
2714
- templateRef: fileTemplate.templateRef,
2715
- state: files[0].state,
2716
- $implicit: files
2717
- }"></ng-container>
2718
- </li>
2719
- </ng-template>
2720
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: FileListItemDirective, selector: "[kendoUploadFileListItem]", inputs: ["files", "index"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FileListSingleItemComponent, selector: "kendo-upload-file-list-single-item", inputs: ["disabled", "file", "fileInfoTemplate"] }, { kind: "component", type: FileListMultipleItemsComponent, selector: "kendo-upload-file-list-multiple-items", inputs: ["disabled", "files", "fileInfoTemplate"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
2721
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileListComponent, decorators: [{
2722
- type: Component,
2723
- args: [{
2724
- selector: '[kendo-upload-file-list]',
2725
- template: `
2726
- <ng-template ngFor
2727
- [ngForOf]="fileList"
2728
- let-files
2729
- let-index="index">
2730
- <li kendoUploadFileListItem [files]='files' [index]='index' role="listitem">
2731
- <kendo-upload-file-list-single-item
2732
- class='k-file-single'
2733
- *ngIf='files.length === 1 && !fileTemplate'
2734
- [disabled]='disabled'
2735
- [file]='files[0]'
2736
- [fileInfoTemplate]="fileInfoTemplate"></kendo-upload-file-list-single-item>
2737
- <kendo-upload-file-list-multiple-items
2738
- class='k-file-multiple'
2739
- *ngIf='files.length > 1 && !fileTemplate'
2740
- [disabled]='disabled'
2741
- [files]='files'
2742
- [fileInfoTemplate]="fileInfoTemplate"></kendo-upload-file-list-multiple-items>
2743
- <ng-container
2744
- *ngIf="fileTemplate" [ngTemplateOutlet]="fileTemplate.templateRef" [ngTemplateOutletContext]="{
2745
- templateRef: fileTemplate.templateRef,
2746
- state: files[0].state,
2747
- $implicit: files
2748
- }"></ng-container>
2749
- </li>
2750
- </ng-template>
2751
- `,
2752
- standalone: true,
2753
- imports: [NgFor, FileListItemDirective, NgIf, FileListSingleItemComponent, FileListMultipleItemsComponent, NgTemplateOutlet]
2754
- }]
2755
- }], ctorParameters: function () { return [{ type: UploadService }, { type: NavigationService }]; }, propDecorators: { disabled: [{
2756
- type: Input
2757
- }], fileList: [{
2758
- type: Input
2759
- }], fileTemplate: [{
2760
- type: Input
2761
- }], fileInfoTemplate: [{
2762
- type: Input
2763
- }], fileListItems: [{
2764
- type: ViewChildren,
2765
- args: [FileListItemDirective]
2766
- }], fileListRole: [{
2767
- type: HostBinding,
2768
- args: ['attr.role']
2769
- }] } });
2770
-
2771
- /**
2772
- * @hidden
2773
- */
2774
- class UploadStatusTotalComponent {
2775
- constructor(localization) {
2776
- this.localization = localization;
2777
- this.checkmarkIcon = checkIcon;
2778
- this.exceptionSVGIcon = exclamationCircleIcon;
2779
- this.uploadSVGIcon = uploadIcon;
2780
- this.pauseSVGIcon = pauseSmIcon;
2781
- }
2782
- get iconClass() {
2783
- if (!this.isUploading && !this.isFailed) {
2784
- return 'checkmark';
2785
- }
2786
- if (!this.isUploading && this.isFailed) {
2787
- return 'exception';
2788
- }
2789
- if (this.isUploading) {
2790
- return 'upload';
2791
- }
2792
- if (this.isPaused) {
2793
- return 'pause-sm';
2794
- }
2795
- }
2796
- get SVGIconClass() {
2797
- if (!this.isUploading && !this.isFailed) {
2798
- return this.checkmarkIcon;
2799
- }
2800
- if (!this.isUploading && this.isFailed) {
2801
- return this.exceptionSVGIcon;
2802
- }
2803
- if (this.isUploading) {
2804
- return this.uploadSVGIcon;
2805
- }
2806
- if (this.isPaused) {
2807
- return this.pauseSVGIcon;
2808
- }
2809
- }
2810
- ngDoCheck() {
2811
- this.isPaused = this.fileList.hasFileWithState([FileState.Paused]);
2812
- this.isFailed = this.fileList.hasFileWithState([FileState.Failed]);
2813
- this.isUploading = this.fileList.hasFileWithState([FileState.Uploading]);
2814
- if (this.isPaused && !this.isUploading) {
2815
- this.statusText = this.localization.get('headerStatusPaused');
2816
- }
2817
- else {
2818
- this.statusText = this.isUploading ? this.localization.get('headerStatusUploading')
2819
- : this.localization.get('headerStatusUploaded');
2820
- }
2821
- }
2822
- }
2823
- UploadStatusTotalComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadStatusTotalComponent, deps: [{ token: i1$1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
2824
- UploadStatusTotalComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UploadStatusTotalComponent, isStandalone: true, selector: "kendo-upload-status-total", inputs: { fileList: "fileList" }, ngImport: i0, template: `
2825
- <kendo-icon-wrapper
2826
- [name]="iconClass"
2827
- [svgIcon]="SVGIconClass"
2828
- >
2829
- </kendo-icon-wrapper>
2830
- {{statusText}}
2831
- `, isInline: true, dependencies: [{ kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] });
2832
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadStatusTotalComponent, decorators: [{
2833
- type: Component,
2834
- args: [{
2835
- selector: 'kendo-upload-status-total',
2836
- template: `
2837
- <kendo-icon-wrapper
2838
- [name]="iconClass"
2839
- [svgIcon]="SVGIconClass"
2840
- >
2841
- </kendo-icon-wrapper>
2842
- {{statusText}}
2843
- `,
2844
- standalone: true,
2845
- imports: [IconWrapperComponent]
2846
- }]
2847
- }], ctorParameters: function () { return [{ type: i1$1.LocalizationService }]; }, propDecorators: { fileList: [{
2848
- type: Input
2849
- }] } });
2850
-
2851
- /**
2852
- * @hidden
2853
- */
2854
- class FileSelectDirective {
2855
- constructor(uploadService, navigation, el) {
2856
- this.uploadService = uploadService;
2857
- this.navigation = navigation;
2858
- this.type = "file";
2859
- this.autocomplete = "off";
2860
- this.tabIndex = -1;
2861
- this.ariaHidden = true;
2862
- this.classNames = true;
2863
- this.element = el;
2864
- }
2865
- get nameAttribute() {
2866
- return this.uploadService.async.saveField;
2867
- }
2868
- get multipleAttribute() {
2869
- return this.multiple ? "multiple" : null;
2870
- }
2871
- get dirAttribute() {
2872
- return this.dir;
2873
- }
2874
- get disabledAttribute() {
2875
- return this.disabled ? "true" : null;
2876
- }
2877
- get acceptAttribute() {
2878
- return this.accept ? this.accept : null;
2879
- }
2880
- get requiredAttribute() {
2881
- return this.required ? "" : null;
2882
- }
2883
- onInputChange(event) {
2884
- const ua = navigator.userAgent;
2885
- const webkit = /(webkit)[ \/]([\w.]+)/i;
2886
- const ie = /(windows)[ \/]([\w.]+)/i;
2887
- let selectedFiles = inputFiles(event.target);
2888
- selectedFiles = assignGuidToFiles(selectedFiles, !this.uploadService.async.batch);
2889
- validateFiles(selectedFiles, this.restrictions);
2890
- if (!this.multiple) {
2891
- this.uploadService.clearFiles();
2892
- }
2893
- this.uploadService.addFiles(selectedFiles);
2894
- /*
2895
- Chrome, IE, Edge and Safari do not trigger a `change` event
2896
- when a file with the same name is selected a number of consecutive times.
2897
- As a workaround, clear the input value after handling the file.
2898
- */
2899
- const native = this.element.nativeElement;
2900
- if (ua.match(webkit) || ua.match(ie)) {
2901
- native.type = "";
2902
- native.type = "file";
2903
- }
2904
- setTimeout(() => {
2905
- this.navigation.focusedIndex = -1;
2906
- });
2907
- }
2908
- }
2909
- FileSelectDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectDirective, deps: [{ token: UploadService }, { token: NavigationService }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
2910
- FileSelectDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: FileSelectDirective, isStandalone: true, selector: "[kendoFileSelect]", inputs: { dir: "dir", disabled: "disabled", multiple: "multiple", restrictions: "restrictions", accept: "accept", required: "required" }, host: { listeners: { "change": "onInputChange($event)" }, properties: { "attr.type": "this.type", "attr.autocomplete": "this.autocomplete", "attr.tabindex": "this.tabIndex", "attr.aria-hidden": "this.ariaHidden", "class.k-hidden": "this.classNames", "attr.name": "this.nameAttribute", "attr.multiple": "this.multipleAttribute", "attr.dir": "this.dirAttribute", "attr.disabled": "this.disabledAttribute", "attr.accept": "this.acceptAttribute", "attr.required": "this.requiredAttribute" } }, ngImport: i0 });
2911
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectDirective, decorators: [{
2912
- type: Directive,
2913
- args: [{
2914
- selector: '[kendoFileSelect]',
2915
- standalone: true
2916
- }]
2917
- }], ctorParameters: function () { return [{ type: UploadService }, { type: NavigationService }, { type: i0.ElementRef }]; }, propDecorators: { dir: [{
2918
- type: Input
2919
- }], disabled: [{
2920
- type: Input
2921
- }], multiple: [{
2922
- type: Input
2923
- }], restrictions: [{
2924
- type: Input
2925
- }], accept: [{
2926
- type: Input
2927
- }], required: [{
2928
- type: Input
2929
- }], type: [{
2930
- type: HostBinding,
2931
- args: ["attr.type"]
2932
- }], autocomplete: [{
2933
- type: HostBinding,
2934
- args: ["attr.autocomplete"]
2935
- }], tabIndex: [{
2936
- type: HostBinding,
2937
- args: ["attr.tabindex"]
2938
- }], ariaHidden: [{
2939
- type: HostBinding,
2940
- args: ["attr.aria-hidden"]
2941
- }], classNames: [{
2942
- type: HostBinding,
2943
- args: ["class.k-hidden"]
2944
- }], nameAttribute: [{
2945
- type: HostBinding,
2946
- args: ["attr.name"]
2947
- }], multipleAttribute: [{
2948
- type: HostBinding,
2949
- args: ["attr.multiple"]
2950
- }], dirAttribute: [{
2951
- type: HostBinding,
2952
- args: ["attr.dir"]
2953
- }], disabledAttribute: [{
2954
- type: HostBinding,
2955
- args: ["attr.disabled"]
2956
- }], acceptAttribute: [{
2957
- type: HostBinding,
2958
- args: ["attr.accept"]
2959
- }], requiredAttribute: [{
2960
- type: HostBinding,
2961
- args: ["attr.required"]
2962
- }], onInputChange: [{
2963
- type: HostListener,
2964
- args: ["change", ["$event"]]
2965
- }] } });
2966
-
2967
- /**
2968
- * @hidden
2969
- */
2970
- class DropZoneBase {
2971
- constructor(element, renderer, cssClass) {
2972
- this.element = element;
2973
- this.renderer = renderer;
2974
- this.hideIntervalElement = null;
2975
- this.hoverClass = cssClass;
2976
- }
2977
- /**
2978
- * @hidden
2979
- */
2980
- onElementDragEnterListener() {
2981
- this.addClass(this.hoverClass);
2982
- this.lastDragElement = new Date();
2983
- if (!this.hideIntervalElement) {
2984
- this.hideIntervalElement = setInterval(() => {
2985
- if (this.calculateTimeDiff(this.lastDragElement) < 100) {
2986
- return;
2987
- }
2988
- this.removeClass(this.hoverClass);
2989
- clearInterval(this.hideIntervalElement);
2990
- this.hideIntervalElement = null;
2991
- }, 100);
2992
- }
2993
- return false;
2994
- }
2995
- /**
2996
- * @hidden
2997
- */
2998
- onElementDragOverListener() {
2999
- this.lastDragElement = new Date();
3000
- return false;
3001
- }
3002
- calculateTimeDiff(prevEvent) {
3003
- return new Date().getTime() - prevEvent.getTime();
3004
- }
3005
- addClass(className) {
3006
- this.renderer.addClass(this.element.nativeElement, className);
3007
- }
3008
- removeClass(className) {
3009
- this.renderer.removeClass(this.element.nativeElement, className);
3010
- }
3011
- }
3012
- DropZoneBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DropZoneBase, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: 'hoverClass' }], target: i0.ɵɵFactoryTarget.Directive });
3013
- DropZoneBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: DropZoneBase, host: { listeners: { "dragenter": "onElementDragEnterListener()", "dragover": "onElementDragOverListener()" } }, ngImport: i0 });
3014
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DropZoneBase, decorators: [{
3015
- type: Directive
3016
- }], ctorParameters: function () {
3017
- return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: undefined, decorators: [{
3018
- type: Inject,
3019
- args: ['hoverClass']
3020
- }] }];
3021
- }, propDecorators: { onElementDragEnterListener: [{
3022
- type: HostListener,
3023
- args: ['dragenter']
3024
- }], onElementDragOverListener: [{
3025
- type: HostListener,
3026
- args: ['dragover']
3027
- }] } });
3028
-
3029
- /**
3030
- * @hidden
3031
- */
3032
- class DropZoneInternalDirective extends DropZoneBase {
3033
- constructor(element, renderer, ngZone, uploadService) {
3034
- super(element, renderer, 'k-hover');
3035
- this.ngZone = ngZone;
3036
- this.uploadService = uploadService;
3037
- this.initialClassName = true;
3038
- this.hideIntervalDocument = null;
3039
- this.activeClass = 'k-dropzone-active';
3040
- this.ngZone.runOutsideAngular(() => {
3041
- this.unsubscribeDocumentDragEnter = this.renderer.listen('document', 'dragenter', () => this.onDocumentDragEnter());
3042
- this.unsubscribeDocumentDragOver = this.renderer.listen('document', 'dragover', () => this.onDocumentDragOver());
3043
- });
3044
- }
3045
- ngOnDestroy() {
3046
- this.ngZone.runOutsideAngular(() => {
3047
- if (this.unsubscribeDocumentDragEnter) {
3048
- this.unsubscribeDocumentDragEnter();
3049
- }
3050
- if (this.unsubscribeDocumentDragOver) {
3051
- this.unsubscribeDocumentDragOver();
3052
- }
3053
- });
3054
- }
3055
- onDocumentDragEnter() {
3056
- this.addClass(this.activeClass);
3057
- this.lastDragDocument = new Date();
3058
- if (!this.hideIntervalDocument) {
3059
- this.hideIntervalDocument = setInterval(() => {
3060
- if (this.calculateTimeDiff(this.lastDragDocument) < 100) {
3061
- return;
3062
- }
3063
- this.removeClass(this.activeClass);
3064
- clearInterval(this.hideIntervalDocument);
3065
- this.hideIntervalDocument = null;
3066
- }, 100);
3067
- }
3068
- return false;
3069
- }
3070
- /**
3071
- * @hidden
3072
- */
3073
- onDocumentDragOver() {
3074
- this.lastDragDocument = new Date();
3075
- return false;
3076
- }
3077
- onDropListener(event) {
3078
- const droppedFiles = event.dataTransfer.files;
3079
- if (droppedFiles.length > 0 && !this.disabled) {
3080
- let files = getAllFileInfo(droppedFiles);
3081
- files = assignGuidToFiles(files, !this.uploadService.async.batch);
3082
- if (!this.multiple) {
3083
- files.splice(1, files.length - 1);
3084
- this.uploadService.clearFiles();
3085
- }
3086
- validateFiles(files, this.restrictions);
3087
- this.uploadService.addFiles(files);
3088
- }
3089
- return false;
3090
- }
3091
- }
3092
- DropZoneInternalDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DropZoneInternalDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: UploadService }], target: i0.ɵɵFactoryTarget.Directive });
3093
- DropZoneInternalDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: DropZoneInternalDirective, isStandalone: true, selector: "\n [kendoUploadInternalDropZone],\n [kendoFileSelectInternalDropZone]\n ", inputs: { disabled: "disabled", multiple: "multiple", restrictions: "restrictions" }, host: { listeners: { "drop": "onDropListener($event)" }, properties: { "class.k-dropzone": "this.initialClassName", "class.k-upload-dropzone": "this.initialClassName" } }, usesInheritance: true, ngImport: i0 });
3094
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DropZoneInternalDirective, decorators: [{
3095
- type: Directive,
3096
- args: [{
3097
- selector: `
3098
- [kendoUploadInternalDropZone],
3099
- [kendoFileSelectInternalDropZone]
3100
- `,
3101
- standalone: true
3102
- }]
3103
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: UploadService }]; }, propDecorators: { disabled: [{
3104
- type: Input
3105
- }], multiple: [{
3106
- type: Input
3107
- }], restrictions: [{
3108
- type: Input
3109
- }], initialClassName: [{
3110
- type: HostBinding,
3111
- args: ['class.k-dropzone']
3112
- }, {
3113
- type: HostBinding,
3114
- args: ['class.k-upload-dropzone']
3115
- }], onDropListener: [{
3116
- type: HostListener,
3117
- args: ['drop', ['$event']]
3118
- }] } });
3119
-
3120
- /**
3121
- * @hidden
3122
- */
3123
- class Messages extends ComponentMessages {
3124
- }
3125
- Messages.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Messages, deps: null, target: i0.ɵɵFactoryTarget.Directive });
3126
- Messages.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: Messages, inputs: { cancel: "cancel", clearSelectedFiles: "clearSelectedFiles", dropFilesHere: "dropFilesHere", externalDropFilesHere: "externalDropFilesHere", filesBatchStatus: "filesBatchStatus", filesBatchStatusFailed: "filesBatchStatusFailed", filesBatchStatusUploaded: "filesBatchStatusUploaded", fileStatusFailed: "fileStatusFailed", fileStatusUploaded: "fileStatusUploaded", headerStatusPaused: "headerStatusPaused", headerStatusUploaded: "headerStatusUploaded", headerStatusUploading: "headerStatusUploading", invalidFileExtension: "invalidFileExtension", invalidMaxFileSize: "invalidMaxFileSize", invalidMinFileSize: "invalidMinFileSize", pause: "pause", remove: "remove", resume: "resume", retry: "retry", select: "select", uploadSelectedFiles: "uploadSelectedFiles" }, usesInheritance: true, ngImport: i0 });
3127
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: Messages, decorators: [{
3128
- type: Directive
3129
- }], propDecorators: { cancel: [{
3130
- type: Input
3131
- }], clearSelectedFiles: [{
3132
- type: Input
3133
- }], dropFilesHere: [{
3134
- type: Input
3135
- }], externalDropFilesHere: [{
3136
- type: Input
3137
- }], filesBatchStatus: [{
3138
- type: Input
3139
- }], filesBatchStatusFailed: [{
3140
- type: Input
3141
- }], filesBatchStatusUploaded: [{
3142
- type: Input
3143
- }], fileStatusFailed: [{
3144
- type: Input
3145
- }], fileStatusUploaded: [{
3146
- type: Input
3147
- }], headerStatusPaused: [{
3148
- type: Input
3149
- }], headerStatusUploaded: [{
3150
- type: Input
3151
- }], headerStatusUploading: [{
3152
- type: Input
3153
- }], invalidFileExtension: [{
3154
- type: Input
3155
- }], invalidMaxFileSize: [{
3156
- type: Input
3157
- }], invalidMinFileSize: [{
3158
- type: Input
3159
- }], pause: [{
3160
- type: Input
3161
- }], remove: [{
3162
- type: Input
3163
- }], resume: [{
3164
- type: Input
3165
- }], retry: [{
3166
- type: Input
3167
- }], select: [{
3168
- type: Input
3169
- }], uploadSelectedFiles: [{
3170
- type: Input
3171
- }] } });
3172
-
3173
- /**
3174
- * @hidden
3175
- */
3176
- class LocalizedMessagesDirective extends Messages {
3177
- constructor(service) {
3178
- super();
3179
- this.service = service;
3180
- }
3181
- }
3182
- LocalizedMessagesDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LocalizedMessagesDirective, deps: [{ token: i1$1.LocalizationService }], target: i0.ɵɵFactoryTarget.Directive });
3183
- LocalizedMessagesDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: LocalizedMessagesDirective, isStandalone: true, selector: "\n [kendoUploadLocalizedMessages],\n [kendoFileSelectLocalizedMessages],\n [kendoUploadDropZoneLocalizedMessages]\n ", providers: [
3184
- {
3185
- provide: Messages,
3186
- useExisting: forwardRef(() => LocalizedMessagesDirective)
3187
- }
3188
- ], usesInheritance: true, ngImport: i0 });
3189
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: LocalizedMessagesDirective, decorators: [{
3190
- type: Directive,
3191
- args: [{
3192
- providers: [
3193
- {
3194
- provide: Messages,
3195
- useExisting: forwardRef(() => LocalizedMessagesDirective)
3196
- }
3197
- ],
3198
- selector: `
3199
- [kendoUploadLocalizedMessages],
3200
- [kendoFileSelectLocalizedMessages],
3201
- [kendoUploadDropZoneLocalizedMessages]
3202
- `,
3203
- standalone: true
3204
- }]
3205
- }], ctorParameters: function () { return [{ type: i1$1.LocalizationService }]; } });
3206
-
3207
- /**
3208
- * @hidden
3209
- */
3210
- const UPLOAD_VALUE_ACCESSOR = {
3211
- multi: true,
3212
- provide: NG_VALUE_ACCESSOR,
3213
- useExisting: forwardRef(() => UploadComponent)
3214
- };
3215
- let idx$1 = 0;
3216
- /**
3217
- * Represents the [Kendo UI Upload component for Angular]({% slug overview_upload %}).
3218
- */
3219
- class UploadComponent extends UploadFileSelectBase {
3220
- constructor(uploadService, localization, navigation, dropZoneService, zone, renderer, cdr, wrapper, injector) {
3221
- super(uploadService, navigation, cdr, injector, zone);
3222
- this.uploadService = uploadService;
3223
- this.localization = localization;
3224
- this.navigation = navigation;
3225
- this.dropZoneService = dropZoneService;
3226
- this.zone = zone;
3227
- this.renderer = renderer;
3228
- this.cdr = cdr;
3229
- this.injector = injector;
3230
- /**
3231
- * Enables the chunk functionality of the Upload.
3232
- *
3233
- * @default false
3234
- */
3235
- this.chunkable = false;
3236
- /**
3237
- * Toggles the visibility of the file list.
3238
- * @default true
3239
- */
3240
- this.showFileList = true;
3241
- /**
3242
- * Specifies the possible layout of the action buttons.
3243
- */
3244
- this.actionsLayout = 'end';
3245
- /**
3246
- * Fires when the upload is canceled while in progress.
3247
- */
3248
- this.cancel = new EventEmitter();
3249
- /**
3250
- * Fires when the file list is about to be cleared. If prevented, the files will not be cleared.
3251
- */
3252
- this.clear = new EventEmitter();
3253
- /**
3254
- * Fires when all active uploads are completed either successfully or with errors.
3255
- */
3256
- this.complete = new EventEmitter();
3257
- /**
3258
- * Fires when an `upload` or `remove` operation has failed.
3259
- */
3260
- this.error = new EventEmitter();
3261
- /**
3262
- * Fires when the upload of a file has been paused.
3263
- */
3264
- this.pause = new EventEmitter();
3265
- /**
3266
- * Fires when the upload of a file has been resumed.
3267
- */
3268
- this.resume = new EventEmitter();
3269
- /**
3270
- * Fires when an `upload` or `remove` operation is successfully completed.
3271
- */
3272
- this.success = new EventEmitter();
3273
- /**
3274
- * Fires when one or more files are about to be uploaded. If prevented, the files will neither be uploaded, nor added to the file list.
3275
- */
3276
- this.upload = new EventEmitter();
3277
- /**
3278
- * Fires when one or more files are being uploaded.
3279
- */
3280
- this.uploadProgress = new EventEmitter();
3281
- /**
3282
- * Fires when the value of the component has changed as a result of a successful `upload`, `remove` or `clear` operation.
3283
- */
3284
- this.valueChange = new EventEmitter();
3285
- validatePackage(packageMetadata);
3286
- this.fileList = this.uploadService.files;
3287
- this.localizationChangeSubscription = localization.changes.subscribe(({ rtl }) => {
3288
- this.direction = rtl ? 'rtl' : 'ltr';
3289
- });
3290
- this.direction = localization.rtl ? 'rtl' : 'ltr';
3291
- this.navigation.computeKeys();
3292
- this.wrapper = wrapper.nativeElement;
3293
- this.subscribeBlur();
3294
- this.subscribeFocus();
3295
- this.attachEventHandlers();
3296
- }
3297
- /**
3298
- * By default, the selected files are immediately uploaded
3299
- * ([see example]({% slug fileprocessing_upload %}#toc-automatic-upload-of-files)).
3300
- * To change this behavior, set `autoUpload` to `false`.
3301
- */
3302
- set autoUpload(autoUpload) {
3303
- this.uploadService.async.autoUpload = autoUpload;
3304
- }
3305
- get autoUpload() {
3306
- return this.uploadService.async.autoUpload;
3307
- }
3308
- /**
3309
- * When enabled, all files in the selection are uploaded in one request
3310
- * ([see example]({% slug fileprocessing_upload %}#toc-upload-of-batches-of-files)).
3311
- * Any files that are selected one after the other are uploaded in separate requests.
3312
- */
3313
- set batch(batch) {
3314
- this.uploadService.async.batch = batch;
3315
- }
3316
- get batch() {
3317
- return this.uploadService.async.batch;
3318
- }
3319
- /**
3320
- * Configures whether credentials (cookies, headers) will be sent for cross-site requests
3321
- * ([see example]({% slug credentials_upload %}#toc-attaching-credentials-to-requests)).
3322
- * The default values is `true`. Setting `withCredentials` has no effect on same-site requests.
3323
- * To add credentials to the request, use the `saveHeaders` or `removeHeaders` property,
3324
- * or the [`upload`]({% slug api_upload_uploadevent %}) event.
3325
- */
3326
- set withCredentials(withCredentials) {
3327
- this.uploadService.async.withCredentials = withCredentials;
3328
- }
3329
- get withCredentials() {
3330
- return this.uploadService.async.withCredentials;
3331
- }
3332
- /**
3333
- * Sets the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) key which contains the files submitted to `saveUrl`.
3334
- * The default value is `files`.
3335
- */
3336
- set saveField(saveField) {
3337
- this.uploadService.async.saveField = saveField;
3338
- }
3339
- get saveField() {
3340
- return this.uploadService.async.saveField;
3341
- }
3342
- /**
3343
- * Configures the [`HttpHeaders`](https://angular.io/api/common/http/HttpHeaders)
3344
- * that are attached to each upload request.
3345
- */
3346
- set saveHeaders(saveHeaders) {
3347
- this.uploadService.async.saveHeaders = saveHeaders;
3348
- }
3349
- get saveHeaders() {
3350
- return this.uploadService.async.saveHeaders;
3351
- }
3352
- /**
3353
- * Sets the [`RequestMethod`](https://angular.io/api/http/RequestMethod) of the upload request.
3354
- * The default value is `POST`.
3355
- */
3356
- set saveMethod(saveMethod) {
3357
- this.uploadService.async.saveMethod = saveMethod;
3358
- }
3359
- get saveMethod() {
3360
- return this.uploadService.async.saveMethod;
3361
- }
3362
- /**
3363
- * Sets the URL of the endpoint for the upload request.
3364
- * The request [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) key is named after the `saveField` property.
3365
- * It contains the list of files to be uploaded.
3366
- */
3367
- set saveUrl(saveUrl) {
3368
- this.uploadService.async.saveUrl = saveUrl;
3369
- }
3370
- get saveUrl() {
3371
- return this.uploadService.async.saveUrl;
3372
- }
3373
- /**
3374
- * Sets the expected [`response type`](https://angular.io/api/common/http/HttpRequest#responseType) of the server.
3375
- * It is used to parse the response appropriately.
3376
- * @default 'json'
3377
- */
3378
- set responseType(responseType) {
3379
- this.uploadService.async.responseType = responseType;
3380
- }
3381
- get responseType() {
3382
- return this.uploadService.async.responseType;
3383
- }
3384
- /**
3385
- * Sets the [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) key
3386
- * which contains the list of file names that are submitted to `removeUrl`.
3387
- * The default value is `fileNames`.
3388
- */
3389
- set removeField(removeField) { this.uploadService.async.removeField = removeField; }
3390
- get removeField() { return this.uploadService.async.removeField; }
3391
- /**
3392
- * Configures the [`HttpHeaders`](https://angular.io/api/common/http/HttpHeaders)
3393
- * that are attached to each `remove` request.
3394
- */
3395
- set removeHeaders(removeHeaders) {
3396
- this.uploadService.async.removeHeaders = removeHeaders;
3397
- }
3398
- get removeHeaders() {
3399
- return this.uploadService.async.removeHeaders;
3400
- }
3401
- /**
3402
- * Sets the [`RequestMethod`](https://angular.io/api/http/RequestMethod) of the `remove` request.
3403
- * The default value is `POST`.
3404
- */
3405
- set removeMethod(removeMethod) {
3406
- this.uploadService.async.removeMethod = removeMethod;
3407
- }
3408
- get removeMethod() {
3409
- return this.uploadService.async.removeMethod;
3410
- }
3411
- /**
3412
- * Sets the URL of the endpoint for the `remove` request.
3413
- * The [`FormData`](https://developer.mozilla.org/en-US/docs/Web/API/FormData) request key is named after the `removeField` property.
3414
- * It contains the list of file names which will be removed.
3415
- */
3416
- set removeUrl(removeUrl) {
3417
- this.uploadService.async.removeUrl = removeUrl;
3418
- }
3419
- get removeUrl() {
3420
- return this.uploadService.async.removeUrl;
3421
- }
3422
- /**
3423
- * Specifies if the selected files are uploaded simultaneously or one by one.
3424
- *
3425
- * @default true
3426
- */
3427
- set concurrent(concurrent) {
3428
- this.uploadService.async.concurrent = concurrent;
3429
- }
3430
- get concurrent() {
3431
- return this.uploadService.async.concurrent;
3432
- }
3433
- /**
3434
- * @hidden
3435
- */
3436
- set tabIndex(tabIndex) {
3437
- this.tabindex = tabIndex;
3438
- }
3439
- get tabIndex() {
3440
- return this.tabindex;
3441
- }
3442
- get dir() {
3443
- return this.direction;
3444
- }
3445
- ngOnInit() {
3446
- this.verifySettings();
3447
- const { buttonId, fileListId } = this.getIds();
3448
- this.focusableId = buttonId;
3449
- this.fileListId = fileListId;
3450
- this.uploadService.setChunkSettings(this.chunkable);
3451
- if (this.zoneId) {
3452
- this.dropZoneService.addComponent(this, this.zoneId);
3453
- }
3454
- this.zone.runOutsideAngular(() => {
3455
- this.subs.add(this.renderer.listen(this.wrapper, 'keydown', event => this.handleKeydown(event)));
3456
- });
3457
- }
3458
- ngOnChanges(changes) {
3459
- if (isChanged("chunkable", changes)) {
3460
- const newChunkable = changes.chunkable.currentValue;
3461
- if (typeof newChunkable === 'boolean') {
3462
- this.uploadService.async.chunk = newChunkable;
3463
- }
3464
- if (typeof newChunkable === "object" && newChunkable !== null) {
3465
- this.uploadService.async.chunk = true;
3466
- this.uploadService.chunk = Object.assign({}, this.uploadService.chunk, newChunkable);
3467
- }
3468
- }
3469
- }
3470
- ngOnDestroy() {
3471
- this.fileList.clear();
3472
- if (this.zoneId) {
3473
- this.dropZoneService.clearComponent(this, this.zoneId);
3474
- }
3475
- if (this.blurSubscription) {
3476
- this.blurSubscription.unsubscribe();
3477
- }
3478
- if (this.wrapperFocusSubscription) {
3479
- this.wrapperFocusSubscription.unsubscribe();
3480
- }
3481
- if (this.selectButtonFocusSubscription) {
3482
- this.selectButtonFocusSubscription.unsubscribe();
3483
- }
3484
- if (this.localizationChangeSubscription) {
3485
- this.localizationChangeSubscription.unsubscribe();
3486
- }
3487
- if (this.subs) {
3488
- this.subs.unsubscribe();
3489
- }
3490
- }
3491
- /**
3492
- * @hidden
3493
- */
3494
- writeValue(newValue) {
3495
- super.writeValue(newValue, validateInitialFileInfo, 'addInitialFiles');
3496
- }
3497
- /**
3498
- * @hidden
3499
- */
3500
- get showActionButtons() {
3501
- let areVisible = false;
3502
- if (!this.autoUpload) {
3503
- const hasFilesToUpload = this.fileList.filesToUpload.length > 0;
3504
- const uploadingFiles = this.fileList.hasFileWithState([FileState.Uploading]);
3505
- if (this.concurrent && hasFilesToUpload) {
3506
- areVisible = true;
3507
- }
3508
- if (!this.concurrent && hasFilesToUpload && !uploadingFiles) {
3509
- areVisible = true;
3510
- }
3511
- }
3512
- this.navigation.actionButtonsVisible = areVisible;
3513
- return areVisible;
3514
- }
3515
- /**
3516
- * @hidden
3517
- */
3518
- get showTotalStatus() {
3519
- const states = [
3520
- FileState.Uploaded,
3521
- FileState.Uploading,
3522
- FileState.Failed,
3523
- FileState.Paused
3524
- ];
3525
- if (this.fileList.hasFileWithState(states)) {
3526
- return true;
3527
- }
3528
- return false;
3529
- }
3530
- /**
3531
- * @hidden
3532
- */
3533
- textFor(key) {
3534
- return this.localization.get(key);
3535
- }
3536
- /**
3537
- * @hidden
3538
- */
3539
- getIds() {
3540
- const id = ++idx$1;
3541
- const buttonId = `k-upload-button-${id}`;
3542
- const fileListId = `k-upload-file-list-${id}`;
3543
- return { buttonId, fileListId };
3544
- }
3545
- /**
3546
- * Pauses the upload process of a file that is currently uploading.
3547
- * The `pauseFileByUid` method requires the `chunkable` option of the Upload to be enabled.
3548
- *
3549
- * @param uid - The `uid` of the file that will be paused.
3550
- */
3551
- pauseFileByUid(uid) {
3552
- this.uploadService.pauseFile(uid);
3553
- }
3554
- /**
3555
- * Resumes the upload process for a file that has been previously paused.
3556
- * The `resumeFileByUid` method requires the `chunkable` option of the Upload to be enabled.
3557
- *
3558
- * @param uid - The `uid` of the file that will be resumed.
3559
- */
3560
- resumeFileByUid(uid) {
3561
- this.uploadService.resumeFile(uid);
3562
- }
3563
- /**
3564
- * Triggers the removal of a file or a batch of files.
3565
- * @param uid - The `uid` of the file or a batch of files that will be removed.
3566
- */
3567
- removeFilesByUid(uid) {
3568
- this.uploadService.removeFiles(uid);
3569
- }
3570
- /**
3571
- * Triggers another upload attempt of an unsuccessfully uploaded file or a batch of files.
3572
- * @param uid - The `uid` of the file or a batch of files to be retried.
3573
- */
3574
- retryUploadByUid(uid) {
3575
- this.uploadService.retryFiles(uid);
3576
- }
3577
- /**
3578
- * Cancels the upload of a file or a batch of files.
3579
- * @param uid - The `uid` of the file or a batch of files that will be canceled.
3580
- */
3581
- cancelUploadByUid(uid) {
3582
- this.uploadService.cancelFiles(uid);
3583
- }
3584
- /**
3585
- * Uploads the currently selected files which pass the set restrictions.
3586
- */
3587
- uploadFiles() {
3588
- if (this.fileList.filesToUpload.length) {
3589
- this.uploadService.uploadFiles();
3590
- }
3591
- }
3592
- /**
3593
- * Visually clears all files from the UI without issuing requests to the remove handler.
3594
- */
3595
- clearFiles() {
3596
- this.uploadService.clearFiles();
3597
- }
3598
- /**
3599
- * @hidden
3600
- * Used by the external dropzone to add files to the Upload
3601
- */
3602
- addFiles(files) {
3603
- this.uploadService.addFiles(files);
3604
- }
3605
- /**
3606
- * @hidden
3607
- * Used to determine if the component is empty.
3608
- */
3609
- isEmpty() {
3610
- return false;
3611
- }
3612
- verifySettings() {
3613
- if (isDevMode()) {
3614
- if (this.batch && this.chunkable !== false) {
3615
- throw new Error('The file chunking functionality requires the batch setting to be disabled.');
3616
- }
3617
- }
3618
- }
3619
- subscribeBlur() {
3620
- if (!isDocumentAvailable()) {
3621
- return;
3622
- }
3623
- this.zone.runOutsideAngular(() => {
3624
- this.documentClick = fromEvent(document, 'click').pipe(filter((event) => {
3625
- return !(this.wrapper !== event.target && this.wrapper.contains(event.target));
3626
- }));
3627
- this.blurSubscription = merge(this.documentClick, this.navigation.onTabOut).subscribe(() => {
3628
- if (this.navigation.focused) {
3629
- this.zone.run(() => {
3630
- this.navigation.focused = false;
3631
- this.onTouchedCallback();
3632
- this.onBlur.emit();
3633
- });
3634
- }
3635
- });
3636
- });
3637
- }
3638
- handleKeydown(event) {
3639
- if (this.disabled) {
3640
- return;
3641
- }
3642
- if (event.target === this.fileSelectButton.nativeElement && (event.keyCode === Keys.Enter || event.keyCode === Keys.Space)) {
3643
- event.preventDefault();
3644
- this.fileSelectInput.nativeElement.click();
3645
- return;
3646
- }
3647
- if (hasClasses(event.target, UPLOAD_CLASSES) ||
3648
- (!isFocusable(event.target) && !hasClasses(event.target, IGNORE_TARGET_CLASSES))) {
3649
- this.navigation.process(event);
3650
- }
3651
- }
3652
- subscribeFocus() {
3653
- this.wrapperFocusSubscription = this.navigation.onWrapperFocus.subscribe(() => {
3654
- this.onFocus.emit();
3655
- });
3656
- this.selectButtonFocusSubscription = this.navigation.onSelectButtonFocus.subscribe(() => {
3657
- this.fileSelectButton.nativeElement.focus();
3658
- });
3659
- }
3660
- attachEventHandlers() {
3661
- this.subs = this.uploadService.cancelEvent.subscribe((args) => {
3662
- this.cancel.emit(args);
3663
- });
3664
- this.subs.add(this.uploadService.changeEvent.subscribe((files) => {
3665
- this.onChangeCallback(files);
3666
- this.valueChange.emit(files);
3667
- }));
3668
- this.subs.add(this.uploadService.clearEvent.subscribe((args) => {
3669
- this.clear.emit(args);
3670
- }));
3671
- this.subs.add(this.uploadService.completeEvent.subscribe(() => {
3672
- this.complete.emit();
3673
- }));
3674
- this.subs.add(this.uploadService.errorEvent.subscribe((args) => {
3675
- this.error.emit(args);
3676
- }));
3677
- this.subs.add(this.uploadService.pauseEvent.subscribe((args) => {
3678
- this.pause.emit(args);
3679
- }));
3680
- this.subs.add(this.uploadService.removeEvent.subscribe((args) => {
3681
- this.remove.emit(args);
3682
- }));
3683
- this.subs.add(this.uploadService.resumeEvent.subscribe((args) => {
3684
- this.resume.emit(args);
3685
- }));
3686
- this.subs.add(this.uploadService.selectEvent.subscribe((args) => {
3687
- this.select.emit(args);
3688
- }));
3689
- this.subs.add(this.uploadService.successEvent.subscribe((args) => {
3690
- this.success.emit(args);
3691
- }));
3692
- this.subs.add(this.uploadService.uploadEvent.subscribe((args) => {
3693
- this.upload.emit(args);
3694
- }));
3695
- this.subs.add(this.uploadService.uploadProgressEvent.subscribe((args) => {
3696
- this.uploadProgress.emit(args);
3697
- }));
3698
- }
3699
- }
3700
- UploadComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadComponent, deps: [{ token: UploadService }, { token: i1$1.LocalizationService }, { token: NavigationService }, { token: DropZoneService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
3701
- UploadComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UploadComponent, isStandalone: true, selector: "kendo-upload", inputs: { autoUpload: "autoUpload", batch: "batch", withCredentials: "withCredentials", saveField: "saveField", saveHeaders: "saveHeaders", saveMethod: "saveMethod", saveUrl: "saveUrl", responseType: "responseType", removeField: "removeField", removeHeaders: "removeHeaders", removeMethod: "removeMethod", removeUrl: "removeUrl", chunkable: "chunkable", concurrent: "concurrent", showFileList: "showFileList", tabIndex: "tabIndex", actionsLayout: "actionsLayout" }, outputs: { cancel: "cancel", clear: "clear", complete: "complete", error: "error", pause: "pause", resume: "resume", success: "success", upload: "upload", uploadProgress: "uploadProgress", valueChange: "valueChange" }, host: { properties: { "attr.dir": "this.dir" } }, providers: [
3702
- LocalizationService,
3703
- NavigationService,
3704
- UploadService,
3705
- DropZoneService,
3706
- UPLOAD_VALUE_ACCESSOR,
3707
- {
3708
- provide: L10N_PREFIX,
3709
- useValue: 'kendo.upload'
3710
- },
3711
- {
3712
- provide: KendoInput,
3713
- useExisting: forwardRef(() => UploadComponent)
3714
- }
3715
- ], viewQueries: [{ propertyName: "fileSelectInput", first: true, predicate: ["fileSelectInput"], descendants: true, static: true }], exportAs: ["kendoUpload"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: `
3716
- <ng-container kendoUploadLocalizedMessages
3717
- i18n-cancel="kendo.upload.cancel|The text for the Cancel button"
3718
- cancel="Cancel"
3719
-
3720
- i18n-clearSelectedFiles="kendo.upload.clearSelectedFiles|The text for the Clear button"
3721
- clearSelectedFiles="Clear"
3722
-
3723
- i18n-dropFilesHere="kendo.upload.dropFilesHere|The drop zone hint"
3724
- dropFilesHere="Drop files here to upload"
3725
-
3726
- i18n-filesBatchStatus="kendo.upload.filesBatchStatus|The status message for a batch of files"
3727
- filesBatchStatus="files"
3728
-
3729
- i18n-filesBatchStatusFailed="kendo.upload.filesBatchStatusFailed|The status message for a batch of files after failed upload"
3730
- filesBatchStatusFailed="files failed to upload."
3731
-
3732
- i18n-filesBatchStatusUploaded="kendo.upload.filesBatchStatusUploaded|The status message for a batch of files after successful upload"
3733
- filesBatchStatusUploaded="files successfully uploaded."
3734
-
3735
- i18n-fileStatusFailed="kendo.upload.fileStatusFailed|The file status message after failed upload"
3736
- fileStatusFailed="File failed to upload."
3737
-
3738
- i18n-fileStatusUploaded="kendo.upload.fileStatusUploaded|The file status message after successful upload"
3739
- fileStatusUploaded="File successfully uploaded."
3740
-
3741
- i18n-headerStatusPaused="kendo.upload.headerStatusPaused|The header status message when the file upload is paused"
3742
- headerStatusPaused="Paused"
3743
-
3744
- i18n-headerStatusUploaded="kendo.upload.headerStatusUploaded|The header status message after file upload completion"
3745
- headerStatusUploaded="Done"
3746
-
3747
- i18n-headerStatusUploading="kendo.upload.headerStatusUploading|The header status message during file upload"
3748
- headerStatusUploading="Uploading..."
3749
-
3750
- i18n-invalidFileExtension="kendo.upload.invalidFileExtension|The text for the invalid allowed extensions restriction message"
3751
- invalidFileExtension="File type not allowed."
3752
-
3753
- i18n-invalidMaxFileSize="kendo.upload.invalidMaxFileSize|The text for the invalid max file size restriction message"
3754
- invalidMaxFileSize="File size too large."
3755
-
3756
- i18n-invalidMinFileSize="kendo.upload.invalidMinFileSize|The text for the invalid min file size restriction message"
3757
- invalidMinFileSize="File size too small."
3758
-
3759
- i18n-pause="kendo.upload.pause|The text for the Pause button"
3760
- pause="Pause"
3761
-
3762
- i18n-remove="kendo.upload.remove|The text for the Remove button"
3763
- remove="Remove"
3764
-
3765
- i18n-resume="kendo.upload.resume|The text for the Resume button"
3766
- resume="Resume"
3767
-
3768
- i18n-retry="kendo.upload.retry|The text for the Retry button"
3769
- retry="Retry"
3770
-
3771
- i18n-select="kendo.upload.select|The text for the Select button"
3772
- select="Select files..."
3773
-
3774
- i18n-uploadSelectedFiles="kendo.upload.uploadSelectedFiles|The text for the Upload files button"
3775
- uploadSelectedFiles="Upload"
3776
- >
3777
- </ng-container>
3778
- <div kendoUploadInternalDropZone
3779
- [restrictions]="restrictions"
3780
- [multiple]="multiple"
3781
- [disabled]="disabled"
3782
- >
3783
- <div class="k-upload-button-wrap">
3784
- <button
3785
- kendoButton
3786
- #fileSelectButton
3787
- class="k-upload-button"
3788
- type="button"
3789
- (click)="fileSelectInput.click()"
3790
- (focus)="onFileSelectButtonFocus()"
3791
- [id]="focusableId"
3792
- [attr.aria-label]="textFor('select')"
3793
- [attr.tabindex]="tabindex"
3794
- [attr.aria-expanded]="hasFileList"
3795
- [attr.aria-controls]="hasFileList ? fileListId : undefined"
3796
- >
3797
- {{textFor('select')}}
3798
- </button>
3799
- <input kendoFileSelect #fileSelectInput
3800
- [dir]="direction"
3801
- [accept]="accept"
3802
- [restrictions]="restrictions"
3803
- [multiple]="multiple"
3804
- [disabled]="disabled"
3805
- [required]="isControlRequired" />
3806
- </div>
3807
- <kendo-upload-status-total *ngIf="showTotalStatus"
3808
- class="k-upload-status"
3809
- [fileList]="fileList">
3810
- </kendo-upload-status-total>
3811
- <div class="k-dropzone-hint">{{textFor('dropFilesHere')}}</div>
3812
- </div>
3813
- <ul kendo-upload-file-list *ngIf="hasFileList"
3814
- class="k-upload-files k-reset"
3815
- [disabled]="disabled"
3816
- [fileList]="fileList.files"
3817
- [fileTemplate]="fileTemplate"
3818
- [fileInfoTemplate]="fileInfoTemplate"
3819
- [id]="fileListId">
3820
- </ul>
3821
- <kendo-upload-action-buttons
3822
- *ngIf="showActionButtons"
3823
- [disabled]="disabled"
3824
- [actionsLayout]="actionsLayout">
3825
- </kendo-upload-action-buttons>
3826
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "\n [kendoUploadLocalizedMessages],\n [kendoFileSelectLocalizedMessages],\n [kendoUploadDropZoneLocalizedMessages]\n " }, { kind: "directive", type: DropZoneInternalDirective, selector: "\n [kendoUploadInternalDropZone],\n [kendoFileSelectInternalDropZone]\n ", inputs: ["disabled", "multiple", "restrictions"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: FileSelectDirective, selector: "[kendoFileSelect]", inputs: ["dir", "disabled", "multiple", "restrictions", "accept", "required"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: UploadStatusTotalComponent, selector: "kendo-upload-status-total", inputs: ["fileList"] }, { kind: "component", type: FileListComponent, selector: "[kendo-upload-file-list]", inputs: ["disabled", "fileList", "fileTemplate", "fileInfoTemplate"] }, { kind: "component", type: UploadActionButtonsComponent, selector: "kendo-upload-action-buttons", inputs: ["disabled", "actionsLayout"] }] });
3827
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadComponent, decorators: [{
3828
- type: Component,
3829
- args: [{
3830
- exportAs: 'kendoUpload',
3831
- providers: [
3832
- LocalizationService,
3833
- NavigationService,
3834
- UploadService,
3835
- DropZoneService,
3836
- UPLOAD_VALUE_ACCESSOR,
3837
- {
3838
- provide: L10N_PREFIX,
3839
- useValue: 'kendo.upload'
3840
- },
3841
- {
3842
- provide: KendoInput,
3843
- useExisting: forwardRef(() => UploadComponent)
3844
- }
3845
- ],
3846
- selector: 'kendo-upload',
3847
- template: `
3848
- <ng-container kendoUploadLocalizedMessages
3849
- i18n-cancel="kendo.upload.cancel|The text for the Cancel button"
3850
- cancel="Cancel"
3851
-
3852
- i18n-clearSelectedFiles="kendo.upload.clearSelectedFiles|The text for the Clear button"
3853
- clearSelectedFiles="Clear"
3854
-
3855
- i18n-dropFilesHere="kendo.upload.dropFilesHere|The drop zone hint"
3856
- dropFilesHere="Drop files here to upload"
3857
-
3858
- i18n-filesBatchStatus="kendo.upload.filesBatchStatus|The status message for a batch of files"
3859
- filesBatchStatus="files"
3860
-
3861
- i18n-filesBatchStatusFailed="kendo.upload.filesBatchStatusFailed|The status message for a batch of files after failed upload"
3862
- filesBatchStatusFailed="files failed to upload."
3863
-
3864
- i18n-filesBatchStatusUploaded="kendo.upload.filesBatchStatusUploaded|The status message for a batch of files after successful upload"
3865
- filesBatchStatusUploaded="files successfully uploaded."
3866
-
3867
- i18n-fileStatusFailed="kendo.upload.fileStatusFailed|The file status message after failed upload"
3868
- fileStatusFailed="File failed to upload."
3869
-
3870
- i18n-fileStatusUploaded="kendo.upload.fileStatusUploaded|The file status message after successful upload"
3871
- fileStatusUploaded="File successfully uploaded."
3872
-
3873
- i18n-headerStatusPaused="kendo.upload.headerStatusPaused|The header status message when the file upload is paused"
3874
- headerStatusPaused="Paused"
3875
-
3876
- i18n-headerStatusUploaded="kendo.upload.headerStatusUploaded|The header status message after file upload completion"
3877
- headerStatusUploaded="Done"
3878
-
3879
- i18n-headerStatusUploading="kendo.upload.headerStatusUploading|The header status message during file upload"
3880
- headerStatusUploading="Uploading..."
3881
-
3882
- i18n-invalidFileExtension="kendo.upload.invalidFileExtension|The text for the invalid allowed extensions restriction message"
3883
- invalidFileExtension="File type not allowed."
3884
-
3885
- i18n-invalidMaxFileSize="kendo.upload.invalidMaxFileSize|The text for the invalid max file size restriction message"
3886
- invalidMaxFileSize="File size too large."
3887
-
3888
- i18n-invalidMinFileSize="kendo.upload.invalidMinFileSize|The text for the invalid min file size restriction message"
3889
- invalidMinFileSize="File size too small."
3890
-
3891
- i18n-pause="kendo.upload.pause|The text for the Pause button"
3892
- pause="Pause"
3893
-
3894
- i18n-remove="kendo.upload.remove|The text for the Remove button"
3895
- remove="Remove"
3896
-
3897
- i18n-resume="kendo.upload.resume|The text for the Resume button"
3898
- resume="Resume"
3899
-
3900
- i18n-retry="kendo.upload.retry|The text for the Retry button"
3901
- retry="Retry"
3902
-
3903
- i18n-select="kendo.upload.select|The text for the Select button"
3904
- select="Select files..."
3905
-
3906
- i18n-uploadSelectedFiles="kendo.upload.uploadSelectedFiles|The text for the Upload files button"
3907
- uploadSelectedFiles="Upload"
3908
- >
3909
- </ng-container>
3910
- <div kendoUploadInternalDropZone
3911
- [restrictions]="restrictions"
3912
- [multiple]="multiple"
3913
- [disabled]="disabled"
3914
- >
3915
- <div class="k-upload-button-wrap">
3916
- <button
3917
- kendoButton
3918
- #fileSelectButton
3919
- class="k-upload-button"
3920
- type="button"
3921
- (click)="fileSelectInput.click()"
3922
- (focus)="onFileSelectButtonFocus()"
3923
- [id]="focusableId"
3924
- [attr.aria-label]="textFor('select')"
3925
- [attr.tabindex]="tabindex"
3926
- [attr.aria-expanded]="hasFileList"
3927
- [attr.aria-controls]="hasFileList ? fileListId : undefined"
3928
- >
3929
- {{textFor('select')}}
3930
- </button>
3931
- <input kendoFileSelect #fileSelectInput
3932
- [dir]="direction"
3933
- [accept]="accept"
3934
- [restrictions]="restrictions"
3935
- [multiple]="multiple"
3936
- [disabled]="disabled"
3937
- [required]="isControlRequired" />
3938
- </div>
3939
- <kendo-upload-status-total *ngIf="showTotalStatus"
3940
- class="k-upload-status"
3941
- [fileList]="fileList">
3942
- </kendo-upload-status-total>
3943
- <div class="k-dropzone-hint">{{textFor('dropFilesHere')}}</div>
3944
- </div>
3945
- <ul kendo-upload-file-list *ngIf="hasFileList"
3946
- class="k-upload-files k-reset"
3947
- [disabled]="disabled"
3948
- [fileList]="fileList.files"
3949
- [fileTemplate]="fileTemplate"
3950
- [fileInfoTemplate]="fileInfoTemplate"
3951
- [id]="fileListId">
3952
- </ul>
3953
- <kendo-upload-action-buttons
3954
- *ngIf="showActionButtons"
3955
- [disabled]="disabled"
3956
- [actionsLayout]="actionsLayout">
3957
- </kendo-upload-action-buttons>
3958
- `,
3959
- standalone: true,
3960
- imports: [LocalizedMessagesDirective, DropZoneInternalDirective, ButtonComponent, FileSelectDirective, NgIf, UploadStatusTotalComponent, FileListComponent, UploadActionButtonsComponent]
3961
- }]
3962
- }], ctorParameters: function () { return [{ type: UploadService }, { type: i1$1.LocalizationService }, { type: NavigationService }, { type: DropZoneService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }]; }, propDecorators: { autoUpload: [{
3963
- type: Input
3964
- }], batch: [{
3965
- type: Input
3966
- }], withCredentials: [{
3967
- type: Input
3968
- }], saveField: [{
3969
- type: Input
3970
- }], saveHeaders: [{
3971
- type: Input
3972
- }], saveMethod: [{
3973
- type: Input
3974
- }], saveUrl: [{
3975
- type: Input
3976
- }], responseType: [{
3977
- type: Input
3978
- }], removeField: [{
3979
- type: Input
3980
- }], removeHeaders: [{
3981
- type: Input
3982
- }], removeMethod: [{
3983
- type: Input
3984
- }], removeUrl: [{
3985
- type: Input
3986
- }], chunkable: [{
3987
- type: Input
3988
- }], concurrent: [{
3989
- type: Input
3990
- }], showFileList: [{
3991
- type: Input
3992
- }], tabIndex: [{
3993
- type: Input,
3994
- args: ['tabIndex']
3995
- }], actionsLayout: [{
3996
- type: Input
3997
- }], fileSelectInput: [{
3998
- type: ViewChild,
3999
- args: ['fileSelectInput', { static: true }]
4000
- }], cancel: [{
4001
- type: Output
4002
- }], clear: [{
4003
- type: Output
4004
- }], complete: [{
4005
- type: Output
4006
- }], error: [{
4007
- type: Output
4008
- }], pause: [{
4009
- type: Output
4010
- }], resume: [{
4011
- type: Output
4012
- }], success: [{
4013
- type: Output
4014
- }], upload: [{
4015
- type: Output
4016
- }], uploadProgress: [{
4017
- type: Output
4018
- }], valueChange: [{
4019
- type: Output
4020
- }], dir: [{
4021
- type: HostBinding,
4022
- args: ['attr.dir']
4023
- }] } });
4024
-
4025
- class UploadDropZoneDirective {
4026
- constructor(dropZoneService) {
4027
- this.dropZoneService = dropZoneService;
4028
- }
4029
- /**
4030
- * @hidden
4031
- */
4032
- onElementDragEnter() {
4033
- return false;
4034
- }
4035
- /**
4036
- * @hidden
4037
- */
4038
- onElementDragOver() {
4039
- return false;
4040
- }
4041
- /**
4042
- * @hidden
4043
- */
4044
- onDropListener(event) {
4045
- const components = this.componentInstance;
4046
- if (!isPresent(components)) {
4047
- return;
4048
- }
4049
- components.forEach((component) => {
4050
- const droppedFiles = event.dataTransfer.files;
4051
- if (droppedFiles.length > 0 && !component.disabled) {
4052
- let files = getAllFileInfo(droppedFiles);
4053
- if (component instanceof UploadComponent) {
4054
- files = assignGuidToFiles(files, !component.batch);
4055
- }
4056
- else {
4057
- files = assignGuidToFiles(files, true);
4058
- }
4059
- if (!component.multiple) {
4060
- files.splice(1, files.length - 1);
4061
- component.clearFiles();
4062
- }
4063
- validateFiles(files, component.restrictions);
4064
- component.addFiles(files);
4065
- }
4066
- });
4067
- return false;
4068
- }
4069
- /**
4070
- * @hidden
4071
- */
4072
- get componentInstance() {
4073
- const id = this.zoneId || this.fileSelectZoneId;
4074
- return this.dropZoneService.getComponents(id);
4075
- }
4076
- }
4077
- UploadDropZoneDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadDropZoneDirective, deps: [{ token: DropZoneService }], target: i0.ɵɵFactoryTarget.Directive });
4078
- UploadDropZoneDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: UploadDropZoneDirective, isStandalone: true, selector: "[kendoUploadDropZone], [kendoFileSelectDropZone]", inputs: { zoneId: ["kendoUploadDropZone", "zoneId"], fileSelectZoneId: ["kendoFileSelectDropZone", "fileSelectZoneId"] }, host: { listeners: { "dragenter": "onElementDragEnter()", "dragover": "onElementDragOver()", "drop": "onDropListener($event)" } }, providers: [
4079
- DropZoneService
4080
- ], ngImport: i0 });
4081
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadDropZoneDirective, decorators: [{
4082
- type: Directive,
4083
- args: [{
4084
- providers: [
4085
- DropZoneService
4086
- ],
4087
- selector: '[kendoUploadDropZone], [kendoFileSelectDropZone]',
4088
- standalone: true
4089
- }]
4090
- }], ctorParameters: function () { return [{ type: DropZoneService }]; }, propDecorators: { zoneId: [{
4091
- type: Input,
4092
- args: ['kendoUploadDropZone']
4093
- }], fileSelectZoneId: [{
4094
- type: Input,
4095
- args: ['kendoFileSelectDropZone']
4096
- }], onElementDragEnter: [{
4097
- type: HostListener,
4098
- args: ['dragenter']
4099
- }], onElementDragOver: [{
4100
- type: HostListener,
4101
- args: ['dragover']
4102
- }], onDropListener: [{
4103
- type: HostListener,
4104
- args: ['drop', ['$event']]
4105
- }] } });
4106
-
4107
- /**
4108
- * Represents the [Kendo UI UploadDropZone component for Angular]({% slug overview_upload %}).
4109
- */
4110
- class UploadDropZoneComponent extends DropZoneBase {
4111
- constructor(element, renderer, localization) {
4112
- super(element, renderer, 'k-external-dropzone-hover');
4113
- this.localization = localization;
4114
- this.hostClass = true;
4115
- this._svgIcon = uploadIcon;
4116
- this.localizationChangeSubscription = this.localization.changes.subscribe(({ rtl }) => {
4117
- this.direction = rtl ? 'rtl' : 'ltr';
4118
- });
4119
- }
4120
- get dirAttribute() {
4121
- return this.direction;
4122
- }
4123
- /**
4124
- * Defines an SVGIcon to be rendered inside the DropZone.
4125
- * The input can take either an [existing Kendo SVG icon](slug:svgicon_list) or a custom one.
4126
- */
4127
- set svgIcon(icon) {
4128
- if (isDevMode() && icon && this.icon && this.iconClass) {
4129
- throw new Error('Setting both icon/svgIcon and iconClass options at the same time is not supported.');
4130
- }
4131
- this._svgIcon = icon;
4132
- }
4133
- get svgIcon() {
4134
- return this._svgIcon;
4135
- }
4136
- /**
4137
- * @hidden
4138
- */
4139
- textFor(key) {
4140
- return this.localization.get(key);
4141
- }
4142
- /**
4143
- * @hidden
4144
- */
4145
- get iconClasses() {
4146
- if (this.icon) {
4147
- return `${this.icon}`;
4148
- }
4149
- if (!this.icon && !this.iconClass) {
4150
- return 'upload';
4151
- }
4152
- }
4153
- ngOnDestroy() {
4154
- if (this.localizationChangeSubscription) {
4155
- this.localizationChangeSubscription.unsubscribe();
4156
- }
4157
- }
4158
- }
4159
- UploadDropZoneComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadDropZoneComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1$1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
4160
- UploadDropZoneComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: UploadDropZoneComponent, isStandalone: true, selector: "kendo-uploaddropzone", inputs: { zoneId: "zoneId", icon: "icon", iconClass: "iconClass", svgIcon: "svgIcon" }, host: { properties: { "class.k-external-dropzone": "this.hostClass", "attr.dir": "this.dirAttribute" } }, providers: [
4161
- LocalizationService,
4162
- {
4163
- provide: L10N_PREFIX,
4164
- useValue: 'kendo.uploaddropzone'
4165
- }
4166
- ], exportAs: ["kendoUploadDropZone"], usesInheritance: true, ngImport: i0, template: `
4167
- <ng-container kendoUploadDropZoneLocalizedMessages
4168
- i18n-externalDropFilesHere='kendo.uploaddropzone.externalDropFilesHere|Sets the external drop-zone hint'
4169
- externalDropFilesHere='Drag and drop files here to upload'>
4170
- </ng-container>
4171
- <div class='k-dropzone-inner' [kendoUploadDropZone]="zoneId">
4172
- <kendo-icon-wrapper
4173
- size="xxxlarge"
4174
- innerCssClass="k-dropzone-icon"
4175
- [name]="iconClasses"
4176
- [customFontClass]="iconClass"
4177
- [svgIcon]="svgIcon"
4178
- ></kendo-icon-wrapper>
4179
- <span class="k-dropzone-hint">{{ textFor('externalDropFilesHere') }}</span>
4180
- <span class="k-dropzone-note">
4181
- <ng-content></ng-content>
4182
- </span>
4183
- </div>
4184
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "\n [kendoUploadLocalizedMessages],\n [kendoFileSelectLocalizedMessages],\n [kendoUploadDropZoneLocalizedMessages]\n " }, { kind: "directive", type: UploadDropZoneDirective, selector: "[kendoUploadDropZone], [kendoFileSelectDropZone]", inputs: ["kendoUploadDropZone", "kendoFileSelectDropZone"] }, { kind: "component", type: IconWrapperComponent, selector: "kendo-icon-wrapper", inputs: ["name", "svgIcon", "innerCssClass", "customFontClass", "size"], exportAs: ["kendoIconWrapper"] }] });
4185
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadDropZoneComponent, decorators: [{
4186
- type: Component,
4187
- args: [{
4188
- exportAs: 'kendoUploadDropZone',
4189
- providers: [
4190
- LocalizationService,
4191
- {
4192
- provide: L10N_PREFIX,
4193
- useValue: 'kendo.uploaddropzone'
4194
- }
4195
- ],
4196
- selector: 'kendo-uploaddropzone',
4197
- template: `
4198
- <ng-container kendoUploadDropZoneLocalizedMessages
4199
- i18n-externalDropFilesHere='kendo.uploaddropzone.externalDropFilesHere|Sets the external drop-zone hint'
4200
- externalDropFilesHere='Drag and drop files here to upload'>
4201
- </ng-container>
4202
- <div class='k-dropzone-inner' [kendoUploadDropZone]="zoneId">
4203
- <kendo-icon-wrapper
4204
- size="xxxlarge"
4205
- innerCssClass="k-dropzone-icon"
4206
- [name]="iconClasses"
4207
- [customFontClass]="iconClass"
4208
- [svgIcon]="svgIcon"
4209
- ></kendo-icon-wrapper>
4210
- <span class="k-dropzone-hint">{{ textFor('externalDropFilesHere') }}</span>
4211
- <span class="k-dropzone-note">
4212
- <ng-content></ng-content>
4213
- </span>
4214
- </div>
4215
- `,
4216
- standalone: true,
4217
- imports: [LocalizedMessagesDirective, UploadDropZoneDirective, IconWrapperComponent]
4218
- }]
4219
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1$1.LocalizationService }]; }, propDecorators: { hostClass: [{
4220
- type: HostBinding,
4221
- args: ['class.k-external-dropzone']
4222
- }], dirAttribute: [{
4223
- type: HostBinding,
4224
- args: ['attr.dir']
4225
- }], zoneId: [{
4226
- type: Input
4227
- }], icon: [{
4228
- type: Input
4229
- }], iconClass: [{
4230
- type: Input
4231
- }], svgIcon: [{
4232
- type: Input
4233
- }] } });
4234
-
4235
- /**
4236
- * @hidden
4237
- */
4238
- const FILESELECT_VALUE_ACCESSOR = {
4239
- multi: true,
4240
- provide: NG_VALUE_ACCESSOR,
4241
- useExisting: forwardRef(() => FileSelectComponent)
4242
- };
4243
- let idx = 0;
4244
- class FileSelectComponent extends UploadFileSelectBase {
4245
- constructor(uploadService, localization, navigation, dropZoneService, ngZone, renderer, cdr, wrapper, injector) {
4246
- super(uploadService, navigation, cdr, injector, ngZone);
4247
- this.uploadService = uploadService;
4248
- this.localization = localization;
4249
- this.navigation = navigation;
4250
- this.dropZoneService = dropZoneService;
4251
- this.ngZone = ngZone;
4252
- this.renderer = renderer;
4253
- this.cdr = cdr;
4254
- this.injector = injector;
4255
- /**
4256
- * Fires when the value of the component has changed as a result of a successful `select` or `remove` operation.
4257
- */
4258
- this.valueChange = new EventEmitter();
4259
- /**
4260
- * @hidden
4261
- */
4262
- this._restrictions = {
4263
- allowedExtensions: [],
4264
- maxFileSize: 0,
4265
- minFileSize: 0
4266
- };
4267
- validatePackage(packageMetadata);
4268
- this.wrapper = wrapper.nativeElement;
4269
- this.direction = localization.rtl ? 'rtl' : 'ltr';
4270
- this.navigation.computeKeys();
4271
- this.localizationChangeSubscription = localization.changes.subscribe(({ rtl }) => {
4272
- this.direction = rtl ? 'rtl' : 'ltr';
4273
- });
4274
- this.subscribeBlur();
4275
- this.subscribeFocus();
4276
- this.attachEventHandlers();
4277
- this.setDefaultSettings();
4278
- }
4279
- get dir() {
4280
- return this.direction;
4281
- }
4282
- /**
4283
- * Sets the `name` attribute of the `input` element of the FileSelect.
4284
- */
4285
- set name(name) {
4286
- this.uploadService.async.saveField = name;
4287
- }
4288
- get name() {
4289
- return this.uploadService.async.saveField;
4290
- }
4291
- ngOnInit() {
4292
- const { buttonId, fileListId } = this.getIds();
4293
- this.focusableId = buttonId;
4294
- this.fileListId = fileListId;
4295
- if (this.zoneId) {
4296
- this.dropZoneService.addComponent(this, this.zoneId);
4297
- }
4298
- this.subs.add(this.renderer.listen(this.fileSelectInput.nativeElement, 'mouseenter', () => {
4299
- this.renderer.addClass(this.fileSelectButton.nativeElement, 'k-hover');
4300
- }));
4301
- this.subs.add(this.renderer.listen(this.fileSelectInput.nativeElement, 'mouseleave', () => {
4302
- this.renderer.removeClass(this.fileSelectButton.nativeElement, 'k-hover');
4303
- }));
4304
- this.ngZone.runOutsideAngular(() => {
4305
- this.subs.add(this.renderer.listen(this.wrapper, 'keydown', event => this.handleKeydown(event)));
4306
- });
4307
- }
4308
- /**
4309
- * @hidden
4310
- */
4311
- textFor(key) {
4312
- return this.localization.get(key);
4313
- }
4314
- ngOnDestroy() {
4315
- this.fileList.clear();
4316
- if (this.blurSubscription) {
4317
- this.blurSubscription.unsubscribe();
4318
- }
4319
- if (this.wrapperFocusSubscription) {
4320
- this.wrapperFocusSubscription.unsubscribe();
4321
- }
4322
- if (this.selectButtonFocusSubscription) {
4323
- this.selectButtonFocusSubscription.unsubscribe();
4324
- }
4325
- if (this.localizationChangeSubscription) {
4326
- this.localizationChangeSubscription.unsubscribe();
4327
- }
4328
- if (this.subs) {
4329
- this.subs.unsubscribe();
4330
- }
4331
- }
4332
- /**
4333
- * Removes specific file from the file list.
4334
- */
4335
- removeFileByUid(uid) {
4336
- this.uploadService.removeFiles(uid);
4337
- }
4338
- /**
4339
- * Visually clears all files from the UI.
4340
- */
4341
- clearFiles() {
4342
- this.uploadService.clearFiles();
4343
- }
4344
- /**
4345
- * @hidden
4346
- * Used to determine if the component is empty.
4347
- */
4348
- isEmpty() {
4349
- return false;
4350
- }
4351
- /**
4352
- * @hidden
4353
- * Used by the external dropzone to add files to the FileSelect
4354
- */
4355
- addFiles(files) {
4356
- this.uploadService.addFiles(files);
4357
- }
4358
- /**
4359
- * @hidden
4360
- */
4361
- get selectButtonTabIndex() {
4362
- return this.disabled ? undefined : this.tabindex;
4363
- }
4364
- /**
4365
- * @hidden
4366
- */
4367
- getIds() {
4368
- const id = ++idx;
4369
- const buttonId = `k-fileselect-button-${id}`;
4370
- const fileListId = `k-fileselect-file-list-${id}`;
4371
- return { buttonId, fileListId };
4372
- }
4373
- /**
4374
- * @hidden
4375
- */
4376
- writeValue(newValue) {
4377
- super.writeValue(newValue, validateInitialFileSelectFile, 'addInitialFileSelectFiles');
4378
- }
4379
- subscribeBlur() {
4380
- if (!isDocumentAvailable()) {
4381
- return;
4382
- }
4383
- this.ngZone.runOutsideAngular(() => {
4384
- this.documentClick = fromEvent(document, 'click').pipe(filter((event) => {
4385
- return !(this.wrapper !== event.target && this.wrapper.contains(event.target));
4386
- }));
4387
- this.blurSubscription = merge(this.documentClick, this.navigation.onTabOut).subscribe(() => {
4388
- if (this.navigation.focused) {
4389
- this.ngZone.run(() => {
4390
- this.navigation.focused = false;
4391
- this.onTouchedCallback();
4392
- this.onBlur.emit();
4393
- });
4394
- }
4395
- });
4396
- });
4397
- }
4398
- subscribeFocus() {
4399
- this.wrapperFocusSubscription = this.navigation.onWrapperFocus.subscribe(() => {
4400
- this.onFocus.emit();
4401
- });
4402
- this.selectButtonFocusSubscription = this.navigation.onSelectButtonFocus.subscribe(() => {
4403
- this.fileSelectButton.nativeElement.focus();
4404
- });
4405
- }
4406
- handleKeydown(event) {
4407
- if (this.disabled) {
4408
- return;
4409
- }
4410
- if (event.target === this.fileSelectButton.nativeElement && (event.keyCode === Keys.Enter || event.keyCode === Keys.Space)) {
4411
- event.preventDefault();
4412
- this.fileSelectInput.nativeElement.click();
4413
- return;
4414
- }
4415
- if (hasClasses(event.target, UPLOAD_CLASSES) ||
4416
- (!isFocusable(event.target) && !hasClasses(event.target, IGNORE_TARGET_CLASSES))) {
4417
- this.navigation.process(event, 'fileselect');
4418
- }
4419
- }
4420
- attachEventHandlers() {
4421
- this.subs = this.uploadService.changeEvent.subscribe((files) => {
4422
- let model = [];
4423
- if (files !== null) {
4424
- files.forEach((file) => {
4425
- if (file.state === FileState.Initial) {
4426
- model.push(file);
4427
- }
4428
- if (file.state === FileState.Selected && file.rawFile && !file.validationErrors) {
4429
- model.push(file.rawFile);
4430
- }
4431
- });
4432
- }
4433
- if (model.length === 0) {
4434
- model = null;
4435
- }
4436
- this.onChangeCallback(model);
4437
- this.valueChange.emit(model);
4438
- });
4439
- this.subs.add(this.uploadService.removeEvent.subscribe((args) => {
4440
- this.remove.emit(args);
4441
- }));
4442
- this.subs.add(this.uploadService.selectEvent.subscribe((args) => {
4443
- this.select.emit(args);
4444
- }));
4445
- }
4446
- setDefaultSettings() {
4447
- this.uploadService.async.autoUpload = false;
4448
- this.uploadService.component = 'FileSelect';
4449
- }
4450
- }
4451
- FileSelectComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectComponent, deps: [{ token: UploadService }, { token: i1$1.LocalizationService }, { token: NavigationService }, { token: DropZoneService }, { token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
4452
- FileSelectComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: FileSelectComponent, isStandalone: true, selector: "kendo-fileselect", inputs: { name: "name" }, outputs: { valueChange: "valueChange" }, host: { properties: { "attr.dir": "this.dir" } }, providers: [
4453
- LocalizationService,
4454
- NavigationService,
4455
- UploadService,
4456
- DropZoneService,
4457
- FILESELECT_VALUE_ACCESSOR,
4458
- {
4459
- provide: L10N_PREFIX,
4460
- useValue: 'kendo.fileselect'
4461
- },
4462
- {
4463
- provide: KendoInput,
4464
- useExisting: forwardRef(() => FileSelectComponent)
4465
- }
4466
- ], viewQueries: [{ propertyName: "fileSelectInput", first: true, predicate: ["fileSelectInput"], descendants: true, static: true }], exportAs: ["kendoFileSelect"], usesInheritance: true, ngImport: i0, template: `
4467
- <ng-container kendoFileSelectLocalizedMessages
4468
- i18n-dropFilesHere="kendo.fileselect.dropFilesHere|The drop zone hint"
4469
- dropFilesHere="Drop files here to select"
4470
-
4471
- i18n-invalidFileExtension="kendo.fileselect.invalidFileExtension|The text for the invalid allowed extensions restriction message"
4472
- invalidFileExtension="File type not allowed."
4473
-
4474
- i18n-invalidMaxFileSize="kendo.fileselect.invalidMaxFileSize|The text for the invalid max file size restriction message"
4475
- invalidMaxFileSize="File size too large."
4476
-
4477
- i18n-invalidMinFileSize="kendo.fileselect.invalidMinFileSize|The text for the invalid min file size restriction message"
4478
- invalidMinFileSize="File size too small."
4479
-
4480
- i18n-remove="kendo.fileselect.remove|The text for the Remove button"
4481
- remove="Remove"
4482
-
4483
- i18n-select="kendo.fileselect.select|The text for the Select button"
4484
- select="Select files..."
4485
- >
4486
- </ng-container>
4487
- <div kendoFileSelectInternalDropZone
4488
- [restrictions]="restrictions"
4489
- [multiple]="multiple"
4490
- [disabled]="disabled">
4491
- <div class="k-upload-button-wrap">
4492
- <button
4493
- kendoButton
4494
- #fileSelectButton
4495
- class="k-upload-button"
4496
- type="button"
4497
- role="button"
4498
- (click)="fileSelectInput.click()"
4499
- (focus)="onFileSelectButtonFocus()"
4500
- [id]="focusableId"
4501
- [attr.aria-label]="textFor('select')"
4502
- [attr.tabindex]="tabindex"
4503
- [attr.aria-expanded]="hasFileList"
4504
- [attr.aria-controls]="hasFileList ? fileListId : undefined"
4505
- >
4506
- {{textFor('select')}}
4507
- </button>
4508
- <input kendoFileSelect #fileSelectInput
4509
- [dir]="direction"
4510
- [accept]="accept"
4511
- [restrictions]="restrictions"
4512
- [multiple]="multiple"
4513
- [disabled]="disabled"
4514
- [required]="isControlRequired"
4515
- />
4516
- </div>
4517
- <div class="k-dropzone-hint">{{textFor('dropFilesHere')}}</div>
4518
- </div>
4519
- <ul kendo-upload-file-list
4520
- class="k-upload-files k-reset"
4521
- *ngIf="hasFileList"
4522
- [disabled]="disabled"
4523
- [fileList]="fileList.files"
4524
- [fileTemplate]="fileTemplate"
4525
- [fileInfoTemplate]="fileInfoTemplate"
4526
- [id]="fileListId">
4527
- </ul>
4528
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "\n [kendoUploadLocalizedMessages],\n [kendoFileSelectLocalizedMessages],\n [kendoUploadDropZoneLocalizedMessages]\n " }, { kind: "directive", type: DropZoneInternalDirective, selector: "\n [kendoUploadInternalDropZone],\n [kendoFileSelectInternalDropZone]\n ", inputs: ["disabled", "multiple", "restrictions"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: FileSelectDirective, selector: "[kendoFileSelect]", inputs: ["dir", "disabled", "multiple", "restrictions", "accept", "required"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: FileListComponent, selector: "[kendo-upload-file-list]", inputs: ["disabled", "fileList", "fileTemplate", "fileInfoTemplate"] }] });
4529
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectComponent, decorators: [{
4530
- type: Component,
4531
- args: [{
4532
- exportAs: 'kendoFileSelect',
4533
- providers: [
4534
- LocalizationService,
4535
- NavigationService,
4536
- UploadService,
4537
- DropZoneService,
4538
- FILESELECT_VALUE_ACCESSOR,
4539
- {
4540
- provide: L10N_PREFIX,
4541
- useValue: 'kendo.fileselect'
4542
- },
4543
- {
4544
- provide: KendoInput,
4545
- useExisting: forwardRef(() => FileSelectComponent)
4546
- }
4547
- ],
4548
- selector: 'kendo-fileselect',
4549
- template: `
4550
- <ng-container kendoFileSelectLocalizedMessages
4551
- i18n-dropFilesHere="kendo.fileselect.dropFilesHere|The drop zone hint"
4552
- dropFilesHere="Drop files here to select"
4553
-
4554
- i18n-invalidFileExtension="kendo.fileselect.invalidFileExtension|The text for the invalid allowed extensions restriction message"
4555
- invalidFileExtension="File type not allowed."
4556
-
4557
- i18n-invalidMaxFileSize="kendo.fileselect.invalidMaxFileSize|The text for the invalid max file size restriction message"
4558
- invalidMaxFileSize="File size too large."
4559
-
4560
- i18n-invalidMinFileSize="kendo.fileselect.invalidMinFileSize|The text for the invalid min file size restriction message"
4561
- invalidMinFileSize="File size too small."
4562
-
4563
- i18n-remove="kendo.fileselect.remove|The text for the Remove button"
4564
- remove="Remove"
4565
-
4566
- i18n-select="kendo.fileselect.select|The text for the Select button"
4567
- select="Select files..."
4568
- >
4569
- </ng-container>
4570
- <div kendoFileSelectInternalDropZone
4571
- [restrictions]="restrictions"
4572
- [multiple]="multiple"
4573
- [disabled]="disabled">
4574
- <div class="k-upload-button-wrap">
4575
- <button
4576
- kendoButton
4577
- #fileSelectButton
4578
- class="k-upload-button"
4579
- type="button"
4580
- role="button"
4581
- (click)="fileSelectInput.click()"
4582
- (focus)="onFileSelectButtonFocus()"
4583
- [id]="focusableId"
4584
- [attr.aria-label]="textFor('select')"
4585
- [attr.tabindex]="tabindex"
4586
- [attr.aria-expanded]="hasFileList"
4587
- [attr.aria-controls]="hasFileList ? fileListId : undefined"
4588
- >
4589
- {{textFor('select')}}
4590
- </button>
4591
- <input kendoFileSelect #fileSelectInput
4592
- [dir]="direction"
4593
- [accept]="accept"
4594
- [restrictions]="restrictions"
4595
- [multiple]="multiple"
4596
- [disabled]="disabled"
4597
- [required]="isControlRequired"
4598
- />
4599
- </div>
4600
- <div class="k-dropzone-hint">{{textFor('dropFilesHere')}}</div>
4601
- </div>
4602
- <ul kendo-upload-file-list
4603
- class="k-upload-files k-reset"
4604
- *ngIf="hasFileList"
4605
- [disabled]="disabled"
4606
- [fileList]="fileList.files"
4607
- [fileTemplate]="fileTemplate"
4608
- [fileInfoTemplate]="fileInfoTemplate"
4609
- [id]="fileListId">
4610
- </ul>
4611
- `,
4612
- standalone: true,
4613
- imports: [LocalizedMessagesDirective, DropZoneInternalDirective, ButtonComponent, FileSelectDirective, NgIf, FileListComponent]
4614
- }]
4615
- }], ctorParameters: function () { return [{ type: UploadService }, { type: i1$1.LocalizationService }, { type: NavigationService }, { type: DropZoneService }, { type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i0.Injector }]; }, propDecorators: { fileSelectInput: [{
4616
- type: ViewChild,
4617
- args: ['fileSelectInput', { static: true }]
4618
- }], dir: [{
4619
- type: HostBinding,
4620
- args: ['attr.dir']
4621
- }], name: [{
4622
- type: Input
4623
- }], valueChange: [{
4624
- type: Output
4625
- }] } });
4626
-
4627
- /**
4628
- * Custom component messages override default component messages ([more information and example]({% slug globalization_upload %})).
4629
- *
4630
- * @example
4631
- * ```html-no-run
4632
- * <kendo-fileselect>
4633
- * <kendo-fileselect-messages
4634
- * dropFilesHere="Drop your file here"
4635
- * select="Upload file">
4636
- * </kendo-fileselect-messages>
4637
- * </kendo-fileselect>
4638
- * ```
4639
- */
4640
- class CustomMessagesComponent extends Messages {
4641
- constructor(service) {
4642
- super();
4643
- this.service = service;
4644
- }
4645
- get override() {
4646
- return true;
4647
- }
4648
- }
4649
- CustomMessagesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomMessagesComponent, deps: [{ token: i1$1.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
4650
- CustomMessagesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: CustomMessagesComponent, isStandalone: true, selector: "kendo-upload-messages, kendo-fileselect-messages, kendo-uploaddropzone-messages", providers: [
4651
- {
4652
- provide: Messages,
4653
- useExisting: forwardRef(() => CustomMessagesComponent)
4654
- }
4655
- ], usesInheritance: true, ngImport: i0, template: ``, isInline: true });
4656
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CustomMessagesComponent, decorators: [{
4657
- type: Component,
4658
- args: [{
4659
- providers: [
4660
- {
4661
- provide: Messages,
4662
- useExisting: forwardRef(() => CustomMessagesComponent)
4663
- }
4664
- ],
4665
- selector: 'kendo-upload-messages, kendo-fileselect-messages, kendo-uploaddropzone-messages',
4666
- template: ``,
4667
- standalone: true
4668
- }]
4669
- }], ctorParameters: function () { return [{ type: i1$1.LocalizationService }]; } });
4670
-
4671
- /**
4672
- * Utility array that contains all `FileSelect` related components and directives
4673
- */
4674
- const KENDO_FILESELECT = [
4675
- FileSelectComponent,
4676
- FileTemplateDirective,
4677
- FileInfoTemplateDirective,
4678
- CustomMessagesComponent,
4679
- UploadDropZoneDirective,
4680
- UploadDropZoneComponent
4681
- ];
4682
- /**
4683
- * Utility array that contains all `Upload` related components and directives
4684
- */
4685
- const KENDO_UPLOAD = [
4686
- UploadComponent,
4687
- UploadActionButtonsComponent,
4688
- UploadStatusTotalComponent,
4689
- FileTemplateDirective,
4690
- FileInfoTemplateDirective,
4691
- CustomMessagesComponent,
4692
- UploadDropZoneDirective,
4693
- UploadDropZoneComponent
4694
- ];
4695
- /**
4696
- * Utility array that contains all `@progress/kendo-angular-upload` related components and directives
4697
- */
4698
- const KENDO_UPLOADS = [
4699
- ...KENDO_FILESELECT,
4700
- ...KENDO_UPLOAD
4701
- ];
4702
-
4703
- // IMPORTANT: NgModule export kept for backwards compatibility
4704
- /**
4705
- * Represents the [NgModule](https://angular.io/api/core/NgModule) definition for the FileSelect component.
4706
- */
4707
- class FileSelectModule {
4708
- }
4709
- FileSelectModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4710
- FileSelectModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: FileSelectModule, imports: [FileSelectComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent], exports: [FileSelectComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent] });
4711
- FileSelectModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectModule, providers: [
4712
- IconsService,
4713
- PopupService,
4714
- ResizeBatchService
4715
- ], imports: [FileSelectComponent, CustomMessagesComponent, UploadDropZoneComponent] });
4716
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: FileSelectModule, decorators: [{
4717
- type: NgModule,
4718
- args: [{
4719
- exports: [...KENDO_FILESELECT],
4720
- imports: [...KENDO_FILESELECT],
4721
- providers: [
4722
- IconsService,
4723
- PopupService,
4724
- ResizeBatchService
4725
- ]
4726
- }]
4727
- }] });
4728
-
4729
- // IMPORTANT: NgModule export kept for backwards compatibility
4730
- /**
4731
- * Represents the [NgModule](https://angular.io/api/core/NgModule) definition for the Upload component.
4732
- */
4733
- class UploadModule {
4734
- }
4735
- UploadModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4736
- UploadModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: UploadModule, imports: [UploadComponent, UploadActionButtonsComponent, UploadStatusTotalComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent], exports: [UploadComponent, UploadActionButtonsComponent, UploadStatusTotalComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent] });
4737
- UploadModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadModule, providers: [
4738
- IconsService,
4739
- PopupService,
4740
- ResizeBatchService
4741
- ], imports: [UploadComponent, UploadActionButtonsComponent, UploadStatusTotalComponent, CustomMessagesComponent, UploadDropZoneComponent] });
4742
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadModule, decorators: [{
4743
- type: NgModule,
4744
- args: [{
4745
- exports: [...KENDO_UPLOAD],
4746
- imports: [...KENDO_UPLOAD],
4747
- providers: [
4748
- IconsService,
4749
- PopupService,
4750
- ResizeBatchService
4751
- ]
4752
- }]
4753
- }] });
4754
-
4755
- // IMPORTANT: NgModule export kept for backwards compatibility
4756
- /**
4757
- * Represents the [NgModule](link:site.data.urls.angular['ngmoduleapi'])
4758
- * definition for the Uploads components.
4759
- *
4760
- * @example
4761
- *
4762
- * ```ts-no-run
4763
- * import { UploadsModule } from '@progress/kendo-angular-upload';
4764
- *
4765
- * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
4766
- * import { NgModule } from '@angular/core';
4767
- *
4768
- * import { AppComponent } from './app.component';
4769
- *
4770
- * _@NgModule({
4771
- * declarations: [AppComponent],
4772
- * imports: [BrowserModule, UploadsModule],
4773
- * bootstrap: [AppComponent]
4774
- * })
4775
- * export class AppModule {}
4776
- *
4777
- * platformBrowserDynamic().bootstrapModule(AppModule);
4778
- *
4779
- * ```
4780
- */
4781
- class UploadsModule {
4782
- }
4783
- UploadsModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
4784
- UploadsModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: UploadsModule, imports: [FileSelectComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent, UploadComponent, UploadActionButtonsComponent, UploadStatusTotalComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent], exports: [FileSelectComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent, UploadComponent, UploadActionButtonsComponent, UploadStatusTotalComponent, FileTemplateDirective, FileInfoTemplateDirective, CustomMessagesComponent, UploadDropZoneDirective, UploadDropZoneComponent] });
4785
- UploadsModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadsModule, providers: [
4786
- IconsService,
4787
- PopupService,
4788
- ResizeBatchService
4789
- ], imports: [FileSelectComponent, CustomMessagesComponent, UploadDropZoneComponent, UploadComponent, UploadActionButtonsComponent, UploadStatusTotalComponent, CustomMessagesComponent, UploadDropZoneComponent] });
4790
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: UploadsModule, decorators: [{
4791
- type: NgModule,
4792
- args: [{
4793
- exports: [...KENDO_UPLOADS],
4794
- imports: [...KENDO_UPLOADS],
4795
- providers: [
4796
- IconsService,
4797
- PopupService,
4798
- ResizeBatchService
4799
- ]
4800
- }]
4801
- }] });
4802
-
4803
- /**
4804
- * Generated bundle index. Do not edit.
4805
- */
4806
-
4807
- export { CancelEvent, ClearEvent, CustomMessagesComponent, DropZoneService, ErrorEvent, FileInfoTemplateDirective, FileListComponent, FileListItemActionButtonComponent, FileListItemBase, FileListMultipleItemsComponent, FileListSingleItemComponent, FileMap, FileSelectComponent, FileSelectDirective, FileSelectModule, FileState, FileTemplateDirective, KENDO_FILESELECT, KENDO_UPLOAD, KENDO_UPLOADS, NavigationService, PauseEvent, RemoveEvent, ResumeEvent, SelectEvent, SuccessEvent, UPLOAD_VALUE_ACCESSOR, UploadActionButtonsComponent, UploadComponent, UploadDropZoneComponent, UploadDropZoneDirective, UploadEvent, UploadModule, UploadProgressEvent, UploadService, UploadStatusTotalComponent, UploadsModule, validateFiles };
4808
-