quasar-ui-danx 0.4.2 → 0.4.4

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 (75) hide show
  1. package/dist/danx.es.js +7127 -6615
  2. package/dist/danx.es.js.map +1 -1
  3. package/dist/danx.umd.js +11 -5
  4. package/dist/danx.umd.js.map +1 -1
  5. package/dist/style.css +1 -1
  6. package/package.json +3 -1
  7. package/src/components/ActionTable/ActionTable.vue +28 -41
  8. package/src/components/ActionTable/Columns/ActionTableColumn.vue +19 -18
  9. package/src/components/ActionTable/Filters/CollapsableFiltersSidebar.vue +6 -6
  10. package/src/components/ActionTable/Filters/{FilterFieldList.vue → FilterList.vue} +26 -26
  11. package/src/components/ActionTable/Filters/FilterableField.vue +28 -31
  12. package/src/components/ActionTable/Filters/index.ts +2 -2
  13. package/src/components/ActionTable/Form/Fields/EditOnClickTextField.vue +71 -0
  14. package/src/components/ActionTable/Form/Fields/FieldLabel.vue +8 -13
  15. package/src/components/ActionTable/Form/Fields/MultiFileField.vue +48 -44
  16. package/src/components/ActionTable/Form/Fields/SelectField.vue +24 -38
  17. package/src/components/ActionTable/Form/Fields/SelectWithChildrenField.vue +28 -33
  18. package/src/components/ActionTable/Form/Fields/SingleFileField.vue +15 -15
  19. package/src/components/ActionTable/Form/Fields/SliderNumberField.vue +45 -0
  20. package/src/components/ActionTable/Form/Fields/TextField.vue +47 -66
  21. package/src/components/ActionTable/Form/Fields/index.ts +2 -0
  22. package/src/components/ActionTable/Form/RenderedForm.vue +50 -9
  23. package/src/components/ActionTable/Form/Utilities/MaxLengthCounter.vue +17 -0
  24. package/src/components/ActionTable/Form/Utilities/index.ts +1 -0
  25. package/src/components/ActionTable/Form/index.ts +1 -0
  26. package/src/components/ActionTable/Layouts/ActionTableLayout.vue +16 -15
  27. package/src/components/ActionTable/Toolbars/ActionToolbar.vue +6 -6
  28. package/src/components/ActionTable/listControls.ts +106 -166
  29. package/src/components/ActionTable/listHelpers.ts +2 -3
  30. package/src/components/ActionTable/tableColumns.ts +3 -27
  31. package/src/components/AuditHistory/AuditHistoryItemValue.vue +26 -26
  32. package/src/components/PanelsDrawer/PanelsDrawer.vue +17 -4
  33. package/src/components/PanelsDrawer/PanelsDrawerPanels.vue +6 -11
  34. package/src/components/PanelsDrawer/PanelsDrawerTabs.vue +20 -20
  35. package/src/components/Utility/Dialogs/ConfirmActionDialog.vue +39 -0
  36. package/src/components/Utility/Dialogs/ConfirmDialog.vue +10 -24
  37. package/src/components/Utility/Dialogs/DialogLayout.vue +10 -28
  38. package/src/components/Utility/Dialogs/FullscreenCarouselDialog.vue +42 -36
  39. package/src/components/Utility/Dialogs/index.ts +1 -0
  40. package/src/components/Utility/Files/FilePreview.vue +76 -73
  41. package/src/components/Utility/Layouts/ContentDrawer.vue +24 -31
  42. package/src/components/Utility/Tools/ActionVnode.vue +3 -3
  43. package/src/components/Utility/Tools/RenderVnode.vue +1 -1
  44. package/src/components/Utility/Transitions/MaxHeightTransition.vue +26 -0
  45. package/src/components/Utility/Transitions/index.ts +1 -0
  46. package/src/config/index.ts +36 -31
  47. package/src/helpers/FileUpload.ts +295 -297
  48. package/src/helpers/FlashMessages.ts +80 -71
  49. package/src/helpers/actions.ts +102 -82
  50. package/src/helpers/download.ts +189 -189
  51. package/src/helpers/downloadPdf.ts +55 -52
  52. package/src/helpers/formats.ts +151 -109
  53. package/src/helpers/index.ts +2 -0
  54. package/src/helpers/multiFileUpload.ts +72 -58
  55. package/src/helpers/objectStore.ts +52 -0
  56. package/src/helpers/request.ts +70 -51
  57. package/src/helpers/routes.ts +29 -0
  58. package/src/helpers/storage.ts +7 -3
  59. package/src/helpers/utils.ts +47 -29
  60. package/src/styles/quasar-reset.scss +16 -1
  61. package/src/styles/themes/danx/dialogs.scss +4 -0
  62. package/src/types/actions.d.ts +43 -0
  63. package/src/types/config.d.ts +15 -0
  64. package/src/types/controls.d.ts +99 -0
  65. package/src/types/dialogs.d.ts +32 -0
  66. package/src/types/fields.d.ts +20 -0
  67. package/src/types/files.d.ts +54 -0
  68. package/src/types/formats.d.ts +4 -0
  69. package/src/{components/ActionTable/Form/form.d.ts → types/forms.d.ts} +6 -0
  70. package/src/types/index.d.ts +12 -0
  71. package/src/types/requests.d.ts +13 -0
  72. package/src/types/shared.d.ts +15 -0
  73. package/src/types/tables.d.ts +27 -0
  74. package/types/index.d.ts +1 -1
  75. /package/src/components/ActionTable/Filters/{FilterFieldItem.vue → FilterItem.vue} +0 -0
