@overmap-ai/core 1.0.63-form-submission-fix.0 → 1.0.63-form-submission-fix.2

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,66 @@ 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
+ files: Object.values(filePayloads)
5539
+ },
5540
+ blockers: [revisionId],
5541
+ blocks: offlineFormRevisionAttachments.map((attachment) => attachment.offline_id)
5542
+ });
5543
+ promise.then((result) => {
5544
+ this.processPresignedUrls(result.presigned_urls);
5545
+ this.dispatch(updateFormRevisionAttachments(result.attachments));
5546
+ }).catch(() => {
5547
+ this.dispatch(
5548
+ deleteFormRevisionAttachments(
5549
+ offlineFormRevisionAttachments.map((attachment) => attachment.offline_id)
5550
+ )
5551
+ );
5523
5552
  });
5553
+ return [offlineFormRevisionAttachments, promise.then(({ attachments }) => attachments)];
5524
5554
  }
5525
5555
  async add(ownerId, form, initialRevision, urlPrefix) {
5526
5556
  const { fields, images } = await separateImageFromFields(initialRevision.fields);
@@ -5553,14 +5583,16 @@ var __publicField = (obj, key, value) => {
5553
5583
  blockers: [ownerId],
5554
5584
  blocks: [form.offline_id, offlineFormRevision.offline_id]
5555
5585
  });
5556
- const attachImagesPromises = this.getAttachImagePromises(images, offlineFormRevision.offline_id);
5586
+ const [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(
5587
+ offlineFormRevision.offline_id,
5588
+ images
5589
+ );
5557
5590
  void formPromise.catch((e) => {
5558
5591
  this.dispatch(deleteForm(form.offline_id));
5559
5592
  this.dispatch(deleteFormRevision(offlineFormRevision.offline_id));
5560
5593
  throw e;
5561
5594
  });
5562
- const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
5563
- return [form, offlineFormRevision, formPromise, settledPromise];
5595
+ return [form, offlineFormRevision, offlineFormRevisionAttachments, formPromise, attachmentsPromise];
5564
5596
  }
5565
5597
  addForOrganization(organizationId, initialRevision) {
5566
5598
  const state = this.client.store.getState();
@@ -5642,14 +5674,16 @@ var __publicField = (obj, key, value) => {
5642
5674
  blockers: [formId],
5643
5675
  blocks: [offlineRevision.offline_id]
5644
5676
  });
5645
- const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
5677
+ const [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(
5678
+ fullRevision.offline_id,
5679
+ images
5680
+ );
5646
5681
  void promise.then((result) => {
5647
5682
  this.dispatch(setFormRevision(result));
5648
5683
  }).catch(() => {
5649
5684
  this.dispatch(deleteFormRevision(fullRevision.offline_id));
5650
5685
  });
5651
- const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
5652
- return [fullRevision, settledPromise];
5686
+ return [fullRevision, offlineFormRevisionAttachments, promise, attachmentsPromise];
5653
5687
  }
5654
5688
  async favorite(formId) {
5655
5689
  const { store } = this.client;
@@ -5812,46 +5846,70 @@ var __publicField = (obj, key, value) => {
5812
5846
  return { values: newValues, files };
5813
5847
  };
5814
5848
  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)
