@overmap-ai/core 1.0.63-form-submission-fix.0 → 1.0.63-form-submission-fix.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.
@@ -5491,36 +5491,65 @@ var __publicField = (obj, key, value) => {
5491
5491
  }
5492
5492
  return { fields: newFields, images };
5493
5493
  };
5494
- class FormService extends BaseApiService {
5495
- constructor() {
5496
- super(...arguments);
5497
- // Attach images to revision, after uploading them to S3
5498
- __publicField(this, "getAttachImagePromises", (images, offlineRevisionId) => {
5499
- return Object.entries(images).map(async ([key, image]) => {
5500
- const sha1 = await hashFile(image);
5501
- await this.client.files.addCache(image, sha1);
5502
- const [fileProps] = await this.client.files.uploadFileToS3(sha1);
5503
- const revisionAttachmentPayload = offline({
5504
- ...fileProps,
5505
- revision: offlineRevisionId,
5506
- field_identifier: key
5507
- });
5508
- const attach = await this.enqueueRequest({
5509
- description: "Attach image to form revision field",
5510
- method: HttpMethod.POST,
5511
- url: `/forms/revisions/${offlineRevisionId}/attachments/`,
5512
- payload: revisionAttachmentPayload,
5513
- blockers: [revisionAttachmentPayload.revision],
5514
- blocks: [revisionAttachmentPayload.offline_id]
5515
- });
5516
- const offlinePayload = {
5517
- ...revisionAttachmentPayload,
5518
- file: URL.createObjectURL(image)
5494
+ class FormService extends BaseUploadService {
5495
+ async bulkAddRevisionAttachments(revisionId, files) {
5496
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5497
+ const createdBy = this.client.store.getState().userReducer.currentUser.id;
5498
+ const filePayloads = {};
5499
+ const offlineFormRevisionAttachments = [];
5500
+ const attachmentPayloads = [];
5501
+ for (const [fieldIdentifier, file] of Object.entries(files)) {
5502
+ const sha1 = await hashFile(file);
5503
+ if (!(sha1 in filePayloads)) {
5504
+ filePayloads[sha1] = {
5505
+ sha1,
5506
+ file_type: file.type,
5507
+ extension: file.name.split(".").pop(),
5508
+ size: file.size
5519
5509
  };
5520
- this.dispatch(addFormRevisionAttachment(offlinePayload));
5521
- return attach;
5510
+ await this.client.files.addCache(file, sha1);
5511
+ }
5512
+ const offlineFormRevisionAttachment = offline({
5513
+ file: URL.createObjectURL(file),
5514
+ file_type: file.type,
5515
+ file_name: file.name,
5516
+ file_sha1: sha1,
5517
+ created_by: createdBy,
5518
+ revision: revisionId,
5519
+ submitted_at: submittedAt,
5520
+ field_identifier: fieldIdentifier
5522
5521
  });
5522
+ offlineFormRevisionAttachments.push(offlineFormRevisionAttachment);
5523
+ const attachmentPayload = {
5524
+ offline_id: offlineFormRevisionAttachment.offline_id,
5525
+ name: file.name,
5526
+ sha1
5527
+ };
5528
+ attachmentPayloads.push(attachmentPayload);
5529
+ }
5530
+ this.dispatch(addFormRevisionAttachments(offlineFormRevisionAttachments));
5531
+ const promise = this.enqueueRequest({
5532
+ description: "Attach files to form revision",
5533
+ method: HttpMethod.POST,
5534
+ url: `/forms/revisions/${revisionId}/attachments/bulk/`,
5535
+ payload: {
5536
+ submitted_at: submittedAt,
5537
+ attachments: attachmentPayloads
5538
+ },
5539
+ blockers: [revisionId],
5540
+ blocks: offlineFormRevisionAttachments.map((attachment) => attachment.offline_id)
5523
5541
  });
5542
+ promise.then((result) => {
5543
+ this.processPresignedUrls(result.presigned_urls);
5544
+ this.dispatch(updateFormRevisionAttachments(result.attachments));
5545
+ }).catch(() => {
5546
+ this.dispatch(
5547
+ deleteFormRevisionAttachments(
5548
+ offlineFormRevisionAttachments.map((attachment) => attachment.offline_id)
5549
+ )
5550
+ );
5551
+ });
5552
+ return [offlineFormRevisionAttachments, promise.then(({ attachments }) => attachments)];
5524
5553
  }
5525
5554
  async add(ownerId, form, initialRevision, urlPrefix) {
5526
5555
  const { fields, images } = await separateImageFromFields(initialRevision.fields);
@@ -5553,14 +5582,16 @@ var __publicField = (obj, key, value) => {
5553
5582
  blockers: [ownerId],
5554
5583
  blocks: [form.offline_id, offlineFormRevision.offline_id]
5555
5584
  });
5556
- const attachImagesPromises = this.getAttachImagePromises(images, offlineFormRevision.offline_id);
5585
+ const [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(
5586
+ offlineFormRevision.offline_id,
5587
+ images
5588
+ );
5557
5589
  void formPromise.catch((e) => {
5558
5590
  this.dispatch(deleteForm(form.offline_id));
5559
5591
  this.dispatch(deleteFormRevision(offlineFormRevision.offline_id));
5560
5592
  throw e;
5561
5593
  });
5562
- const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
5563
- return [form, offlineFormRevision, formPromise, settledPromise];
5594
+ return [form, offlineFormRevision, offlineFormRevisionAttachments, formPromise, attachmentsPromise];
5564
5595
  }
5565
5596
  addForOrganization(organizationId, initialRevision) {
5566
5597
  const state = this.client.store.getState();
@@ -5642,14 +5673,16 @@ var __publicField = (obj, key, value) => {
5642
5673
  blockers: [formId],
5643
5674
  blocks: [offlineRevision.offline_id]
5644
5675
  });
5645
- const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
5676
+ const [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(
5677
+ fullRevision.offline_id,
5678
+ images
5679
+ );
5646
5680
  void promise.then((result) => {
5647
5681
  this.dispatch(setFormRevision(result));
5648
5682
  }).catch(() => {
5649
5683
  this.dispatch(deleteFormRevision(fullRevision.offline_id));
5650
5684
  });
5651
- const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
5652
- return [fullRevision, settledPromise];
5685
+ return [fullRevision, offlineFormRevisionAttachments, promise, attachmentsPromise];
5653
5686
  }
5654
5687
  async favorite(formId) {
5655
5688
  const { store } = this.client;
@@ -5812,46 +5845,69 @@ var __publicField = (obj, key, value) => {
5812
5845
  return { values: newValues, files };
5813
5846
  };
5814
5847
  class FormSubmissionService extends BaseUploadService {
5815
- constructor() {
5816
- super(...arguments);
5817
- // Attach files to submission, after uploading them to S3
5818
- __publicField(this, "getAttachFilesPromises", (files, submission) => {
5819
- return Object.entries(files).map(async ([key, fileArray]) => {
5820
- const attachResults = [];
5821
- for (const file of fileArray) {
5822
- const sha1 = await hashFile(file);
5823
- await this.client.files.addCache(file, sha1);
5824
- const [fileProps] = await this.client.files.uploadFileToS3(sha1);
5825
- const submissionAttachmentPayload = offline({
5826
- ...fileProps,
5827
- submission: submission.offline_id,
5828
- field_identifier: key
5829
- });
5830
- const attach = await this.enqueueRequest({
5831
- description: "Attach file to form submission",
5832
- method: HttpMethod.POST,
5833
- url: `/forms/submission/${submission.offline_id}/attachments/`,
5834
- payload: submissionAttachmentPayload,
5835
- blockers: [
5836
- submission.asset,
5837
- submission.asset_stage,
5838
- submission.issue,
5839
- submission.form_revision
5840
- ].filter((x) => x !== void 0),
5841
- blocks: [submissionAttachmentPayload.offline_id]
5842
- });
5843
- const offlinePayload = {
5844
- ...submissionAttachmentPayload,
5845
- file: URL.createObjectURL(file)
5848
+ async bulkAddSubmissionAttachments(submissionId, files) {
5849
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5850
+ const createdBy = this.client.store.getState().userReducer.currentUser.id;
5851
+ const filePayloads = {};
5852
+ const offlineFormSubmissionAttachments = [];
5853
+ const attachmentPayloads = [];
5854
+ for (const [fieldIdentifier, filesArray] of Object.entries(files)) {
5855
+ for (const file of filesArray) {
5856
+ const sha1 = await hashFile(file);
5857
+ if (!(sha1 in filePayloads)) {
5858
+ filePayloads[sha1] = {
5859
+ sha1,
5860
+ file_type: file.type,
5861
+ extension: file.name.split(".").pop(),
5862
+ size: file.size
5846
5863
  };
5847
- this.dispatch(addFormSubmissionAttachment(offlinePayload));
5848
- attachResults.push(attach);
5864
+ await this.client.files.addCache(file, sha1);
5849
5865
  }
5850
- return attachResults;
5851
- });
5866
+ const offlineFormSubmissionAttachment = offline({
5867
+ file: URL.createObjectURL(file),
5868
+ file_type: file.type,
5869
+ file_name: file.name,
5870
+ file_sha1: sha1,
5871
+ created_by: createdBy,
5872
+ submission: submissionId,
5873
+ submitted_at: submittedAt,
5874
+ field_identifier: fieldIdentifier
5875
+ });
5876
+ offlineFormSubmissionAttachments.push(offlineFormSubmissionAttachment);
5877
+ const attachmentPayload = {
5878
+ offline_id: offlineFormSubmissionAttachment.offline_id,
5879
+ name: file.name,
5880
+ sha1
5881
+ };
5882
+ attachmentPayloads.push(attachmentPayload);
5883
+ }
5884
+ }
5885
+ this.dispatch(addFormSubmissionAttachments(offlineFormSubmissionAttachments));
5886
+ const promise = this.enqueueRequest({
5887
+ description: "Attach files to form submission",
5888
+ method: HttpMethod.POST,
5889
+ url: `/forms/submissions/${submissionId}/attachments/bulk/`,
5890
+ payload: {
5891
+ submitted_at: submittedAt,
5892
+ attachments: attachmentPayloads
5893
+ },
5894
+ blockers: [submissionId],
5895
+ blocks: offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id)
5896
+ });
5897
+ promise.then((result) => {
5898
+ this.processPresignedUrls(result.presigned_urls);
5899
+ this.dispatch(updateFormSubmissionAttachments(result.attachments));
5900
+ }).catch(() => {
5901
+ this.dispatch(
5902
+ deleteFormSubmissionAttachments(
5903
+ offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id)
5904
+ )
5905
+ );
5852
5906
  });
5907
+ return [offlineFormSubmissionAttachments, promise.then(({ attachments }) => attachments)];
5853
5908
  }
5854
- add(payload) {
5909
+ // Outer promise is for hashing and caching files for submission attachments
5910
+ async add(payload) {
5855
5911
  const { store } = this.client;
5856
5912
  const state = store.getState();
5857
5913
  const activeProjectId = state.projectReducer.activeProjectId;
@@ -5875,9 +5931,12 @@ var __publicField = (obj, key, value) => {
5875
5931
  ),
5876
5932
  blocks: [offlineSubmission.offline_id]
5877
5933
  });
5878
- const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
5879
5934
  this.dispatch(addFormSubmission(offlineSubmission));
5880
- void promise.then((result) => {
5935
+ const [offlineFormSubmissionAttachments, attachmentsPromise] = await this.bulkAddSubmissionAttachments(
5936
+ offlineSubmission.offline_id,
5937
+ files
5938
+ );
5939
+ promise.then((result) => {
5881
5940
  this.dispatch(addActiveProjectFormSubmissionsCount(1));
5882
5941
  this.dispatch(setFormSubmission(result));
5883
5942
  return result;
@@ -5885,8 +5944,7 @@ var __publicField = (obj, key, value) => {
5885
5944
  this.dispatch(deleteFormSubmission(offlineSubmission.offline_id));
5886
5945
  this.dispatch(addActiveProjectFormSubmissionsCount(-1));
5887
5946
  });
5888
- const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
5889
- return [offlineSubmission, settledPromise];
5947
+ return [offlineSubmission, offlineFormSubmissionAttachments, promise, attachmentsPromise];
5890
5948
  }
5891
5949
  // Note currently the bulkAdd method is specific to form submissions for assets
5892
5950
  // TODO: adapt the support bulk adding to any model type
@@ -5987,36 +6045,6 @@ var __publicField = (obj, key, value) => {
5987
6045
  });
5988
6046
  return batchPromises;
5989
6047
  }
5990
- update(submission) {
5991
- const { store } = this.client;
5992
- const { values, files } = separateFilesFromValues(submission.values);
5993
- const attachFilesPromises = this.getAttachFilesPromises(files, submission);
5994
- const offlineSubmission = {
5995
- ...submission,
5996
- values
5997
- };
5998
- const submissionToBeUpdated = selectFormSubmission(submission.offline_id)(store.getState());
5999
- if (!submissionToBeUpdated) {
6000
- throw new Error(`Expected submission with offline_id ${submission.offline_id} to exist`);
6001
- }
6002
- this.dispatch(updateFormSubmission(offlineSubmission));
6003
- const promise = this.enqueueRequest({
6004
- description: "Patch form submission",
6005
- method: HttpMethod.PATCH,
6006
- url: `/forms/submissions/${submission.offline_id}/`,
6007
- payload: offlineSubmission,
6008
- blockers: [offlineSubmission.issue, offlineSubmission.asset, offlineSubmission.asset_stage].filter(
6009
- (x) => x !== void 0
6010
- ),
6011
- blocks: [offlineSubmission.offline_id]
6012
- });
6013
- promise.then((createdSubmission) => {
6014
- this.dispatch(setFormSubmission(createdSubmission));
6015
- }).catch(() => {
6016
- this.dispatch(setFormSubmission(submissionToBeUpdated));
6017
- });
6018
- return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
6019
- }
6020
6048
  async delete(submissionId) {
6021
6049
  const { store } = this.client;
6022
6050
  const state = store.getState();