@@ -1,305 +1,303 @@
1
1
  import { uid } from "quasar";
2
2
  import { danxOptions } from "../config";
3
+ import {
4
+ FileUploadAllCompleteCallback,
5
+ FileUploadCompleteCallback,
6
+ FileUploadErrorCallback,
7
+ FileUploadOptions,
8
+ FileUploadProgressCallback,
9
+ UploadedFile,
10
+ XHRFileUpload
11
+ } from "../types";
3
12
  import { resolveFileLocation } from "./files";
4
13
  import { FlashMessages } from "./FlashMessages";
5
14
 
6
- export type FileUploadOptions = {
7
- directory?: string,
8
- presignedUploadUrl?: Function | null;
9
- uploadCompletedUrl?: Function | null;
10
- };
11
-
12
- export type UploadedFile = {
13
- id: string,
14
- name: string,
15
- size: number,
16
- type: string,
17
- progress: number,
18
- location: string,
19
- blobUrl: string,
20
- url: string,
21
- }
22
15
 
23
16
  export class FileUpload {
24
- files: UploadedFile[] = [];
25
- fileUploads: UploadedFile[] = [];
26
- onErrorCb: Function | null = null;
27
- onProgressCb: Function | null = null;
28
- onCompleteCb: Function | null = null;
29
- onAllCompleteCb: Function | null = null;
30
- options: FileUploadOptions | null = {};
31
-
32
- constructor(files: UploadedFile[] | UploadedFile, options: FileUploadOptions | null = {}) {
33
- this.files = !Array.isArray(files) && !(files instanceof FileList) ? [files] : files;
34
- this.fileUploads = [];
35
- this.onErrorCb = null;
36
- this.onProgressCb = null;
37
- this.onCompleteCb = null;
38
- this.onAllCompleteCb = null;
39
-
40
- this.options = {
41
- ...danxOptions.value.fileUpload,
42
- ...options
43
- };
44
-
45
- if (!this.options.presignedUploadUrl) {
46
- throw new Error("Please configure the danxOptions: import { configure } from 'quasar-ui-danx';");
47
- }
48
- this.prepare();
49
- }
50
-
51
- /**
52
- * Prepares all files for upload and provides an id and blobUrl for each file
53
- */
54
- prepare() {
55
- // Prepare required attributes
56
- for (const file of this.files) {
57
- if (!(file instanceof File)) {
58
- throw Error(
59
- "FileUpload constructor requires a File object or a list of File objects"
60
- );
61
- }
62
-
63
- file.id = uid();
64
- file.blobUrl = URL.createObjectURL(file);
65
-
66
- // Prepare FormData
67
- const formData = new FormData();
68
- formData.append("file", file);
69
-
70
- this.fileUploads.push({
71
- file,
72
- xhr: null, // NOTE: The XHR will be setup asynchronously right before sending file uploads
73
- formData,
74
- isComplete: false
75
- });
76
- }
77
- }
78
-
79
- /**
80
- * Callback for when all files have been uploaded
81
- */
82
- onAllComplete(cb: Function) {
83
- this.onAllCompleteCb = cb;
84
- return this;
85
- }
86
-
87
- /**
88
- * Callback fired once for each file upon successful completion of upload
89
- * @param cb
90
- * @returns {FileUpload}
91
- */
92
- onComplete(cb: Function) {
93
- this.onCompleteCb = cb;
94
- return this;
95
- }
96
-
97
- /**
98
- * Callback fired each time there is an upload progress update for a file
99
- * @param cb
100
- * @returns {FileUpload}
101
- */
102
- onProgress(cb: Function) {
103
- this.onProgressCb = cb;
104
- return this;
105
- }
106
-
107
- /**
108
- * Callback fired when an error occurs during upload
109
- * @param cb
110
- * @returns {FileUpload}
111
- */
112
- onError(cb: Function) {
113
- this.onErrorCb = cb;
114
- return this;
115
- }
116
-
117
- /**
118
- * Handles the error events / fires the callback if it is set
119
- * @param e
120
- * @param file
121
- * @param error
122
- */
123
- errorHandler(e: InputEvent, file: UploadedFile, error = null) {
124
- if (this.onErrorCb) {
125
- this.onErrorCb({ e, file, error });
126
- }
127
- }
128
-
129
- /**
130
- * Resolve the locations of all the files
131
- * @returns {Promise<FileUpload>}
132
- */
133
- async resolveLocation(waitMessage = null) {
134
- for (const fileUpload of this.fileUploads) {
135
- fileUpload.file.location = await resolveFileLocation(
136
- fileUpload.file,
137
- waitMessage
138
- );
139
- fileUpload.formData.append(
140
- "meta",
141
- JSON.stringify(fileUpload.file.location)
142
- );
143
- }
144
- return this;
145
- }
146
-
147
- /**
148
- * Fires the progress callback
149
- * @param fileUpload
150
- * @param progress
151
- */
152
- fireProgressCallback(fileUpload, progress) {
153
- fileUpload.file.progress = progress;
154
- this.onProgressCb && this.onProgressCb({ file: this.wrapFile(fileUpload.file), progress });
155
- }
156
-
157
- /**
158
- * Fires the complete callback
159
- * @param fileUpload
160
- * @param uploadedFile
161
- */
162
- fireCompleteCallback(fileUpload, uploadedFile) {
163
- fileUpload.isComplete = true;
164
- fileUpload.file.progress = 1;
165
- this.onCompleteCb && this.onCompleteCb({ file: this.wrapFile(fileUpload.file), uploadedFile });
166
- }
167
-
168
- /**
169
- * Check if all files have been uploaded and call the callback if they have
170
- */
171
- checkAllComplete() {
172
- if (this.onAllCompleteCb) {
173
- if (this.fileUploads.every((fileUpload) => fileUpload.isComplete)) {
174
- this.onAllCompleteCb({ files: this.fileUploads });
175
- }
176
- }
177
- }
178
-
179
- /**
180
- * Returns a native JS object that is easier to work with than the File objects (no weird behavior of missing
181
- * properties, easily printable, etc.)
182
- * @param file
183
- * @returns {{size, name, progress, location, blobUrl: *, id, type}}
184
- */
185
- wrapFile(file) {
186
- return {
187
- id: file.id,
188
- name: file.name,
189
- size: file.size,
190
- type: file.type,
191
- progress: file.progress,
192
- location: file.location,
193
- blobUrl: file.blobUrl
194
- };
195
- }
196
-
197
- /**
198
- * Registers all the callbacks requested for the XHR / post-processing of file uploads
199
- */
200
- setXhrCallbacks() {
201
- // Set the error callbacks
202
- for (const fileUpload of this.fileUploads) {
203
- fileUpload.xhr.addEventListener(
204
- "error",
205
- (e) => this.errorHandler(e, fileUpload.file),
206
- false
207
- );
208
- }
209
-
210
- // Set the progress callbacks
211
- if (this.onProgressCb) {
212
- for (const fileUpload of this.fileUploads) {
213
- fileUpload.xhr.upload.addEventListener(
214
- "progress",
215
- (e) => {
216
- // Max of 95%, so we can indicate we are completing the signed URL process
217
- const progress = Math.min(.95, e.loaded / e.total);
218
- this.fireProgressCallback(fileUpload, progress);
219
- },
220
- false
221
- );
222
- }
223
- }
224
-
225
- // Set the load callbacks which registers the Complete / All Complete callbacks and handles non-xhr related
226
- // errors
227
- for (const fileUpload of this.fileUploads) {
228
- fileUpload.xhr.addEventListener(
229
- "load",
230
- async (e) => {
231
- try {
232
- // First complete the presigned upload to get the updated file resource data
233
- const uploadedFile = await this.completePresignedUpload(fileUpload);
234
-
235
- // Fire the file complete callbacks
236
- this.fireCompleteCallback(fileUpload, uploadedFile);
237
- this.checkAllComplete();
238
- } catch (error) {
239
- this.errorHandler(e, fileUpload.file, error);
240
- }
241
- },
242
- false
243
- );
244
- }
245
- }
246
-
247
- /**
248
- * Mark the presigned upload as completed and return the file resource from the platform server
249
- * @param fileUpload
250
- * @returns {Promise<void>}
251
- */
252
- async completePresignedUpload(fileUpload) {
253
- // Show 95% as the last 5% will be to complete the presigned upload
254
- this.fireProgressCallback(fileUpload, .95);
255
-
256
- // Let the platform know the presigned upload is complete
257
- return await fetch(this.options.uploadCompletedUrl(fileUpload.file.resource_id), { method: "POST" }).then(r => r.json());
258
- }
259
-
260
- /**
261
- * Start uploading all files
262
- */
263
- async upload() {
264
- for (const fileUpload of this.fileUploads) {
265
- const mimeType = fileUpload.file.mimeType || fileUpload.file.type;
266
- const presignedUrl = this.options.presignedUploadUrl(this.options.directory, fileUpload.file.name, mimeType);
267
-
268
- // Fetch presigned upload URL
269
- const fileResource = await fetch(presignedUrl).then(r => r.json());
270
-
271
- if (!fileResource.url) {
272
- FlashMessages.error("Could not fetch presigned upload URL for file " + fileUpload.file.name);
273
- continue;
274
- }
275
-
276
- const isS3Upload = !fileResource.url.match("upload-presigned-url-contents");
277
-
278
- // We need the file resource ID to complete the presigned upload
279
- fileUpload.file.resource_id = fileResource.id;
280
-
281
- // Prepare XHR request
282
- const xhr = new XMLHttpRequest();
283
-
284
- // The XHR request is different based on weather we're sending to S3 or the platform server
285
- if (isS3Upload) {
286
- xhr.open("PUT", fileResource.url);
287
- xhr.setRequestHeader("Content-Type", mimeType);
288
- fileUpload.body = fileUpload.file;
289
- } else {
290
- xhr.open("POST", fileResource.url);
291
- fileUpload.body = fileUpload.formData;
292
- }
293
-
294
- fileUpload.xhr = xhr;
295
- }
296
-
297
- // Set all the callbacks on the XHR requests
298
- this.setXhrCallbacks();
299
-
300
- // Send all the XHR file uploads
301
- for (const fileUpload of this.fileUploads) {
302
- fileUpload.xhr.send(fileUpload.body);
303
- }
304
- }
17
+ files: UploadedFile[] = [];
18
+ fileUploads: XHRFileUpload[] = [];
19
+ onErrorCb: FileUploadErrorCallback | null = null;
20
+ onProgressCb: FileUploadProgressCallback | null = null;
21
+ onCompleteCb: FileUploadCompleteCallback | null = null;
22
+ onAllCompleteCb: FileUploadAllCompleteCallback | null = null;
23
+ options: FileUploadOptions;
24
+
25
+ constructor(files: UploadedFile[] | UploadedFile, options?: FileUploadOptions) {
26
+ this.files = !Array.isArray(files) && !(files instanceof FileList) ? [files] : files;
27
+ this.fileUploads = [];
28
+ this.onErrorCb = null;
29
+ this.onProgressCb = null;
30
+ this.onCompleteCb = null;
31
+ this.onAllCompleteCb = null;
32
+
33
+ this.options = {
34
+ createPresignedUpload: null,
35
+ completePresignedUpload: null,
36
+ ...danxOptions.value.fileUpload,
37
+ ...options
38
+ };
39
+
40
+ if (!this.options.createPresignedUpload || !this.options.completePresignedUpload) {
41
+ throw new Error("Please configure danxOptions.fileUpload: import { configure } from 'quasar-ui-danx';");
42
+ }
43
+ this.prepare();
44
+ }
45
+
46
+ /**
47
+ * Prepares all files for upload and provides an id and blobUrl for each file
48
+ */
49
+ prepare() {
50
+ // Prepare required attributes
51
+ for (const file of this.files) {
52
+ if (!(file instanceof File)) {
53
+ throw Error(
54
+ "FileUpload constructor requires a File object or a list of File objects"
55
+ );
56
+ }
57
+
58
+ file.id = uid();
59
+ file.blobUrl = URL.createObjectURL(file);
60
+
61
+ // Prepare FormData
62
+ const formData = new FormData();
63
+ formData.append("file", file);
64
+
65
+ this.fileUploads.push({
66
+ file,
67
+ xhr: null, // NOTE: The XHR will be setup asynchronously right before sending file uploads
68
+ formData,
69
+ isComplete: false
70
+ });
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Callback for when all files have been uploaded
76
+ */
77
+ onAllComplete(cb: FileUploadAllCompleteCallback) {
78
+ this.onAllCompleteCb = cb;
79
+ return this;
80
+ }
81
+
82
+ /**
83
+ * Callback fired once for each file upon successful completion of upload
84
+ * @param cb
85
+ * @returns {FileUpload}
86
+ */
87
+ onComplete(cb: FileUploadCompleteCallback) {
88
+ this.onCompleteCb = cb;
89
+ return this;
90
+ }
91
+
92
+ /**
93
+ * Callback fired each time there is an upload progress update for a file
94
+ * @param cb
95
+ * @returns {FileUpload}
96
+ */
97
+ onProgress(cb: FileUploadProgressCallback) {
98
+ this.onProgressCb = cb;
99
+ return this;
100
+ }
101
+
102
+ /**
103
+ * Callback fired when an error occurs during upload
104
+ */
105
+ onError(cb: FileUploadErrorCallback) {
106
+ this.onErrorCb = cb;
107
+ return this;
108
+ }
109
+
110
+ /**
111
+ * Handles the error events / fires the callback if it is set
112
+ */
113
+ errorHandler(e: InputEvent, file: UploadedFile, error = null) {
114
+ if (this.onErrorCb) {
115
+ this.onErrorCb({ e, file, error });
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Resolve the locations of all the files
121
+ * @returns {Promise<FileUpload>}
122
+ */
123
+ async resolveLocation(waitMessage = null) {
124
+ for (const fileUpload of this.fileUploads) {
125
+ fileUpload.file.location = await resolveFileLocation(
126
+ fileUpload.file,
127
+ waitMessage
128
+ );
129
+ fileUpload.formData.append(
130
+ "meta",
131
+ JSON.stringify(fileUpload.file.location)
132
+ );
133
+ }
134
+ return this;
135
+ }
136
+
137
+ /**
138
+ * Fires the progress callback
139
+ * @param fileUpload
140
+ * @param progress
141
+ */
142
+ fireProgressCallback(fileUpload: XHRFileUpload, progress: number) {
143
+ fileUpload.file.progress = progress;
144
+ this.onProgressCb && this.onProgressCb({ file: this.wrapFile(fileUpload.file), progress });
145
+ }
146
+
147
+ /**
148
+ * Fires the complete callback
149
+ * @param fileUpload
150
+ * @param uploadedFile
151
+ */
152
+ fireCompleteCallback(fileUpload: XHRFileUpload, uploadedFile: UploadedFile) {
153
+ fileUpload.isComplete = true;
154
+ fileUpload.file.progress = 1;
155
+ this.onCompleteCb && this.onCompleteCb({ file: this.wrapFile(fileUpload.file), uploadedFile });
156
+ }
157
+
158
+ /**
159
+ * Check if all files have been uploaded and call the callback if they have
160
+ */
161
+ checkAllComplete() {
162
+ if (this.onAllCompleteCb) {
163
+ if (this.fileUploads.every((fileUpload) => fileUpload.isComplete)) {
164
+ this.onAllCompleteCb({ files: this.fileUploads });
165
+ }
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Returns a native JS object that is easier to work with than the File objects (no weird behavior of missing
171
+ * properties, easily printable, etc.)
172
+ */
173
+ wrapFile(file: UploadedFile) {
174
+ return {
175
+ id: file.id,
176
+ name: file.name,
177
+ size: file.size,
178
+ type: file.type,
179
+ progress: file.progress,
180
+ location: file.location,
181
+ blobUrl: file.blobUrl,
182
+ url: ""
183
+ };
184
+ }
185
+
186
+ /**
187
+ * Registers all the callbacks requested for the XHR / post-processing of file uploads
188
+ */
189
+ setXhrCallbacks() {
190
+ // Set the error callbacks
191
+ for (const fileUpload of this.fileUploads) {
192
+ fileUpload.xhr?.addEventListener(
193
+ "error",
194
+ (e) => this.errorHandler(e, fileUpload.file),
195
+ false
196
+ );
197
+ }
198
+
199
+ // Set the progress callbacks
200
+ if (this.onProgressCb) {
201
+ for (const fileUpload of this.fileUploads) {
202
+ fileUpload.xhr?.upload.addEventListener(
203
+ "progress",
204
+ (e) => {
205
+ // Max of 95%, so we can indicate we are completing the signed URL process
206
+ const progress = Math.min(.95, e.loaded / e.total);
207
+ this.fireProgressCallback(fileUpload, progress);
208
+ },
209
+ false
210
+ );
211
+ }
212
+ }
213
+
214
+ // Set the load callbacks which registers the Complete / All Complete callbacks and handles non-xhr related
215
+ // errors
216
+ for (const fileUpload of this.fileUploads) {
217
+ fileUpload.xhr?.addEventListener(
218
+ "load",
219
+ async (e) => {
220
+ try {
221
+ // First complete the presigned upload to get the updated file resource data
222
+ const uploadedFile = await this.completePresignedUpload(fileUpload);
223
+
224
+ // Fire the file complete callbacks
225
+ this.fireCompleteCallback(fileUpload, uploadedFile);
226
+ this.checkAllComplete();
227
+ } catch (error) {
228
+ this.errorHandler(e, fileUpload.file, error);
229
+ }
230
+ },
231
+ false
232
+ );
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Mark the presigned upload as completed and return the file resource from the platform server
238
+ */
239
+ async completePresignedUpload(fileUpload: XHRFileUpload) {
240
+ // Show 95% as the last 5% will be to complete the presigned upload
241
+ this.fireProgressCallback(fileUpload, .95);
242
+
243
+ if (!fileUpload.file.resource_id) {
244
+ throw new Error("File resource ID is required to complete presigned upload");
245
+ }
246
+
247
+ if (!this.options.completePresignedUpload) {
248
+ throw new Error("Please configure danxOptions.fileUpload.completePresignedUpload");
249
+ }
250
+
251
+ // Let the platform know the presigned upload is complete
252
+ return await this.options.completePresignedUpload(fileUpload.file.resource_id);
253
+ }
254
+
255
+ /**
256
+ * Start uploading all files
257
+ */
258
+ async upload() {
259
+ for (const fileUpload of this.fileUploads) {
260
+ const mimeType = fileUpload.file.mimeType || fileUpload.file.type;
261
+
262
+ if (!this.options.createPresignedUpload) {
263
+ throw new Error("Please configure danxOptions.fileUpload.createPresignedUpload");
264
+ }
265
+
266
+ // Fetch presigned upload URL
267
+ const fileResource = await this.options.createPresignedUpload(this.options.directory || "", fileUpload.file.name, mimeType);
268
+
269
+ if (!fileResource.url) {
270
+ FlashMessages.error("Could not fetch presigned upload URL for file " + fileUpload.file.name);
271
+ continue;
272
+ }
273
+
274
+ const isS3Upload = !fileResource.url.match("upload-presigned-url-contents");
275
+
276
+ // We need the file resource ID to complete the presigned upload
277
+ fileUpload.file.resource_id = fileResource.id;
278
+
279
+ // Prepare XHR request
280
+ const xhr = new XMLHttpRequest();
281
+
282
+ // The XHR request is different based on weather we're sending to S3 or the platform server
283
+ if (isS3Upload) {
284
+ xhr.open("PUT", fileResource.url);
285
+ xhr.setRequestHeader("Content-Type", mimeType);
286
+ fileUpload.body = fileUpload.file;
287
+ } else {
288
+ xhr.open("POST", fileResource.url);
289
+ fileUpload.body = fileUpload.formData;
290
+ }
291
+
292
+ fileUpload.xhr = xhr;
293
+ }
294
+
295
+ // Set all the callbacks on the XHR requests
296
+ this.setXhrCallbacks();
297
+
298
+ // Send all the XHR file uploads
299
+ for (const fileUpload of this.fileUploads) {
300
+ fileUpload.xhr?.send(fileUpload.body);
301
+ }
302
+ }
305
303
  }