5849
+ async bulkAddSubmissionAttachments(submissionId, files) {
5850
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5851
+ const createdBy = this.client.store.getState().userReducer.currentUser.id;
5852
+ const filePayloads = {};
5853
+ const offlineFormSubmissionAttachments = [];
5854
+ const attachmentPayloads = [];
5855
+ for (const [fieldIdentifier, filesArray] of Object.entries(files)) {
5856
+ for (const file of filesArray) {
5857
+ const sha1 = await hashFile(file);
5858
+ if (!(sha1 in filePayloads)) {
5859
+ filePayloads[sha1] = {
5860
+ sha1,
5861
+ file_type: file.type,
5862
+ extension: file.name.split(".").pop(),
5863
+ size: file.size
5846
5864
  };
5847
- this.dispatch(addFormSubmissionAttachment(offlinePayload));
5848
- attachResults.push(attach);
5865
+ await this.client.files.addCache(file, sha1);
5849
5866
  }
5850
- return attachResults;
5851
- });
5867
+ const offlineFormSubmissionAttachment = offline({
5868
+ file: URL.createObjectURL(file),
5869
+ file_type: file.type,
5870
+ file_name: file.name,
5871
+ file_sha1: sha1,
5872
+ created_by: createdBy,
5873
+ submission: submissionId,
5874
+ submitted_at: submittedAt,
5875
+ field_identifier: fieldIdentifier
5876
+ });
5877
+ offlineFormSubmissionAttachments.push(offlineFormSubmissionAttachment);
5878
+ const attachmentPayload = {
5879
+ offline_id: offlineFormSubmissionAttachment.offline_id,
5880
+ name: file.name,
5881
+ sha1
5882
+ };
5883
+ attachmentPayloads.push(attachmentPayload);
5884
+ }
5885
+ }
5886
+ this.dispatch(addFormSubmissionAttachments(offlineFormSubmissionAttachments));
5887
+ const promise = this.enqueueRequest({
5888
+ description: "Attach files to form submission",
5889
+ method: HttpMethod.POST,
5890
+ url: `/forms/submissions/${submissionId}/attachments/bulk/`,
5891
+ payload: {
5892
+ submitted_at: submittedAt,
5893
+ attachments: attachmentPayloads,
5894
+ files: Object.values(filePayloads)
5895
+ },
5896
+ blockers: [submissionId],
5897
+ blocks: offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id)
5898
+ });
5899
+ promise.then((result) => {
5900
+ this.processPresignedUrls(result.presigned_urls);
5901
+ this.dispatch(updateFormSubmissionAttachments(result.attachments));
5902
+ }).catch(() => {
5903
+ this.dispatch(
5904
+ deleteFormSubmissionAttachments(
5905
+ offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id)
5906
+ )
5907
+ );
5852
5908
  });
5909
+ return [offlineFormSubmissionAttachments, promise.then(({ attachments }) => attachments)];
5853
5910
  }
5854
- add(payload) {
5911
+ // Outer promise is for hashing and caching files for submission attachments
5912
+ async add(payload) {
5855
5913
  const { store } = this.client;
5856
5914
  const state = store.getState();
5857
5915
  const activeProjectId = state.projectReducer.activeProjectId;
@@ -5875,9 +5933,12 @@ var __publicField = (obj, key, value) => {
5875
5933
  ),
5876
5934
  blocks: [offlineSubmission.offline_id]
5877
5935
  });
5878
- const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
5879
5936
  this.dispatch(addFormSubmission(offlineSubmission));
5880
- void promise.then((result) => {
5937
+ const [offlineFormSubmissionAttachments, attachmentsPromise] = await this.bulkAddSubmissionAttachments(
5938
+ offlineSubmission.offline_id,
5939
+ files
5940
+ );
5941
+ promise.then((result) => {
5881
5942
  this.dispatch(addActiveProjectFormSubmissionsCount(1));
5882
5943
  this.dispatch(setFormSubmission(result));
5883
5944
  return result;
@@ -5885,8 +5946,7 @@ var __publicField = (obj, key, value) => {
5885
5946
  this.dispatch(deleteFormSubmission(offlineSubmission.offline_id));
5886
5947
  this.dispatch(addActiveProjectFormSubmissionsCount(-1));
5887
5948
  });
5888
- const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
5889
- return [offlineSubmission, settledPromise];
5949
+ return [offlineSubmission, offlineFormSubmissionAttachments, promise, attachmentsPromise];
5890
5950
  }
5891
5951
  // Note currently the bulkAdd method is specific to form submissions for assets
5892
5952
  // TODO: adapt the support bulk adding to any model type
@@ -5987,36 +6047,6 @@ var __publicField = (obj, key, value) => {
5987
6047
  });
5988
6048
  return batchPromises;
5989
6049
  }
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
6050
  async delete(submissionId) {
6021
6051
  const { store } = this.client;
6022
6052
  const state = store.getState();