@overmap-ai/core 1.0.48-bulk-form-submission.2 → 1.0.48-bulk-form-submission.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.
- package/dist/overmap-core.js +175 -35
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +175 -35
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/services/AttachmentService.d.ts +3 -2
- package/dist/sdk/services/UserFormSubmissionService.d.ts +2 -2
- package/dist/store/slices/formSubmissionSlice.d.ts +2 -1
- package/dist/store/slices/index.d.ts +1 -1
- package/dist/store/slices/issueSlice.d.ts +9 -1
- package/dist/store/slices/utils.d.ts +1 -0
- package/dist/typings/files.d.ts +11 -1
- package/dist/typings/models/attachments.d.ts +7 -10
- package/dist/typings/models/base.d.ts +5 -0
- package/dist/typings/models/components.d.ts +2 -3
- package/dist/typings/models/forms.d.ts +3 -5
- package/dist/utils/file.d.ts +2 -0
- package/package.json +1 -1
|
@@ -795,6 +795,19 @@ var __publicField = (obj, key, value) => {
|
|
|
795
795
|
element.click();
|
|
796
796
|
document.body.removeChild(element);
|
|
797
797
|
}
|
|
798
|
+
const constructUploadedFilePayloads = async (files) => {
|
|
799
|
+
const filePayloads = {};
|
|
800
|
+
for (const file of files) {
|
|
801
|
+
const sha1 = await hashFile(file);
|
|
802
|
+
filePayloads[sha1] = {
|
|
803
|
+
sha1,
|
|
804
|
+
extension: file.name.split(".").pop() || "",
|
|
805
|
+
file_type: file.type,
|
|
806
|
+
size: file.size
|
|
807
|
+
};
|
|
808
|
+
}
|
|
809
|
+
return Object.values(filePayloads);
|
|
810
|
+
};
|
|
798
811
|
const fileToBlob = async (dataUrl) => {
|
|
799
812
|
return (await fetch(dataUrl)).blob();
|
|
800
813
|
};
|
|
@@ -1528,6 +1541,15 @@ var __publicField = (obj, key, value) => {
|
|
|
1528
1541
|
throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
|
|
1529
1542
|
}
|
|
1530
1543
|
}
|
|
1544
|
+
function updateAttachments(state, action) {
|
|
1545
|
+
for (const attachment of action.payload) {
|
|
1546
|
+
if (attachment.offline_id in state.attachments) {
|
|
1547
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
1548
|
+
} else {
|
|
1549
|
+
throw new Error(`Attachment ${attachment.offline_id} does not exist.`);
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1531
1553
|
function removeAttachment(state, action) {
|
|
1532
1554
|
if (action.payload in state.attachments) {
|
|
1533
1555
|
delete state.attachments[action.payload];
|
|
@@ -2121,6 +2143,7 @@ var __publicField = (obj, key, value) => {
|
|
|
2121
2143
|
}
|
|
2122
2144
|
},
|
|
2123
2145
|
updateIssueAttachment: updateAttachment,
|
|
2146
|
+
updateIssueAttachments: updateAttachments,
|
|
2124
2147
|
removeIssue: (state, action) => {
|
|
2125
2148
|
if (action.payload in state.issues) {
|
|
2126
2149
|
delete state.issues[action.payload];
|
|
@@ -2129,6 +2152,7 @@ var __publicField = (obj, key, value) => {
|
|
|
2129
2152
|
}
|
|
2130
2153
|
},
|
|
2131
2154
|
removeIssueAttachment: removeAttachment,
|
|
2155
|
+
removeIssueAttachments: removeAttachments,
|
|
2132
2156
|
removeIssueUpdate: (state, action) => {
|
|
2133
2157
|
if (action.payload in state.updates) {
|
|
2134
2158
|
delete state.updates[action.payload];
|
|
@@ -2238,6 +2262,7 @@ var __publicField = (obj, key, value) => {
|
|
|
2238
2262
|
addToRecentIssues,
|
|
2239
2263
|
cleanRecentIssues,
|
|
2240
2264
|
removeIssueAttachment,
|
|
2265
|
+
removeIssueAttachments,
|
|
2241
2266
|
removeAttachmentsOfIssue,
|
|
2242
2267
|
removeIssue,
|
|
2243
2268
|
removeIssueUpdate,
|
|
@@ -2251,6 +2276,7 @@ var __publicField = (obj, key, value) => {
|
|
|
2251
2276
|
setVisibleStatuses,
|
|
2252
2277
|
setVisibleUserIds,
|
|
2253
2278
|
updateIssueAttachment,
|
|
2279
|
+
updateIssueAttachments,
|
|
2254
2280
|
updateIssue,
|
|
2255
2281
|
// Commments
|
|
2256
2282
|
addIssueComment,
|
|
@@ -3814,6 +3840,16 @@ var __publicField = (obj, key, value) => {
|
|
|
3814
3840
|
state.attachments[attachment.offline_id] = attachment;
|
|
3815
3841
|
}
|
|
3816
3842
|
},
|
|
3843
|
+
updateFormSubmissionAttachments: (state, action) => {
|
|
3844
|
+
for (const attachment of action.payload) {
|
|
3845
|
+
if (state.attachments[attachment.offline_id] === void 0) {
|
|
3846
|
+
throw new Error(`Attachment with offline_id ${attachment.offline_id} does not exist`);
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
for (const attachment of action.payload) {
|
|
3850
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3851
|
+
}
|
|
3852
|
+
},
|
|
3817
3853
|
// The delete actions for UserFormSubmissionAttachments are not used in the app, but are included for completeness
|
|
3818
3854
|
// Could be used if editing a submission is ever supported, will be applicable for supporting tip tap content in submissions
|
|
3819
3855
|
deleteFormSubmissionAttachment: (state, action) => {
|
|
@@ -3844,6 +3880,7 @@ var __publicField = (obj, key, value) => {
|
|
|
3844
3880
|
addFormSubmissionAttachment,
|
|
3845
3881
|
addFormSubmissionAttachments,
|
|
3846
3882
|
setFormSubmissionAttachments,
|
|
3883
|
+
updateFormSubmissionAttachments,
|
|
3847
3884
|
deleteFormSubmissionAttachment,
|
|
3848
3885
|
deleteFormSubmissionAttachments
|
|
3849
3886
|
} = formSubmissionSlice.actions;
|
|
@@ -4697,6 +4734,22 @@ var __publicField = (obj, key, value) => {
|
|
|
4697
4734
|
}
|
|
4698
4735
|
}
|
|
4699
4736
|
class AttachmentService extends BaseApiService {
|
|
4737
|
+
processPresignedUrls(presignedUrls) {
|
|
4738
|
+
for (const [sha1, presignedUrl] of Object.entries(presignedUrls)) {
|
|
4739
|
+
void this.enqueueRequest({
|
|
4740
|
+
url: presignedUrl.url,
|
|
4741
|
+
description: "Upload file",
|
|
4742
|
+
method: HttpMethod.POST,
|
|
4743
|
+
isExternalUrl: true,
|
|
4744
|
+
isAuthNeeded: false,
|
|
4745
|
+
attachmentHash: sha1,
|
|
4746
|
+
// TODO: can we use the sha1 as the blocker?
|
|
4747
|
+
blockers: [`s3-${sha1}`],
|
|
4748
|
+
blocks: [sha1],
|
|
4749
|
+
s3url: presignedUrl
|
|
4750
|
+
});
|
|
4751
|
+
}
|
|
4752
|
+
}
|
|
4700
4753
|
fetchAll(projectId) {
|
|
4701
4754
|
const promise = this.enqueueRequest({
|
|
4702
4755
|
description: "Fetch attachments",
|
|
@@ -4722,6 +4775,7 @@ var __publicField = (obj, key, value) => {
|
|
|
4722
4775
|
}
|
|
4723
4776
|
const offlineAttachment = {
|
|
4724
4777
|
...attachmentPayload,
|
|
4778
|
+
// TODO: just handle creating the objectURL in here, then the front end doesn't need to worry about it
|
|
4725
4779
|
file: attachmentPayload.file.objectURL,
|
|
4726
4780
|
file_name: attachmentPayload.file.name,
|
|
4727
4781
|
file_type: attachmentPayload.file.type,
|
|
@@ -4755,6 +4809,7 @@ var __publicField = (obj, key, value) => {
|
|
|
4755
4809
|
}
|
|
4756
4810
|
const offlineAttachment = {
|
|
4757
4811
|
...attachmentPayload,
|
|
4812
|
+
// TODO: just handle creating the objectURL in here, then the front end doesn't need to worry about it
|
|
4758
4813
|
file: attachmentPayload.file.objectURL,
|
|
4759
4814
|
file_name: attachmentPayload.file.name,
|
|
4760
4815
|
file_type: attachmentPayload.file.type,
|
|
@@ -4788,6 +4843,7 @@ var __publicField = (obj, key, value) => {
|
|
|
4788
4843
|
}
|
|
4789
4844
|
const offlineAttachment = {
|
|
4790
4845
|
...attachmentPayload,
|
|
4846
|
+
// TODO: just handle creating the objectURL in here, then the front end doesn't need to worry about it
|
|
4791
4847
|
file: attachmentPayload.file.objectURL,
|
|
4792
4848
|
file_name: attachmentPayload.file.name,
|
|
4793
4849
|
file_type: attachmentPayload.file.type,
|
|
@@ -4840,7 +4896,7 @@ var __publicField = (obj, key, value) => {
|
|
|
4840
4896
|
offline_id,
|
|
4841
4897
|
project,
|
|
4842
4898
|
description: description2 ?? "",
|
|
4843
|
-
submitted_at: (/* @__PURE__ */ new Date()).
|
|
4899
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4844
4900
|
...fileProps
|
|
4845
4901
|
}
|
|
4846
4902
|
});
|
|
@@ -4853,26 +4909,54 @@ var __publicField = (obj, key, value) => {
|
|
|
4853
4909
|
/** the outer Promise is needed to await the hashing of each file, which is required before offline use. If wanting to
|
|
4854
4910
|
* attach promise handlers to the request to add the attachment in the backend, apply it on the promise returned from the
|
|
4855
4911
|
* OptimisticModelResult. */
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
};
|
|
4874
|
-
|
|
4912
|
+
// note the method is only marked as async since files needs to be hashed
|
|
4913
|
+
async attachFilesToIssue(files, issueId) {
|
|
4914
|
+
const { store } = this.client;
|
|
4915
|
+
const offlineAttachments = [];
|
|
4916
|
+
const attachmentsPayload = [];
|
|
4917
|
+
const currentUser = store.getState().userReducer.currentUser;
|
|
4918
|
+
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
4919
|
+
for (const file of files) {
|
|
4920
|
+
const attachment = offline({
|
|
4921
|
+
file: URL.createObjectURL(file),
|
|
4922
|
+
file_name: file.name,
|
|
4923
|
+
file_type: file.type,
|
|
4924
|
+
file_sha1: await hashFile(file),
|
|
4925
|
+
description: "",
|
|
4926
|
+
submitted_at: submittedAt,
|
|
4927
|
+
created_by: currentUser.id,
|
|
4928
|
+
issue: issueId
|
|
4929
|
+
});
|
|
4930
|
+
attachmentsPayload.push({
|
|
4931
|
+
offline_id: attachment.offline_id,
|
|
4932
|
+
name: attachment.file_name,
|
|
4933
|
+
sha1: attachment.file_sha1,
|
|
4934
|
+
description: attachment.description,
|
|
4935
|
+
created_by: attachment.created_by,
|
|
4936
|
+
issue_id: attachment.issue
|
|
4937
|
+
});
|
|
4938
|
+
offlineAttachments.push(attachment);
|
|
4939
|
+
}
|
|
4940
|
+
store.dispatch(addIssueAttachments(offlineAttachments));
|
|
4941
|
+
const promise = this.enqueueRequest({
|
|
4942
|
+
description: "Attach files to issue",
|
|
4943
|
+
method: HttpMethod.POST,
|
|
4944
|
+
url: `/issues/${issueId}/attach/`,
|
|
4945
|
+
payload: {
|
|
4946
|
+
submitted_at: submittedAt,
|
|
4947
|
+
attachments: attachmentsPayload,
|
|
4948
|
+
files: await constructUploadedFilePayloads(files)
|
|
4949
|
+
},
|
|
4950
|
+
blocks: offlineAttachments.map((attachment) => attachment.offline_id),
|
|
4951
|
+
blockers: offlineAttachments.map((attachment) => attachment.file_sha1)
|
|
4952
|
+
});
|
|
4953
|
+
promise.then(({ attachments, presigned_urls }) => {
|
|
4954
|
+
store.dispatch(updateIssueAttachments(attachments));
|
|
4955
|
+
this.processPresignedUrls(presigned_urls);
|
|
4956
|
+
}).catch(() => {
|
|
4957
|
+
store.dispatch(removeIssueAttachments(offlineAttachments.map((attachment) => attachment.offline_id)));
|
|
4875
4958
|
});
|
|
4959
|
+
return [offlineAttachments, promise.then(({ attachments }) => attachments)];
|
|
4876
4960
|
}
|
|
4877
4961
|
attachFilesToComponent(filesToSubmit, componentId) {
|
|
4878
4962
|
return filesToSubmit.map((file) => {
|
|
@@ -7148,17 +7232,18 @@ var __publicField = (obj, key, value) => {
|
|
|
7148
7232
|
}
|
|
7149
7233
|
// Note currently the bulkAdd method is specific to form submissions for components
|
|
7150
7234
|
// TODO: adapt the support bulk adding to any model type
|
|
7151
|
-
bulkAdd(args) {
|
|
7152
|
-
const { form_revision, values: argsValues,
|
|
7235
|
+
async bulkAdd(args) {
|
|
7236
|
+
const { form_revision, values: argsValues, componentOfflineIds } = args;
|
|
7153
7237
|
const { store } = this.client;
|
|
7154
|
-
const
|
|
7238
|
+
const offlineSubmissions = [];
|
|
7239
|
+
const offlineAttachments = [];
|
|
7155
7240
|
const submissionOfflineIds = [];
|
|
7156
|
-
const
|
|
7157
|
-
|
|
7241
|
+
const submissionsPayload = [];
|
|
7242
|
+
const attachmentsPayload = [];
|
|
7158
7243
|
const { values, files } = separateFilesFromValues(argsValues);
|
|
7159
7244
|
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7160
7245
|
const createdBy = store.getState().userReducer.currentUser.id;
|
|
7161
|
-
for (const component_id of
|
|
7246
|
+
for (const component_id of componentOfflineIds) {
|
|
7162
7247
|
const submission = offline({
|
|
7163
7248
|
form_revision,
|
|
7164
7249
|
values,
|
|
@@ -7166,12 +7251,43 @@ var __publicField = (obj, key, value) => {
|
|
|
7166
7251
|
submitted_at: submittedAt,
|
|
7167
7252
|
component: component_id
|
|
7168
7253
|
});
|
|
7169
|
-
attachFilesPromises = attachFilesPromises.concat(this.getAttachFilesPromises(files, submission));
|
|
7170
7254
|
submissionOfflineIds.push(submission.offline_id);
|
|
7171
|
-
|
|
7172
|
-
|
|
7255
|
+
submissionsPayload.push({ offline_id: submission.offline_id, component_id });
|
|
7256
|
+
offlineSubmissions.push(submission);
|
|
7257
|
+
for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
|
|
7258
|
+
for (const file of fileArray) {
|
|
7259
|
+
const sha1 = await hashFile(file);
|
|
7260
|
+
await this.client.files.addCache(file, sha1);
|
|
7261
|
+
const offlineAttachment = offline({
|
|
7262
|
+
file_name: file.name,
|
|
7263
|
+
file_sha1: sha1,
|
|
7264
|
+
file: URL.createObjectURL(file),
|
|
7265
|
+
submission: submission.offline_id,
|
|
7266
|
+
field_identifier: fieldIdentifier
|
|
7267
|
+
});
|
|
7268
|
+
offlineAttachments.push(offlineAttachment);
|
|
7269
|
+
attachmentsPayload.push({
|
|
7270
|
+
offline_id: offlineAttachment.offline_id,
|
|
7271
|
+
submission_id: submission.offline_id,
|
|
7272
|
+
sha1,
|
|
7273
|
+
name: file.name,
|
|
7274
|
+
field_identifier: fieldIdentifier
|
|
7275
|
+
});
|
|
7276
|
+
}
|
|
7277
|
+
}
|
|
7278
|
+
}
|
|
7279
|
+
const filesRecord = {};
|
|
7280
|
+
for (const file of Object.values(files).flat()) {
|
|
7281
|
+
const sha1 = await hashFile(file);
|
|
7282
|
+
filesRecord[sha1] = {
|
|
7283
|
+
sha1,
|
|
7284
|
+
extension: file.name.split(".").pop() || "",
|
|
7285
|
+
file_type: file.type,
|
|
7286
|
+
size: file.size
|
|
7287
|
+
};
|
|
7173
7288
|
}
|
|
7174
|
-
store.dispatch(addFormSubmissions(
|
|
7289
|
+
store.dispatch(addFormSubmissions(offlineSubmissions));
|
|
7290
|
+
store.dispatch(addFormSubmissionAttachments(offlineAttachments));
|
|
7175
7291
|
const promise = this.enqueueRequest({
|
|
7176
7292
|
description: "Bulk add form submissions",
|
|
7177
7293
|
method: HttpMethod.POST,
|
|
@@ -7179,17 +7295,37 @@ var __publicField = (obj, key, value) => {
|
|
|
7179
7295
|
payload: {
|
|
7180
7296
|
form_data: values,
|
|
7181
7297
|
submitted_at: submittedAt,
|
|
7182
|
-
|
|
7298
|
+
submissions: submissionsPayload,
|
|
7299
|
+
attachments: attachmentsPayload,
|
|
7300
|
+
files: Object.values(filesRecord)
|
|
7183
7301
|
},
|
|
7184
|
-
blockers:
|
|
7302
|
+
blockers: componentOfflineIds,
|
|
7185
7303
|
blocks: submissionOfflineIds
|
|
7186
7304
|
});
|
|
7187
|
-
promise.then((
|
|
7188
|
-
store.dispatch(updateFormSubmissions(
|
|
7305
|
+
promise.then(({ submissions, attachments, presigned_urls }) => {
|
|
7306
|
+
store.dispatch(updateFormSubmissions(submissions));
|
|
7307
|
+
store.dispatch(updateFormSubmissionAttachments(attachments));
|
|
7308
|
+
for (const [sha1, presigned_url] of Object.entries(presigned_urls)) {
|
|
7309
|
+
const file = filesRecord[sha1];
|
|
7310
|
+
if (!file)
|
|
7311
|
+
continue;
|
|
7312
|
+
void this.enqueueRequest({
|
|
7313
|
+
url: presigned_url.url,
|
|
7314
|
+
description: "Upload file",
|
|
7315
|
+
method: HttpMethod.POST,
|
|
7316
|
+
isExternalUrl: true,
|
|
7317
|
+
isAuthNeeded: false,
|
|
7318
|
+
attachmentHash: sha1,
|
|
7319
|
+
blockers: [`s3-${file.sha1}.${file.extension}`],
|
|
7320
|
+
blocks: [sha1],
|
|
7321
|
+
s3url: presigned_url
|
|
7322
|
+
});
|
|
7323
|
+
}
|
|
7189
7324
|
}).catch(() => {
|
|
7190
7325
|
store.dispatch(deleteFormSubmissions(submissionOfflineIds));
|
|
7326
|
+
store.dispatch(deleteFormSubmissionAttachments(offlineAttachments.map((x) => x.offline_id)));
|
|
7191
7327
|
});
|
|
7192
|
-
return [
|
|
7328
|
+
return [offlineSubmissions, promise.then(({ submissions }) => submissions)];
|
|
7193
7329
|
}
|
|
7194
7330
|
update(submission) {
|
|
7195
7331
|
const { store } = this.client;
|
|
@@ -15821,6 +15957,7 @@ var __publicField = (obj, key, value) => {
|
|
|
15821
15957
|
exports2.componentStageSlice = componentStageSlice;
|
|
15822
15958
|
exports2.componentTypeReducer = componentTypeReducer;
|
|
15823
15959
|
exports2.componentTypeSlice = componentTypeSlice;
|
|
15960
|
+
exports2.constructUploadedFilePayloads = constructUploadedFilePayloads;
|
|
15824
15961
|
exports2.coordinatesAreEqual = coordinatesAreEqual;
|
|
15825
15962
|
exports2.coordinatesToLiteral = coordinatesToLiteral;
|
|
15826
15963
|
exports2.coordinatesToPointGeometry = coordinatesToPointGeometry;
|
|
@@ -15949,6 +16086,7 @@ var __publicField = (obj, key, value) => {
|
|
|
15949
16086
|
exports2.removeFavouriteProjectId = removeFavouriteProjectId;
|
|
15950
16087
|
exports2.removeIssue = removeIssue;
|
|
15951
16088
|
exports2.removeIssueAttachment = removeIssueAttachment;
|
|
16089
|
+
exports2.removeIssueAttachments = removeIssueAttachments;
|
|
15952
16090
|
exports2.removeIssueComment = removeIssueComment;
|
|
15953
16091
|
exports2.removeIssueComments = removeIssueComments;
|
|
15954
16092
|
exports2.removeIssueUpdate = removeIssueUpdate;
|
|
@@ -16213,9 +16351,11 @@ var __publicField = (obj, key, value) => {
|
|
|
16213
16351
|
exports2.updateComponentTypeAttachment = updateComponentTypeAttachment;
|
|
16214
16352
|
exports2.updateDocuments = updateDocuments;
|
|
16215
16353
|
exports2.updateFormSubmission = updateFormSubmission;
|
|
16354
|
+
exports2.updateFormSubmissionAttachments = updateFormSubmissionAttachments;
|
|
16216
16355
|
exports2.updateFormSubmissions = updateFormSubmissions;
|
|
16217
16356
|
exports2.updateIssue = updateIssue;
|
|
16218
16357
|
exports2.updateIssueAttachment = updateIssueAttachment;
|
|
16358
|
+
exports2.updateIssueAttachments = updateIssueAttachments;
|
|
16219
16359
|
exports2.updateLicense = updateLicense;
|
|
16220
16360
|
exports2.updateOrCreateProject = updateOrCreateProject;
|
|
16221
16361
|
exports2.updateOrganizationAccess = updateOrganizationAccess;
|