@overmap-ai/core 1.0.63-form-submission-fix.3 → 1.0.63-org-projs-only.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.
@@ -5360,23 +5360,17 @@ class ProjectService extends BaseApiService {
5360
5360
  * @throws An APIError if the server returns an error, or any other error that may occur.
5361
5361
  */
5362
5362
  async add(project) {
5363
- if (!project.organization_owner && !project.user_owner) {
5364
- throw new Error("Project type was not chosen when trying to create a project");
5365
- }
5366
5363
  if (!project.bounds && !project.canvas_bounds) {
5367
5364
  throw new Error("Project must either have bounds or canvas_bounds set");
5368
5365
  }
5369
- const isOrganizationProject = !!project.organization_owner;
5370
- const url = isOrganizationProject ? `/organizations/${project.organization_owner}/projects/` : "/projects/";
5371
- const projectType = isOrganizationProject ? { organization_owner: project.organization_owner } : { user_owner: project.user_owner };
5372
5366
  return await this.enqueueRequest({
5373
5367
  description: "Create project",
5374
5368
  method: HttpMethod.POST,
5375
- url,
5369
+ url: "/projects/",
5376
5370
  payload: {
5377
5371
  name: project.name,
5378
5372
  bounds: project.bounds,
5379
- ...projectType
5373
+ organization_owner: project.organization_owner
5380
5374
  },
5381
5375
  blockers: [],
5382
5376
  blocks: []
@@ -5503,67 +5497,36 @@ const separateImageFromFields = async (fields) => {
5503
5497
  }
5504
5498
  return { fields: newFields, images };
5505
5499
  };
5506
- class FormService extends BaseUploadService {
5507
- async bulkAddRevisionAttachments(revisionId, files) {
5508
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5509
- const createdBy = this.client.store.getState().userReducer.currentUser.id;
5510
- const filePayloads = {};
5511
- const offlineFormRevisionAttachments = [];
5512
- const attachmentPayloads = [];
5513
- for (const [fieldIdentifier, file] of Object.entries(files)) {
5514
- const sha1 = await hashFile(file);
5515
- if (!(sha1 in filePayloads)) {
5516
- filePayloads[sha1] = {
5517
- sha1,
5518
- file_type: file.type,
5519
- extension: file.name.split(".").pop(),
5520
- size: file.size
5500
+ class FormService extends BaseApiService {
5501
+ constructor() {
5502
+ super(...arguments);
5503
+ // Attach images to revision, after uploading them to S3
5504
+ __publicField(this, "getAttachImagePromises", (images, offlineRevisionId) => {
5505
+ return Object.entries(images).map(async ([key, image]) => {
5506
+ const sha1 = await hashFile(image);
5507
+ await this.client.files.addCache(image, sha1);
5508
+ const [fileProps] = await this.client.files.uploadFileToS3(sha1);
5509
+ const revisionAttachmentPayload = offline({
5510
+ ...fileProps,
5511
+ revision: offlineRevisionId,
5512
+ field_identifier: key
5513
+ });
5514
+ const attach = await this.enqueueRequest({
5515
+ description: "Attach image to form revision field",
5516
+ method: HttpMethod.POST,
5517
+ url: `/forms/revisions/${offlineRevisionId}/attachments/`,
5518
+ payload: revisionAttachmentPayload,
5519
+ blockers: [revisionAttachmentPayload.revision],
5520
+ blocks: [revisionAttachmentPayload.offline_id]
5521
+ });
5522
+ const offlinePayload = {
5523
+ ...revisionAttachmentPayload,
5524
+ file: URL.createObjectURL(image)
5521
5525
  };
5522
- await this.client.files.addCache(file, sha1);
5523
- }
5524
- const offlineFormRevisionAttachment = offline({
5525
- file: URL.createObjectURL(file),
5526
- file_type: file.type,
5527
- file_name: file.name,
5528
- file_sha1: sha1,
5529
- created_by: createdBy,
5530
- revision: revisionId,
5531
- submitted_at: submittedAt,
5532
- field_identifier: fieldIdentifier
5526
+ this.dispatch(addFormRevisionAttachment(offlinePayload));
5527
+ return attach;
5533
5528
  });
5534
- offlineFormRevisionAttachments.push(offlineFormRevisionAttachment);
5535
- const attachmentPayload = {
5536
- offline_id: offlineFormRevisionAttachment.offline_id,
5537
- name: file.name,
5538
- field_identifier: fieldIdentifier,
5539
- sha1
5540
- };
5541
- attachmentPayloads.push(attachmentPayload);
5542
- }
5543
- this.dispatch(addFormRevisionAttachments(offlineFormRevisionAttachments));
5544
- const promise = this.enqueueRequest({
5545
- description: "Attach files to form revision",
5546
- method: HttpMethod.POST,
5547
- url: `/forms/revisions/${revisionId}/attachments/bulk/`,
5548
- payload: {
5549
- submitted_at: submittedAt,
5550
- attachments: attachmentPayloads,
5551
- files: Object.values(filePayloads)
5552
- },
5553
- blockers: [revisionId],
5554
- blocks: offlineFormRevisionAttachments.map((attachment) => attachment.offline_id)
5555
5529
  });
5556
- promise.then((result) => {
5557
- this.processPresignedUrls(result.presigned_urls);
5558
- this.dispatch(updateFormRevisionAttachments(result.attachments));
5559
- }).catch(() => {
5560
- this.dispatch(
5561
- deleteFormRevisionAttachments(
5562
- offlineFormRevisionAttachments.map((attachment) => attachment.offline_id)
5563
- )
5564
- );
5565
- });
5566
- return [offlineFormRevisionAttachments, promise.then(({ attachments }) => attachments)];
5567
5530
  }
5568
5531
  async add(ownerId, form, initialRevision, urlPrefix) {
5569
5532
  const { fields, images } = await separateImageFromFields(initialRevision.fields);
@@ -5596,16 +5559,14 @@ class FormService extends BaseUploadService {
5596
5559
  blockers: [ownerId],
5597
5560
  blocks: [form.offline_id, offlineFormRevision.offline_id]
5598
5561
  });
5599
- const [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(
5600
- offlineFormRevision.offline_id,
5601
- images
5602
- );
5562
+ const attachImagesPromises = this.getAttachImagePromises(images, offlineFormRevision.offline_id);
5603
5563
  void formPromise.catch((e) => {
5604
5564
  this.dispatch(deleteForm(form.offline_id));
5605
5565
  this.dispatch(deleteFormRevision(offlineFormRevision.offline_id));
5606
5566
  throw e;
5607
5567
  });
5608
- return [form, offlineFormRevision, offlineFormRevisionAttachments, formPromise, attachmentsPromise];
5568
+ const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
5569
+ return [form, offlineFormRevision, formPromise, settledPromise];
5609
5570
  }
5610
5571
  addForOrganization(organizationId, initialRevision) {
5611
5572
  const state = this.client.store.getState();
@@ -5687,16 +5648,14 @@ class FormService extends BaseUploadService {
5687
5648
  blockers: [formId],
5688
5649
  blocks: [offlineRevision.offline_id]
5689
5650
  });
5690
- const [offlineFormRevisionAttachments, attachmentsPromise] = await this.bulkAddRevisionAttachments(
5691
- fullRevision.offline_id,
5692
- images
5693
- );
5651
+ const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
5694
5652
  void promise.then((result) => {
5695
5653
  this.dispatch(setFormRevision(result));
5696
5654
  }).catch(() => {
5697
5655
  this.dispatch(deleteFormRevision(fullRevision.offline_id));
5698
5656
  });
5699
- return [fullRevision, offlineFormRevisionAttachments, promise, attachmentsPromise];
5657
+ const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
5658
+ return [fullRevision, settledPromise];
5700
5659
  }
5701
5660
  async favorite(formId) {
5702
5661
  const { store } = this.client;
@@ -5859,71 +5818,46 @@ const separateFilesFromValues = (values) => {
5859
5818
  return { values: newValues, files };
5860
5819
  };
5861
5820
  class FormSubmissionService extends BaseUploadService {
5862
- async bulkAddSubmissionAttachments(submissionId, files) {
5863
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5864
- const createdBy = this.client.store.getState().userReducer.currentUser.id;
5865
- const filePayloads = {};
5866
- const offlineFormSubmissionAttachments = [];
5867
- const attachmentPayloads = [];
5868
- for (const [fieldIdentifier, filesArray] of Object.entries(files)) {
5869
- for (const file of filesArray) {
5870
- const sha1 = await hashFile(file);
5871
- if (!(sha1 in filePayloads)) {
5872
- filePayloads[sha1] = {
5873
- sha1,
5874
- file_type: file.type,
5875
- extension: file.name.split(".").pop(),
5876
- size: file.size
5877
- };
5821
+ constructor() {
5822
+ super(...arguments);
5823
+ // Attach files to submission, after uploading them to S3
5824
+ __publicField(this, "getAttachFilesPromises", (files, submission) => {
5825
+ return Object.entries(files).map(async ([key, fileArray]) => {
5826
+ const attachResults = [];
5827
+ for (const file of fileArray) {
5828
+ const sha1 = await hashFile(file);
5878
5829
  await this.client.files.addCache(file, sha1);
5830
+ const [fileProps] = await this.client.files.uploadFileToS3(sha1);
5831
+ const submissionAttachmentPayload = offline({
5832
+ ...fileProps,
5833
+ submission: submission.offline_id,
5834
+ field_identifier: key
5835
+ });
5836
+ const attach = await this.enqueueRequest({
5837
+ description: "Attach file to form submission",
5838
+ method: HttpMethod.POST,
5839
+ url: `/forms/submission/${submission.offline_id}/attachments/`,
5840
+ payload: submissionAttachmentPayload,
5841
+ blockers: [
5842
+ submission.asset,
5843
+ submission.asset_stage,
5844
+ submission.issue,
5845
+ submission.form_revision
5846
+ ].filter((x) => x !== void 0),
5847
+ blocks: [submissionAttachmentPayload.offline_id]
5848
+ });
5849
+ const offlinePayload = {
5850
+ ...submissionAttachmentPayload,
5851
+ file: URL.createObjectURL(file)
5852
+ };
5853
+ this.dispatch(addFormSubmissionAttachment(offlinePayload));
5854
+ attachResults.push(attach);
5879
5855
  }
5880
- const offlineFormSubmissionAttachment = offline({
5881
- file: URL.createObjectURL(file),
5882
- file_type: file.type,
5883
- file_name: file.name,
5884
- file_sha1: sha1,
5885
- created_by: createdBy,
5886
- submission: submissionId,
5887
- submitted_at: submittedAt,
5888
- field_identifier: fieldIdentifier
5889
- });
5890
- offlineFormSubmissionAttachments.push(offlineFormSubmissionAttachment);
5891
- const attachmentPayload = {
5892
- offline_id: offlineFormSubmissionAttachment.offline_id,
5893
- name: file.name,
5894
- sha1,
5895
- field_identifier: fieldIdentifier
5896
- };
5897
- attachmentPayloads.push(attachmentPayload);
5898
- }
5899
- }
5900
- this.dispatch(addFormSubmissionAttachments(offlineFormSubmissionAttachments));
5901
- const promise = this.enqueueRequest({
5902
- description: "Attach files to form submission",
5903
- method: HttpMethod.POST,
5904
- url: `/forms/submissions/${submissionId}/attachments/bulk/`,
5905
- payload: {
5906
- submitted_at: submittedAt,
5907
- attachments: attachmentPayloads,
5908
- files: Object.values(filePayloads)
5909
- },
5910
- blockers: [submissionId],
5911
- blocks: offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id)
5912
- });
5913
- promise.then((result) => {
5914
- this.processPresignedUrls(result.presigned_urls);
5915
- this.dispatch(updateFormSubmissionAttachments(result.attachments));
5916
- }).catch(() => {
5917
- this.dispatch(
5918
- deleteFormSubmissionAttachments(
5919
- offlineFormSubmissionAttachments.map((attachment) => attachment.offline_id)
5920
- )
5921
- );
5856
+ return attachResults;
5857
+ });
5922
5858
  });
5923
- return [offlineFormSubmissionAttachments, promise.then(({ attachments }) => attachments)];
5924
5859
  }
5925
- // Outer promise is for hashing and caching files for submission attachments
5926
- async add(payload) {
5860
+ add(payload) {
5927
5861
  const { store } = this.client;
5928
5862
  const state = store.getState();
5929
5863
  const activeProjectId = state.projectReducer.activeProjectId;
@@ -5931,12 +5865,12 @@ class FormSubmissionService extends BaseUploadService {
5931
5865
  throw new Error("Expected an active project");
5932
5866
  }
5933
5867
  const { values, files } = separateFilesFromValues(payload.values);
5934
- const offlineSubmission = offline({
5868
+ const offlineSubmission = {
5935
5869
  ...payload,
5936
5870
  values,
5937
5871
  created_by: state.userReducer.currentUser.id,
5938
5872
  submitted_at: (/* @__PURE__ */ new Date()).toISOString()
5939
- });
5873
+ };
5940
5874
  const promise = this.enqueueRequest({
5941
5875
  description: "Respond to form",
5942
5876
  method: HttpMethod.POST,
@@ -5945,22 +5879,20 @@ class FormSubmissionService extends BaseUploadService {
5945
5879
  blockers: [payload.issue, payload.asset, payload.asset_stage, "add-form-entry"].filter(
5946
5880
  (x) => x !== void 0
5947
5881
  ),
5948
- blocks: [offlineSubmission.offline_id]
5882
+ blocks: [payload.offline_id]
5949
5883
  });
5884
+ const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
5950
5885
  this.dispatch(addFormSubmission(offlineSubmission));
5951
- const [offlineFormSubmissionAttachments, attachmentsPromise] = await this.bulkAddSubmissionAttachments(
5952
- offlineSubmission.offline_id,
5953
- files
5954
- );
5955
- promise.then((result) => {
5886
+ void promise.then((result) => {
5956
5887
  this.dispatch(addActiveProjectFormSubmissionsCount(1));
5957
5888
  this.dispatch(setFormSubmission(result));
5958
5889
  return result;
5959
5890
  }).catch(() => {
5960
- this.dispatch(deleteFormSubmission(offlineSubmission.offline_id));
5891
+ this.dispatch(deleteFormSubmission(payload.offline_id));
5961
5892
  this.dispatch(addActiveProjectFormSubmissionsCount(-1));
5962
5893
  });
5963
- return [offlineSubmission, offlineFormSubmissionAttachments, promise, attachmentsPromise];
5894
+ const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
5895
+ return [offlineSubmission, settledPromise];
5964
5896
  }
5965
5897
  // Note currently the bulkAdd method is specific to form submissions for assets
5966
5898
  // TODO: adapt the support bulk adding to any model type
@@ -6061,6 +5993,36 @@ class FormSubmissionService extends BaseUploadService {
6061
5993
  });
6062
5994
  return batchPromises;
6063
5995
  }
5996
+ update(submission) {
5997
+ const { store } = this.client;
5998
+ const { values, files } = separateFilesFromValues(submission.values);
5999
+ const attachFilesPromises = this.getAttachFilesPromises(files, submission);
6000
+ const offlineSubmission = {
6001
+ ...submission,
6002
+ values
6003
+ };
6004
+ const submissionToBeUpdated = selectFormSubmission(submission.offline_id)(store.getState());
6005
+ if (!submissionToBeUpdated) {
6006
+ throw new Error(`Expected submission with offline_id ${submission.offline_id} to exist`);
6007
+ }
6008
+ this.dispatch(updateFormSubmission(offlineSubmission));
6009
+ const promise = this.enqueueRequest({
6010
+ description: "Patch form submission",
6011
+ method: HttpMethod.PATCH,
6012
+ url: `/forms/submissions/${submission.offline_id}/`,
6013
+ payload: offlineSubmission,
6014
+ blockers: [offlineSubmission.issue, offlineSubmission.asset, offlineSubmission.asset_stage].filter(
6015
+ (x) => x !== void 0
6016
+ ),
6017
+ blocks: [offlineSubmission.offline_id]
6018
+ });
6019
+ promise.then((createdSubmission) => {
6020
+ this.dispatch(setFormSubmission(createdSubmission));
6021
+ }).catch(() => {
6022
+ this.dispatch(setFormSubmission(submissionToBeUpdated));
6023
+ });
6024
+ return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
6025
+ }
6064
6026
  async delete(submissionId) {
6065
6027
  const { store } = this.client;
6066
6028
  const state = store.getState();
@@ -6531,9 +6493,7 @@ class LicenseService extends BaseApiService {
6531
6493
  method: HttpMethod.GET,
6532
6494
  url: `/billing/${license.offline_id}/`,
6533
6495
  isAuthNeeded: true,
6534
- blockers: [
6535
- license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6536
- ],
6496
+ blockers: [license.organization_owner ? license.organization_owner.toString() : ""],
6537
6497
  blocks: []
6538
6498
  });
6539
6499
  this.dispatch(updateLicense(result));
@@ -6545,9 +6505,7 @@ class LicenseService extends BaseApiService {
6545
6505
  method: HttpMethod.DELETE,
6546
6506
  url: `/billing/${license.offline_id}/suspend/`,
6547
6507
  isAuthNeeded: true,
6548
- blockers: [
6549
- license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6550
- ],
6508
+ blockers: [license.organization_owner ? license.organization_owner.toString() : ""],
6551
6509
  blocks: []
6552
6510
  });
6553
6511
  this.dispatch(updateLicense(result));
@@ -6559,9 +6517,7 @@ class LicenseService extends BaseApiService {
6559
6517
  method: HttpMethod.PATCH,
6560
6518
  url: `/billing/${license.offline_id}/suspend/`,
6561
6519
  isAuthNeeded: true,
6562
- blockers: [
6563
- license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6564
- ],
6520
+ blockers: [license.organization_owner ? license.organization_owner.toString() : ""],
6565
6521
  blocks: []
6566
6522
  });
6567
6523
  this.dispatch(updateLicense(result));
@@ -6573,9 +6529,7 @@ class LicenseService extends BaseApiService {
6573
6529
  method: HttpMethod.DELETE,
6574
6530
  url: `/billing/${license.offline_id}/`,
6575
6531
  isAuthNeeded: true,
6576
- blockers: [
6577
- license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6578
- ],
6532
+ blockers: [license.organization_owner ? license.organization_owner.toString() : ""],
6579
6533
  blocks: []
6580
6534
  });
6581
6535
  this.dispatch(updateLicense(result));
@@ -6589,7 +6543,7 @@ class LicenseService extends BaseApiService {
6589
6543
  isAuthNeeded: true,
6590
6544
  payload: { project: project.id },
6591
6545
  blockers: [
6592
- license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : "",
6546
+ license.organization_owner ? license.organization_owner.toString() : "",
6593
6547
  project.id ? project.id.toString() : ""
6594
6548
  ],
6595
6549
  blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
@@ -6603,9 +6557,7 @@ class LicenseService extends BaseApiService {
6603
6557
  method: HttpMethod.DELETE,
6604
6558
  url: `/billing/${license.offline_id}/project/`,
6605
6559
  isAuthNeeded: true,
6606
- blockers: [
6607
- license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6608
- ],
6560
+ blockers: [license.organization_owner ? license.organization_owner.toString() : ""],
6609
6561
  blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
6610
6562
  });
6611
6563
  this.dispatch(updateLicense(result));