@overmap-ai/core 1.0.71-project-file-improvements.4 → 1.0.71-remove-login-timeout.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.
Files changed (131) hide show
  1. package/dist/constants/defaults.d.ts +2 -1
  2. package/dist/constants/index.d.ts +3 -3
  3. package/dist/enums/index.d.ts +5 -5
  4. package/dist/index.d.ts +6 -6
  5. package/dist/overmap-core.js +291 -452
  6. package/dist/overmap-core.js.map +1 -1
  7. package/dist/overmap-core.umd.cjs +300 -460
  8. package/dist/overmap-core.umd.cjs.map +1 -1
  9. package/dist/sdk/base.d.ts +8 -6
  10. package/dist/sdk/classes/OutboxCoordinator.d.ts +4 -4
  11. package/dist/sdk/classes/index.d.ts +1 -1
  12. package/dist/sdk/errors.d.ts +3 -1
  13. package/dist/sdk/globals.d.ts +7 -5
  14. package/dist/sdk/index.d.ts +6 -6
  15. package/dist/sdk/sdk.d.ts +6 -5
  16. package/dist/sdk/services/AgentService.d.ts +6 -10
  17. package/dist/sdk/services/AssetAttachmentService.d.ts +13 -12
  18. package/dist/sdk/services/AssetService.d.ts +5 -4
  19. package/dist/sdk/services/AssetStageCompletionService.d.ts +5 -4
  20. package/dist/sdk/services/AssetStageService.d.ts +5 -4
  21. package/dist/sdk/services/AssetTypeAttachmentService.d.ts +13 -12
  22. package/dist/sdk/services/AssetTypeService.d.ts +5 -4
  23. package/dist/sdk/services/BaseApiService.d.ts +5 -4
  24. package/dist/sdk/services/BaseAttachmentService.d.ts +7 -6
  25. package/dist/sdk/services/BaseAuthService.d.ts +5 -4
  26. package/dist/sdk/services/BaseService.d.ts +7 -5
  27. package/dist/sdk/services/BaseUploadService.d.ts +5 -4
  28. package/dist/sdk/services/CategoryService.d.ts +5 -4
  29. package/dist/sdk/services/DocumentAttachmentService.d.ts +13 -12
  30. package/dist/sdk/services/DocumentService.d.ts +5 -4
  31. package/dist/sdk/services/EmailDomainsService.d.ts +4 -3
  32. package/dist/sdk/services/EmailVerificationService.d.ts +4 -3
  33. package/dist/sdk/services/FileService.d.ts +5 -4
  34. package/dist/sdk/services/FormService.d.ts +5 -4
  35. package/dist/sdk/services/FormSubmissionService.d.ts +6 -5
  36. package/dist/sdk/services/GeoImageService.d.ts +5 -4
  37. package/dist/sdk/services/IssueAssociationService.d.ts +5 -4
  38. package/dist/sdk/services/IssueAttachmentService.d.ts +13 -12
  39. package/dist/sdk/services/IssueCommentService.d.ts +5 -4
  40. package/dist/sdk/services/IssueService.d.ts +5 -4
  41. package/dist/sdk/services/IssueTypeService.d.ts +5 -4
  42. package/dist/sdk/services/IssueUpdateService.d.ts +4 -3
  43. package/dist/sdk/services/JWTAuthService.d.ts +7 -6
  44. package/dist/sdk/services/LicenseService.d.ts +4 -3
  45. package/dist/sdk/services/OrganizationAccessService.d.ts +4 -3
  46. package/dist/sdk/services/OrganizationService.d.ts +4 -3
  47. package/dist/sdk/services/ProjectAccessService.d.ts +4 -3
  48. package/dist/sdk/services/ProjectAttachmentService.d.ts +13 -12
  49. package/dist/sdk/services/ProjectFileService.d.ts +9 -8
  50. package/dist/sdk/services/ProjectService.d.ts +4 -3
  51. package/dist/sdk/services/TeamService.d.ts +5 -4
  52. package/dist/sdk/services/UserService.d.ts +4 -3
  53. package/dist/sdk/services/WorkspaceService.d.ts +5 -4
  54. package/dist/sdk/services/index.d.ts +34 -34
  55. package/dist/sdk/typings.d.ts +9 -8
  56. package/dist/store/adapter.d.ts +12 -11
  57. package/dist/store/index.d.ts +2 -2
  58. package/dist/store/migrations.d.ts +2 -1
  59. package/dist/store/slices/agentsSlice.d.ts +11 -10
  60. package/dist/store/slices/assetAttachmentSlice.d.ts +16 -21
  61. package/dist/store/slices/assetSlice.d.ts +35 -24
  62. package/dist/store/slices/assetStageCompletionSlice.d.ts +33 -22
  63. package/dist/store/slices/assetStageSlice.d.ts +36 -25
  64. package/dist/store/slices/assetTypeAttachmentSlice.d.ts +16 -21
  65. package/dist/store/slices/assetTypeSlice.d.ts +16 -21
  66. package/dist/store/slices/authSlice.d.ts +10 -9
  67. package/dist/store/slices/categorySlice.d.ts +30 -16
  68. package/dist/store/slices/documentAttachmentSlice.d.ts +16 -21
  69. package/dist/store/slices/documentSlice.d.ts +30 -13
  70. package/dist/store/slices/emailDomainsSlice.d.ts +29 -15
  71. package/dist/store/slices/fileSlice.d.ts +7 -6
  72. package/dist/store/slices/formRevisionAttachmentSlice.d.ts +16 -21
  73. package/dist/store/slices/formRevisionSlice.d.ts +37 -26
  74. package/dist/store/slices/formSlice.d.ts +35 -21
  75. package/dist/store/slices/formSubmissionAttachmentSlice.d.ts +16 -21
  76. package/dist/store/slices/formSubmissionSlice.d.ts +16 -21
  77. package/dist/store/slices/geoImageSlice.d.ts +16 -21
  78. package/dist/store/slices/index.d.ts +38 -38
  79. package/dist/store/slices/issueAssociationSlice.d.ts +35 -24
  80. package/dist/store/slices/issueAttachmentSlice.d.ts +16 -21
  81. package/dist/store/slices/issueCommentSlice.d.ts +13 -18
  82. package/dist/store/slices/issueSlice.d.ts +13 -18
  83. package/dist/store/slices/issueTypeSlice.d.ts +12 -14
  84. package/dist/store/slices/issueUpdateSlice.d.ts +13 -18
  85. package/dist/store/slices/licenseSlice.d.ts +10 -9
  86. package/dist/store/slices/organizationAccessSlice.d.ts +11 -13
  87. package/dist/store/slices/organizationSlice.d.ts +27 -10
  88. package/dist/store/slices/outboxSlice.d.ts +15 -15
  89. package/dist/store/slices/projectAccessSlice.d.ts +11 -17
  90. package/dist/store/slices/projectAttachmentSlice.d.ts +16 -21
  91. package/dist/store/slices/projectFileSlice.d.ts +56 -44
  92. package/dist/store/slices/projectSlice.d.ts +10 -24
  93. package/dist/store/slices/rehydratedSlice.d.ts +7 -6
  94. package/dist/store/slices/teamSlice.d.ts +12 -14
  95. package/dist/store/slices/userSlice.d.ts +14 -13
  96. package/dist/store/slices/versioningSlice.d.ts +3 -2
  97. package/dist/store/slices/workspaceSlice.d.ts +31 -17
  98. package/dist/store/store.d.ts +7 -7
  99. package/dist/typings/index.d.ts +6 -6
  100. package/dist/typings/models/access.d.ts +3 -2
  101. package/dist/typings/models/agents.d.ts +3 -2
  102. package/dist/typings/models/assets.d.ts +3 -2
  103. package/dist/typings/models/attachments.d.ts +3 -2
  104. package/dist/typings/models/base.d.ts +3 -2
  105. package/dist/typings/models/categories.d.ts +3 -2
  106. package/dist/typings/models/documents.d.ts +2 -1
  107. package/dist/typings/models/emailDomain.d.ts +2 -1
  108. package/dist/typings/models/emailVerification.d.ts +3 -2
  109. package/dist/typings/models/forms.d.ts +4 -3
  110. package/dist/typings/models/geoImages.d.ts +5 -4
  111. package/dist/typings/models/index.d.ts +21 -21
  112. package/dist/typings/models/issueTypes.d.ts +3 -2
  113. package/dist/typings/models/issues.d.ts +7 -6
  114. package/dist/typings/models/license.d.ts +3 -2
  115. package/dist/typings/models/organizations.d.ts +2 -1
  116. package/dist/typings/models/projects.d.ts +5 -7
  117. package/dist/typings/models/store.d.ts +3 -3
  118. package/dist/typings/models/teams.d.ts +4 -3
  119. package/dist/typings/models/users.d.ts +2 -1
  120. package/dist/typings/models/workspace.d.ts +2 -1
  121. package/dist/typings/search.d.ts +1 -1
  122. package/dist/typings/store.d.ts +2 -1
  123. package/dist/utils/async/DeferredPromise.d.ts +1 -1
  124. package/dist/utils/colors.d.ts +2 -1
  125. package/dist/utils/coordinates.d.ts +3 -2
  126. package/dist/utils/file.d.ts +2 -1
  127. package/dist/utils/forms.d.ts +2 -1
  128. package/dist/utils/index.d.ts +10 -10
  129. package/dist/utils/offline.d.ts +2 -1
  130. package/dist/utils/utils.d.ts +2 -1
  131. package/package.json +18 -20
@@ -1,25 +1,21 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => {
4
- __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
- return value;
6
- };
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
7
4
  var _a;
8
5
  import { DepGraph } from "dependency-graph";
9
6
  import { v4 } from "uuid";
10
7
  import { saveAs } from "file-saver";
11
8
  import ColorCls from "color";
12
- import { gray, gold, brown, yellow, amber, orange, red, crimson, pink, plum, purple, violet, iris, indigo, blue, cyan, jade, grass, lime, mint, sky } from "@radix-ui/colors";
9
+ import { sky, mint, lime, grass, jade, cyan, blue, indigo, iris, violet, purple, plum, pink, crimson, red, orange, amber, yellow, brown, gold, gray } from "@radix-ui/colors";
10
+ import { createSlice, createSelector, combineReducers, compose } from "@reduxjs/toolkit";
13
11
  import { offline as offline$1 } from "@redux-offline/redux-offline";
14
12
  import offlineConfig from "@redux-offline/redux-offline/lib/defaults";
15
13
  import localforage from "localforage";
16
14
  import createMigration from "redux-persist-migrate";
17
- import { createSlice, createSelector, combineReducers } from "@reduxjs/toolkit";
18
15
  import request from "superagent";
19
16
  import { RESET_STATE } from "@redux-offline/redux-offline/lib/constants";
20
17
  import jwtDecode from "jwt-decode";
21
18
  import { openDB } from "idb";
22
- import { unsafeShowToast } from "@overmap-ai/blocks";
23
19
  var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
24
20
  HttpMethod2["GET"] = "GET";
25
21
  HttpMethod2["POST"] = "POST";
@@ -153,8 +149,7 @@ class OutboxCoordinator {
153
149
  return;
154
150
  }
155
151
  for (const node of this.graph.overallOrder()) {
156
- if (node === request2.payload.uuid)
157
- continue;
152
+ if (node === request2.payload.uuid) continue;
158
153
  const details = this.graph.getNodeData(node);
159
154
  if (request2.payload.blockers.some((blocker) => details.payload.blocks.includes(blocker))) {
160
155
  this._addDependency(request2.payload.uuid, node);
@@ -171,8 +166,7 @@ class OutboxCoordinator {
171
166
  insertRequest(request2) {
172
167
  this.graph.addNode(request2.payload.uuid, request2);
173
168
  for (const node of this.graph.overallOrder()) {
174
- if (node === request2.payload.uuid)
175
- continue;
169
+ if (node === request2.payload.uuid) continue;
176
170
  const details = this.graph.getNodeData(node);
177
171
  if (details.payload.blockers.some((blocker) => request2.payload.blocks.includes(blocker))) {
178
172
  this._addDependency(node, request2.payload.uuid);
@@ -208,8 +202,7 @@ class OutboxCoordinator {
208
202
  */
209
203
  peek() {
210
204
  const nextNode = this._getNextNode();
211
- if (!nextNode)
212
- return void 0;
205
+ if (!nextNode) return void 0;
213
206
  return this.graph.getNodeData(nextNode);
214
207
  }
215
208
  /**
@@ -285,13 +278,11 @@ function extractErrorMessage(errorRes, err) {
285
278
  try {
286
279
  ret = Object.entries(responseBody.body).map(([key, value]) => {
287
280
  if (typeof value === "string") {
288
- if (_SPECIAL_KEYS.includes(key))
289
- return value;
281
+ if (_SPECIAL_KEYS.includes(key)) return value;
290
282
  return `${key}: ${value}`;
291
283
  }
292
284
  if (Array.isArray(value)) {
293
- if (_SPECIAL_KEYS.includes(key))
294
- return value.join("\n");
285
+ if (_SPECIAL_KEYS.includes(key)) return value.join("\n");
295
286
  return value.map((v) => `${key}: ${v}`).join("\n");
296
287
  }
297
288
  return `${key}: ${JSON.stringify(value)}`;
@@ -359,11 +350,9 @@ const coordinatesAreEqual = (a, b) => {
359
350
  return a[0] === b[0] && a[1] === b[1];
360
351
  };
361
352
  const coordinatesToText = (coordinates, decimalPlaces) => {
362
- if (!coordinates)
363
- return "(No Location)";
353
+ if (!coordinates) return "(No Location)";
364
354
  const { lat, lng } = coordinatesToLiteral(coordinates);
365
- if (decimalPlaces)
366
- return `${lat.toFixed(decimalPlaces)}, ${lng.toFixed(decimalPlaces)}`;
355
+ if (decimalPlaces) return `${lat.toFixed(decimalPlaces)}, ${lng.toFixed(decimalPlaces)}`;
367
356
  return `${lat}, ${lng}`;
368
357
  };
369
358
  const coordinatesToUrlText = (coordinates) => {
@@ -416,7 +405,7 @@ function hashFile(file) {
416
405
  reader.onload = () => {
417
406
  const fileResult = reader.result;
418
407
  if (!fileResult) {
419
- reject();
408
+ reject(new Error("FileReader did not return a valid ArrayBuffer."));
420
409
  return;
421
410
  }
422
411
  void crypto.subtle.digest("SHA-1", fileResult).then((hash) => {
@@ -430,8 +419,7 @@ function hashFile(file) {
430
419
  function getFileIdentifier(file) {
431
420
  if (!file.name || !file.type || !file.size) {
432
421
  const message = "File has no name, type, and/or size";
433
- console.error(`${message}`, file);
434
- throw new Error(`${message}.`);
422
+ throw new Error(message);
435
423
  }
436
424
  return `${file.name}&${file.type}${file.size}`;
437
425
  }
@@ -553,21 +541,19 @@ const DEFAULT_ISSUE_PRIORITY = IssuePriority.MEDIUM;
553
541
  const OUTBOX_RETRY_DELAY = 6e4;
554
542
  const EMPTY_ARRAY = Object.freeze([]);
555
543
  let debug = false;
556
- const REACT_APP_DEBUG_MEMOIZATION = {}.REACT_APP_DEBUG_MEMOIZATION || "";
544
+ const REACT_APP_DEBUG_MEMOIZATION = "";
557
545
  if (["true", "1"].includes(REACT_APP_DEBUG_MEMOIZATION.toLowerCase())) {
558
546
  debug = true;
559
547
  }
560
548
  function shallowEqual(objA, objB) {
561
- if (objA === objB)
562
- return true;
549
+ if (objA === objB) return true;
563
550
  if (typeof objA !== typeof objB) {
564
551
  return false;
565
552
  }
566
553
  const keysA = Object.keys(objA);
567
554
  const keysB = Object.keys(objB);
568
555
  const keysALength = keysA.length;
569
- if (keysALength !== keysB.length)
570
- return false;
556
+ if (keysALength !== keysB.length) return false;
571
557
  for (let i = 0; i < keysALength; i++) {
572
558
  const key = keysA[i];
573
559
  if (!Object.prototype.hasOwnProperty.call(objB, key) || objA[key] !== objB[key]) {
@@ -594,11 +580,9 @@ function memoize(func) {
594
580
  };
595
581
  }
596
582
  function areArraysEqual(first, second) {
597
- if (first.length !== second.length)
598
- return false;
583
+ if (first.length !== second.length) return false;
599
584
  for (let i = 0; i < first.length; i++) {
600
- if (first[i] !== second[i])
601
- return false;
585
+ if (first[i] !== second[i]) return false;
602
586
  }
603
587
  return true;
604
588
  }
@@ -643,13 +627,11 @@ const generateBadgeColors = (rawColor) => {
643
627
  return { backgroundColor, textColor };
644
628
  };
645
629
  const getLocalDateString = memoize((date) => {
646
- if (!date)
647
- return "";
630
+ if (!date) return "";
648
631
  const asDate = new Date(date);
649
632
  const isThisYear = asDate.getFullYear() === today.getFullYear();
650
633
  const options = { day: "numeric", month: "short" };
651
- if (!isThisYear)
652
- options.year = "numeric";
634
+ if (!isThisYear) options.year = "numeric";
653
635
  return asDate.toLocaleDateString([], options);
654
636
  });
655
637
  const relative = new Intl.RelativeTimeFormat([], { style: "long", numeric: "auto" });
@@ -660,10 +642,10 @@ const isToday = (date) => {
660
642
  };
661
643
  const getLocalRelativeDateString = memoize((date, min, max) => {
662
644
  const days = Math.round((new Date(date).getTime() - today.getTime()) / msInDay);
663
- if (days < min || days > max)
664
- return getLocalDateString(date);
645
+ if (days < min || days > max) return getLocalDateString(date);
665
646
  return relative.format(days, "days");
666
647
  });
648
+ _a = Symbol.toStringTag;
667
649
  class DeferredPromise {
668
650
  constructor() {
669
651
  __publicField(this, _a, "Promise");
@@ -688,14 +670,12 @@ class DeferredPromise {
688
670
  return this._promise.catch(onRejected);
689
671
  }
690
672
  resolve(value) {
691
- if (!this._resolve)
692
- throw new Error("No resolve callback");
673
+ if (!this._resolve) throw new Error("No resolve callback");
693
674
  this._resolve(value);
694
675
  this._state = "fulfilled";
695
676
  }
696
677
  reject(reason) {
697
- if (!this._reject)
698
- throw reason;
678
+ if (!this._reject) throw reason;
699
679
  this._reject(reason);
700
680
  this._state = "rejected";
701
681
  }
@@ -703,35 +683,6 @@ class DeferredPromise {
703
683
  throw new Error("`finally` not implemented");
704
684
  }
705
685
  }
706
- _a = Symbol.toStringTag;
707
- var randomString = function randomString2() {
708
- return Math.random().toString(36).substring(7).split("").join(".");
709
- };
710
- ({
711
- INIT: "@@redux/INIT" + randomString(),
712
- REPLACE: "@@redux/REPLACE" + randomString(),
713
- PROBE_UNKNOWN_ACTION: function PROBE_UNKNOWN_ACTION() {
714
- return "@@redux/PROBE_UNKNOWN_ACTION" + randomString();
715
- }
716
- });
717
- function compose() {
718
- for (var _len = arguments.length, funcs = new Array(_len), _key = 0; _key < _len; _key++) {
719
- funcs[_key] = arguments[_key];
720
- }
721
- if (funcs.length === 0) {
722
- return function(arg) {
723
- return arg;
724
- };
725
- }
726
- if (funcs.length === 1) {
727
- return funcs[0];
728
- }
729
- return funcs.reduce(function(a, b) {
730
- return function() {
731
- return a(b.apply(void 0, arguments));
732
- };
733
- });
734
- }
735
686
  const VERSION_REDUCER_KEY$1 = "versioning";
736
687
  const latestVersion = () => migrations.length - 1;
737
688
  const initialVersioning = (state) => {
@@ -752,8 +703,7 @@ const wrapMigration = (migrator) => (state) => {
752
703
  if (state === void 0) {
753
704
  state = {};
754
705
  }
755
- if (((_a2 = state[VERSION_REDUCER_KEY$1]) == null ? void 0 : _a2.version) === latestVersion())
756
- return state;
706
+ if (((_a2 = state[VERSION_REDUCER_KEY$1]) == null ? void 0 : _a2.version) === latestVersion()) return state;
757
707
  return migrator(state);
758
708
  };
759
709
  const migrations = [initialVersioning, signOut, signOut, createOutboxState];
@@ -947,8 +897,7 @@ const selectAssetsByIds = restructureCreateSelectorWithArgs(
947
897
  const assets = [];
948
898
  for (const assetId of assetIds) {
949
899
  const asset = assetsMapping[assetId];
950
- if (asset)
951
- assets.push(asset);
900
+ if (asset) assets.push(asset);
952
901
  }
953
902
  return fallbackToEmptyArray(assets);
954
903
  })
@@ -1009,11 +958,11 @@ const selectAttachmentsOfAssetByType = restructureCreateSelectorWithArgs(
1009
958
  const attachmentsOfAsset = attachments.filter(({ asset }) => assetId === asset);
1010
959
  const fileAttachments = attachmentsOfAsset.filter(
1011
960
  // this null check here is necessary, there are cases where file_type is null or undefined
1012
- ({ file_type }) => !file_type || !file_type.startsWith("image/")
961
+ ({ file_type }) => !file_type.startsWith("image/")
1013
962
  );
1014
963
  const imageAttachments = attachmentsOfAsset.filter(
1015
964
  // this null check here is necessary, there are cases where file_type is null or undefined
1016
- ({ file_type }) => file_type && file_type.startsWith("image/")
965
+ ({ file_type }) => file_type.startsWith("image/")
1017
966
  );
1018
967
  return { fileAttachments, imageAttachments };
1019
968
  }
@@ -1056,8 +1005,7 @@ const selectCompletedStagesByAsset = createSelector(
1056
1005
  const completedStagesByAsset = {};
1057
1006
  for (const stageCompletion of Object.values(completedStagesMapping)) {
1058
1007
  const { asset, stage, submitted_at } = stageCompletion;
1059
- if (!completedStagesByAsset[asset])
1060
- completedStagesByAsset[asset] = {};
1008
+ if (!completedStagesByAsset[asset]) completedStagesByAsset[asset] = {};
1061
1009
  completedStagesByAsset[asset][stage] = submitted_at;
1062
1010
  }
1063
1011
  return completedStagesByAsset;
@@ -1281,11 +1229,11 @@ const selectAttachmentsOfAssetTypeByType = restructureCreateSelectorWithArgs(
1281
1229
  const attachmentsOfAssetType = attachments.filter(({ asset_type }) => asset_type === assetTypeId);
1282
1230
  const fileAttachments = attachmentsOfAssetType.filter(
1283
1231
  // this null check here is necessary, there are cases where file_type is null or undefined
1284
- ({ file_type }) => !file_type || !file_type.startsWith("image/")
1232
+ ({ file_type }) => !file_type.startsWith("image/")
1285
1233
  );
1286
1234
  const imageAttachments = attachmentsOfAssetType.filter(
1287
1235
  // this null check here is necessary, there are cases where file_type is null or undefined
1288
- ({ file_type }) => file_type && file_type.startsWith("image/")
1236
+ ({ file_type }) => file_type.startsWith("image/")
1289
1237
  );
1290
1238
  return { fileAttachments, imageAttachments };
1291
1239
  }
@@ -1422,8 +1370,7 @@ const selectUploadUrl = (sha1) => (state) => {
1422
1370
  }
1423
1371
  const today2 = (/* @__PURE__ */ new Date()).getTime();
1424
1372
  const expiringWithinAnHour = (url.exp ?? today2) - today2 < msPerHour;
1425
- if (expiringWithinAnHour)
1426
- return void 0;
1373
+ if (expiringWithinAnHour) return void 0;
1427
1374
  return url;
1428
1375
  };
1429
1376
  const fileReducer = fileSlice.reducer;
@@ -1452,8 +1399,7 @@ const userSlice = createSlice({
1452
1399
  state.currentUser = action.payload;
1453
1400
  },
1454
1401
  setProfilePicture: (state, action) => {
1455
- if (!state.currentUser)
1456
- return;
1402
+ if (!state.currentUser) return;
1457
1403
  state.currentUser.profile.file = action.payload.file ?? null;
1458
1404
  state.currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null;
1459
1405
  const currentUser = state.users[state.currentUser.id];
@@ -1587,13 +1533,6 @@ const selectProjectAccesses = createSelector(
1587
1533
  const selectProjectAccessById = (id) => (state) => {
1588
1534
  return state.projectAccessReducer.instances[id];
1589
1535
  };
1590
- const selectActiveProjectAccess = (state) => {
1591
- const currentUser = state.userReducer.currentUser;
1592
- const activeProjectId = state.projectReducer.activeProjectId;
1593
- return Object.values(state.projectAccessReducer.instances).find((projectAccess) => {
1594
- return projectAccess.user === (currentUser == null ? void 0 : currentUser.id) && projectAccess.project === activeProjectId;
1595
- }) ?? null;
1596
- };
1597
1536
  const selectProjectAccessForUser = (user) => (state) => {
1598
1537
  return Object.values(state.projectAccessReducer.instances).find(
1599
1538
  (projectAccess) => projectAccess.user === user.id
@@ -1608,8 +1547,7 @@ const selectProjectAccessUserMapping = (state) => {
1608
1547
  };
1609
1548
  const projectAccessReducer = projectAccessSlice.reducer;
1610
1549
  const initialState$m = {
1611
- projects: {},
1612
- activeProjectId: null
1550
+ projects: {}
1613
1551
  };
1614
1552
  const projectSlice = createSlice({
1615
1553
  name: "projects",
@@ -1623,19 +1561,9 @@ const projectSlice = createSlice({
1623
1561
  });
1624
1562
  state.projects = projectsMap;
1625
1563
  },
1626
- setActiveProjectId: (state, action) => {
1627
- state.activeProjectId = action.payload;
1628
- },
1629
- updateOrCreateProject: (state, action) => {
1564
+ updateProject: (state, action) => {
1630
1565
  state.projects[action.payload.id] = action.payload;
1631
1566
  },
1632
- // Takes a list of Projects and updates existing ones to match the payload, or adds them
1633
- // to the store if they are not already present
1634
- updateOrCreateProjects: (state, action) => {
1635
- action.payload.forEach((project) => {
1636
- state.projects[project.id] = project;
1637
- });
1638
- },
1639
1567
  deleteProject: (state, action) => {
1640
1568
  delete state.projects[action.payload.id];
1641
1569
  },
@@ -1645,50 +1573,12 @@ const projectSlice = createSlice({
1645
1573
  } else {
1646
1574
  throw new Error("Accept project invite: user is not in this project");
1647
1575
  }
1648
- },
1649
- addActiveProjectIssuesCount: (state, action) => {
1650
- if (!state.activeProjectId || !(state.activeProjectId in state.projects)) {
1651
- throw new Error("Update issues count: no active project");
1652
- }
1653
- if (!state.projects[state.activeProjectId].issues_count) {
1654
- state.projects[state.activeProjectId].issues_count = action.payload;
1655
- } else {
1656
- state.projects[state.activeProjectId].issues_count += action.payload;
1657
- }
1658
- },
1659
- addActiveProjectFormSubmissionsCount: (state, action) => {
1660
- if (state.activeProjectId && state.activeProjectId in state.projects) {
1661
- if (!state.projects[state.activeProjectId].form_submissions_count) {
1662
- state.projects[state.activeProjectId].form_submissions_count = action.payload;
1663
- } else {
1664
- state.projects[state.activeProjectId].form_submissions_count += action.payload;
1665
- }
1666
- } else {
1667
- throw new Error("Update form submissions count: no active project");
1668
- }
1669
1576
  }
1670
1577
  }
1671
1578
  });
1672
- const {
1673
- setProjects,
1674
- updateOrCreateProject,
1675
- updateOrCreateProjects: addOrReplaceProjects,
1676
- setActiveProjectId,
1677
- deleteProject,
1678
- acceptProjectInvite,
1679
- addActiveProjectIssuesCount,
1680
- addActiveProjectFormSubmissionsCount
1681
- } = projectSlice.actions;
1579
+ const { setProjects, updateProject, deleteProject, acceptProjectInvite } = projectSlice.actions;
1682
1580
  const projectReducer = projectSlice.reducer;
1683
1581
  const selectProjectMapping = (state) => state.projectReducer.projects;
1684
- const selectActiveProjectId = (state) => state.projectReducer.activeProjectId;
1685
- const selectActiveProject = (state) => {
1686
- const activeProjectId = selectActiveProjectId(state);
1687
- if (!activeProjectId) {
1688
- return null;
1689
- }
1690
- return state.projectReducer.projects[activeProjectId] ?? null;
1691
- };
1692
1582
  const selectProjectById = (id) => (state) => {
1693
1583
  return state.projectReducer.projects[id];
1694
1584
  };
@@ -1845,8 +1735,7 @@ const outboxSlice = createSlice({
1845
1735
  },
1846
1736
  markAsDeleted(state, action) {
1847
1737
  const index = state.deletedRequests.indexOf(action.payload);
1848
- if (index !== -1)
1849
- state.deletedRequests.splice(index, 1);
1738
+ if (index !== -1) state.deletedRequests.splice(index, 1);
1850
1739
  },
1851
1740
  _setLatestRetryTime: (state, action) => {
1852
1741
  state.latestRetryTime = action.payload;
@@ -1857,46 +1746,93 @@ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
1857
1746
  const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
1858
1747
  const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
1859
1748
  const outboxReducer = outboxSlice.reducer;
1860
- const projectFileAdapter = createModelAdapter((file) => file.offline_id);
1861
- const initialState$j = projectFileAdapter.getInitialState({});
1749
+ const initialState$j = {
1750
+ projectFiles: {},
1751
+ activeProjectFileId: null,
1752
+ isImportingProjectFile: false
1753
+ };
1862
1754
  const projectFileSlice = createSlice({
1863
1755
  name: "projectFiles",
1864
1756
  initialState: initialState$j,
1865
1757
  extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1866
1758
  reducers: {
1867
- initializeProjectFiles: projectFileAdapter.initialize,
1868
- addProjectFile: projectFileAdapter.addOne,
1869
- addProjectFiles: projectFileAdapter.addMany,
1870
- setProjectFile: projectFileAdapter.setOne,
1871
- setProjectFiles: projectFileAdapter.setMany,
1872
- updateProjectFile: projectFileAdapter.updateOne,
1873
- updateProjectFiles: projectFileAdapter.updateMany,
1874
- deleteProjectFile: projectFileAdapter.deleteOne,
1875
- deleteProjectFiles: projectFileAdapter.deleteMany
1759
+ addOrReplaceProjectFiles: (state, action) => {
1760
+ for (let fileObj of action.payload) {
1761
+ let file = fileObj.file;
1762
+ if (file.includes("+")) {
1763
+ console.warn("Attempting to apply fix for image URL with '+' character:", file);
1764
+ const parts = file.split("/");
1765
+ if (parts.length < 2) {
1766
+ throw new Error("Invalid URL: " + file);
1767
+ }
1768
+ const lastPart = encodeURIComponent(parts[parts.length - 1]);
1769
+ file = parts.slice(0, -1).join("/") + "/" + lastPart;
1770
+ console.warn("Fixed URL:", file);
1771
+ fileObj = { ...fileObj, file };
1772
+ }
1773
+ state.projectFiles[fileObj.offline_id] = fileObj;
1774
+ }
1775
+ },
1776
+ addOrReplaceProjectFile: (state, action) => {
1777
+ if (!action.payload.project) {
1778
+ throw new Error("ProjectFile has no project. A project must be set before storing.");
1779
+ }
1780
+ state.projectFiles[action.payload.offline_id] = action.payload;
1781
+ },
1782
+ setIsImportingProjectFile: (state, action) => {
1783
+ state.isImportingProjectFile = action.payload;
1784
+ },
1785
+ saveActiveProjectFileBounds: (state, action) => {
1786
+ const activeProjectFileId = state.activeProjectFileId;
1787
+ if (!activeProjectFileId) {
1788
+ throw new Error("Tried to save bounds for active project file, but no active project file was set.");
1789
+ }
1790
+ if (!state.projectFiles[activeProjectFileId]) {
1791
+ throw new Error(
1792
+ `Tried to save bounds for active project file, but project file with ID ${activeProjectFileId}
1793
+ doesn't exist.`
1794
+ );
1795
+ }
1796
+ state.projectFiles[activeProjectFileId].bounds = action.payload;
1797
+ },
1798
+ // TODO: Move to MapContext. Should not be persisted.
1799
+ setActiveProjectFileId: (state, action) => {
1800
+ state.activeProjectFileId = action.payload;
1801
+ },
1802
+ removeProjectFile: (state, action) => {
1803
+ delete state.projectFiles[action.payload];
1804
+ },
1805
+ removeProjectFilesOfProject: (state, action) => {
1806
+ const filesToDelete = Object.values(state.projectFiles).filter((file) => file.project === action.payload);
1807
+ for (const file of filesToDelete) {
1808
+ delete state.projectFiles[file.offline_id];
1809
+ }
1810
+ },
1811
+ resetProjectFileObjectUrls: (state, ..._args) => {
1812
+ for (const key in state.projectFiles) {
1813
+ delete state.projectFiles[key].objectURL;
1814
+ }
1815
+ }
1876
1816
  }
1877
1817
  });
1878
1818
  const {
1879
- initializeProjectFiles,
1880
- addProjectFile,
1881
- addProjectFiles,
1882
- setProjectFile,
1883
- setProjectFiles,
1884
- updateProjectFile,
1885
- updateProjectFiles,
1886
- deleteProjectFile,
1887
- deleteProjectFiles
1819
+ addOrReplaceProjectFiles,
1820
+ addOrReplaceProjectFile,
1821
+ setIsImportingProjectFile,
1822
+ setActiveProjectFileId,
1823
+ saveActiveProjectFileBounds,
1824
+ removeProjectFile,
1825
+ removeProjectFilesOfProject,
1826
+ resetProjectFileObjectUrls
1888
1827
  } = projectFileSlice.actions;
1889
- const selectProjectFileMapping = (state) => state.projectFileReducer.instances;
1890
- const selectProjectFiles = createSelector(
1891
- [selectProjectFileMapping, selectActiveProjectId],
1892
- (mapping, activeProjectId) => {
1893
- return fallbackToEmptyArray(
1894
- Object.values(mapping).filter((file) => file.project === activeProjectId).sort((a, b) => a.z_index - b.z_index)
1895
- );
1896
- }
1897
- );
1828
+ const selectProjectFileMapping = (state) => state.projectFileReducer.projectFiles;
1829
+ const selectProjectFiles = createSelector([selectProjectFileMapping], (mapping) => {
1830
+ return fallbackToEmptyArray(Object.values(mapping).sort((a, b) => a.z_index - b.z_index));
1831
+ });
1832
+ const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
1833
+ const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
1898
1834
  const selectProjectFileById = (id) => (state) => {
1899
- return state.projectFileReducer.instances[id];
1835
+ return state.projectFileReducer.projectFiles[id];
1900
1836
  };
1901
1837
  const projectFileReducer = projectFileSlice.reducer;
1902
1838
  const projectAttachmentAdapter = createModelAdapter((attachment) => attachment.offline_id);
@@ -1948,11 +1884,11 @@ const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(
1948
1884
  const attachmentsOfProject = attachments.filter(({ project }) => projectId === project);
1949
1885
  const fileAttachments = attachmentsOfProject.filter(
1950
1886
  // this null check here is necessary, there are cases where file_type is null or undefined
1951
- ({ file_type }) => !file_type || !file_type.startsWith("image/")
1887
+ ({ file_type }) => !file_type.startsWith("image/")
1952
1888
  );
1953
1889
  const imageAttachments = attachmentsOfProject.filter(
1954
1890
  // this null check here is necessary, there are cases where file_type is null or undefined
1955
- ({ file_type }) => file_type && file_type.startsWith("image/")
1891
+ ({ file_type }) => file_type.startsWith("image/")
1956
1892
  );
1957
1893
  return { fileAttachments, imageAttachments };
1958
1894
  }
@@ -2036,8 +1972,7 @@ const selectLatestFormRevisionOfForm = restructureCreateSelectorWithArgs(
2036
1972
  [selectFormRevisionMapping, (_state, formId) => formId],
2037
1973
  (revisions, formId) => {
2038
1974
  const revisionsOfForm = Object.values(revisions).filter((revision) => revision.form === formId);
2039
- if (revisionsOfForm.length === 0)
2040
- return void 0;
1975
+ if (revisionsOfForm.length === 0) return void 0;
2041
1976
  const sortedRevisions = revisionsOfForm.sort(formRevisionSortFn);
2042
1977
  const latestRevision = sortedRevisions[revisionsOfForm.length - 1];
2043
1978
  return revisions[latestRevision.offline_id];
@@ -2109,7 +2044,7 @@ const selectFilteredForms = restructureCreateSelectorWithArgs(
2109
2044
  return [...regularMatches.slice(0, maxResults)];
2110
2045
  },
2111
2046
  // as the argument is an object, we check the first level of properties for equality
2112
- { memoizeOptions: { equalityCheck: shallowEqual } }
2047
+ { memoizeOptions: { resultEqualityCheck: shallowEqual } }
2113
2048
  )
2114
2049
  );
2115
2050
  const selectFormById = (formId) => (state) => {
@@ -2188,8 +2123,7 @@ const selectFormSubmissionsOfForm = restructureCreateSelectorWithArgs(
2188
2123
  (submissionsMapping, revisionMapping, formId) => {
2189
2124
  const revisionIds = /* @__PURE__ */ new Set();
2190
2125
  for (const revision of Object.values(revisionMapping)) {
2191
- if (revision.form !== formId)
2192
- continue;
2126
+ if (revision.form !== formId) continue;
2193
2127
  revisionIds.add(revision.offline_id);
2194
2128
  }
2195
2129
  return Object.values(submissionsMapping).filter(
@@ -2256,8 +2190,7 @@ const selectAttachedFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(
2256
2190
  ],
2257
2191
  (issues, forms, formRevisions, submissions, issueId) => {
2258
2192
  const issue = issues[issueId];
2259
- if (!issue)
2260
- return [];
2193
+ if (!issue) return [];
2261
2194
  if (!issue.issue_type) {
2262
2195
  return Object.values(submissions).filter((submission) => submission.issue === issueId);
2263
2196
  }
@@ -2314,8 +2247,7 @@ const selectAttachedFormSubmissionsOfAsset = restructureCreateSelectorWithArgs(
2314
2247
  ],
2315
2248
  (assets, forms, formRevisions, submissions, assetId) => {
2316
2249
  const asset = assets[assetId];
2317
- if (!asset)
2318
- return [];
2250
+ if (!asset) return [];
2319
2251
  if (!asset.asset_type) {
2320
2252
  return Object.values(submissions).filter((submission) => submission.asset === assetId);
2321
2253
  }
@@ -2691,8 +2623,7 @@ const selectAncestorIdsOfDocument = restructureCreateSelectorWithArgs(
2691
2623
  createSelector([selectDocumentsMapping, (_state, documentId) => documentId], (mapping, documentId) => {
2692
2624
  const listOfAncestors = [];
2693
2625
  const document2 = mapping[documentId];
2694
- if (!document2 || !document2.parent_document)
2695
- return listOfAncestors;
2626
+ if (!document2 || !document2.parent_document) return listOfAncestors;
2696
2627
  let currentAncestor = mapping[document2.parent_document];
2697
2628
  while (currentAncestor) {
2698
2629
  listOfAncestors.push(currentAncestor.offline_id);
@@ -2758,11 +2689,11 @@ const selectAttachmentsOfDocumentByType = restructureCreateSelectorWithArgs(
2758
2689
  const attachmentsOfProject = attachments.filter(({ document: document2 }) => documentId === document2);
2759
2690
  const fileAttachments = attachmentsOfProject.filter(
2760
2691
  // this null check here is necessary, there are cases where file_type is null or undefined
2761
- ({ file_type }) => !file_type || !file_type.startsWith("image/")
2692
+ ({ file_type }) => !file_type.startsWith("image/")
2762
2693
  );
2763
2694
  const imageAttachments = attachmentsOfProject.filter(
2764
2695
  // this null check here is necessary, there are cases where file_type is null or undefined
2765
- ({ file_type }) => file_type && file_type.startsWith("image/")
2696
+ ({ file_type }) => file_type.startsWith("image/")
2766
2697
  );
2767
2698
  return { fileAttachments, imageAttachments };
2768
2699
  }
@@ -2968,11 +2899,11 @@ const selectAttachmentsOfIssueByType = restructureCreateSelectorWithArgs(
2968
2899
  const attachmentsOfIssue = attachments.filter(({ issue }) => issue === issueId);
2969
2900
  const fileAttachments = attachmentsOfIssue.filter(
2970
2901
  // this null check here is necessary, there are cases where file_type is null or undefined
2971
- ({ file_type }) => !file_type || !file_type.startsWith("image/")
2902
+ ({ file_type }) => !file_type.startsWith("image/")
2972
2903
  );
2973
2904
  const imageAttachments = attachmentsOfIssue.filter(
2974
2905
  // this null check here is necessary, there are cases where file_type is null or undefined
2975
- ({ file_type }) => file_type && file_type.startsWith("image/")
2906
+ ({ file_type }) => file_type.startsWith("image/")
2976
2907
  );
2977
2908
  return { fileAttachments, imageAttachments };
2978
2909
  }
@@ -3119,6 +3050,7 @@ class BaseService {
3119
3050
  async enqueueRequest(requestDetails) {
3120
3051
  return this.client.enqueueRequest(requestDetails, this.host, this.constructor.name);
3121
3052
  }
3053
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3122
3054
  dispatch(action) {
3123
3055
  this.client.store.dispatch(action);
3124
3056
  }
@@ -3188,9 +3120,8 @@ function getOutboxCoordinator() {
3188
3120
  __OUTBOX_COORDINATOR = coordinator;
3189
3121
  return coordinator;
3190
3122
  }
3191
- const persistCallback = (err) => {
3192
- if (err)
3193
- throw err;
3123
+ const persistCallback = (e) => {
3124
+ if (e) throw e;
3194
3125
  const clientStore2 = getClientStore();
3195
3126
  if (clientStore2) {
3196
3127
  clientStore2.dispatch({ type: "rehydrated/setRehydrated", payload: true });
@@ -3254,14 +3185,11 @@ function extractResponseFromError(error) {
3254
3185
  const knownKeys = ["ok", "redirect", "clientError", "serverError", "error"];
3255
3186
  return typeof response === "object" && response !== null && knownKeys.every((key) => key in response);
3256
3187
  }
3257
- if (isResponse(error))
3258
- return error;
3188
+ if (isResponse(error)) return error;
3259
3189
  if (typeof error === "object" && error !== null) {
3260
3190
  const typedError = error;
3261
- if (isResponse(typedError.response))
3262
- return typedError.response;
3263
- if (typedError.response && isResponse(typedError.response.response))
3264
- return typedError.response.response;
3191
+ if (isResponse(typedError.response)) return typedError.response;
3192
+ if (typedError.response && isResponse(typedError.response.response)) return typedError.response.response;
3265
3193
  }
3266
3194
  return void 0;
3267
3195
  }
@@ -3302,15 +3230,11 @@ async function performRequest(action, client) {
3302
3230
  const addPayload = (req) => {
3303
3231
  if (attachmentHash) {
3304
3232
  const s3url = requestDetails.s3url;
3305
- if (!s3url)
3306
- throw new Error(`No S3 URL for file ${attachmentHash}`);
3307
- if ("warning" in s3url)
3308
- throw new Error(`S3 URL warning for file ${attachmentHash}`);
3309
- if (!file)
3310
- throw new Error(`No file for file ${attachmentHash}`);
3233
+ if (!s3url) throw new Error(`No S3 URL for file ${attachmentHash}`);
3234
+ if ("warning" in s3url) throw new Error(`S3 URL warning for file ${attachmentHash}`);
3235
+ if (!file) throw new Error(`No file for file ${attachmentHash}`);
3311
3236
  const s3Sha1Checksum = s3url.fields["x-amz-checksum-sha1"];
3312
- if (!s3Sha1Checksum)
3313
- throw new Error(`No checksum for file ${attachmentHash}`);
3237
+ if (!s3Sha1Checksum) throw new Error(`No checksum for file ${attachmentHash}`);
3314
3238
  return req.set("x-amz-checksum-sha1", s3Sha1Checksum).field({ ...payload, ...s3url.fields }).attach("file", file);
3315
3239
  }
3316
3240
  return req.send(payload);
@@ -3370,8 +3294,7 @@ class MiddlewareChainerPrivate {
3370
3294
  this.compile = this.compile.bind(this);
3371
3295
  }
3372
3296
  then(next) {
3373
- if (this._previous)
3374
- this._previous.next = next;
3297
+ if (this._previous) this._previous.next = next;
3375
3298
  this._all.push(next);
3376
3299
  this._previous = next;
3377
3300
  return {
@@ -3399,11 +3322,9 @@ class OfflineMiddleware {
3399
3322
  } else {
3400
3323
  console.debug("Middleware finished. Performing request:", action);
3401
3324
  const clientStore2 = getClientStore();
3402
- if (!clientStore2)
3403
- throw new Error("Client store not set");
3325
+ if (!clientStore2) throw new Error("Client store not set");
3404
3326
  const clientSDK2 = getClientSDK();
3405
- if (!clientSDK2)
3406
- throw new Error("Client SDK not set");
3327
+ if (!clientSDK2) throw new Error("Client SDK not set");
3407
3328
  return performRequest(action, clientSDK2);
3408
3329
  }
3409
3330
  }
@@ -3424,20 +3345,6 @@ function runMiddleware(action) {
3424
3345
  return (_a2 = allMiddleware[0]) == null ? void 0 : _a2.run(action);
3425
3346
  }
3426
3347
  const discardStatuses = [400, 409, 403, 404, 405, 500];
3427
- const statusMessages = {
3428
- 403: { title: "Forbidden", description: "You are not authorized to perform this action.", accentColor: "red" },
3429
- 404: { title: "Not found", description: "The requested resource was not found.", accentColor: "red" },
3430
- 405: {
3431
- title: "Not supported",
3432
- description: "It's not you. It's us. Sorry for the inconvenience.",
3433
- accentColor: "red"
3434
- },
3435
- 500: {
3436
- title: "Server error",
3437
- description: "Our server seems to be experiencing problems at the moment. We have been alerted and will fix the problem as soon as possible.",
3438
- accentColor: "red"
3439
- }
3440
- };
3441
3348
  function discard(reason, action, retries = 0) {
3442
3349
  var _a2;
3443
3350
  console.debug(
@@ -3490,14 +3397,6 @@ function discard(reason, action, retries = 0) {
3490
3397
  }
3491
3398
  if (status !== void 0 && discardStatuses.includes(status)) {
3492
3399
  console.warn("Discarding request due to error:", reason, "\nAction:", action);
3493
- const message = statusMessages[status];
3494
- if (message) {
3495
- if (unsafeShowToast) {
3496
- unsafeShowToast(message);
3497
- } else {
3498
- console.error(`Could not display toast for status ${status} because there is no toast handle.`);
3499
- }
3500
- }
3501
3400
  const coordinator2 = getOutboxCoordinator();
3502
3401
  if (!coordinator2) {
3503
3402
  throw new Error("Outbox coordinator not set");
@@ -3525,6 +3424,7 @@ function retry(_action, _retries) {
3525
3424
  }
3526
3425
  class BaseSDK {
3527
3426
  constructor(store) {
3427
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3528
3428
  __publicField(this, "store");
3529
3429
  this.store = store;
3530
3430
  }
@@ -3560,9 +3460,13 @@ class BaseSDK {
3560
3460
  };
3561
3461
  performRequest(fullOfflineAction, this).then((result) => {
3562
3462
  promise.resolve(result.body);
3563
- }).catch((error) => {
3564
- discard(error, fullOfflineAction);
3565
- promise.reject(error);
3463
+ }).catch((e) => {
3464
+ discard(e, fullOfflineAction);
3465
+ if (e instanceof Error) {
3466
+ promise.reject(e);
3467
+ } else {
3468
+ promise.reject(new Error((e ?? UNKNOWN_ERROR_MESSAGE).toString()));
3469
+ }
3566
3470
  });
3567
3471
  } else {
3568
3472
  const innerPromise = this.store.dispatch(
@@ -3616,10 +3520,8 @@ class BaseAuthService extends BaseService {
3616
3520
  }
3617
3521
  const EXPIRING_SOON_THRESHOLD = 1800;
3618
3522
  function parseTokens(response) {
3619
- if (!response.access)
3620
- throw new Error("Missing access token");
3621
- if (!response.refresh)
3622
- throw new Error("Missing refresh token");
3523
+ if (!response.access) throw new Error("Missing access token");
3524
+ if (!response.refresh) throw new Error("Missing refresh token");
3623
3525
  return { accessToken: response.access, refreshToken: response.refresh };
3624
3526
  }
3625
3527
  class JWTService extends BaseAuthService {
@@ -3656,8 +3558,7 @@ class JWTService extends BaseAuthService {
3656
3558
  this.clearAuth();
3657
3559
  return void 0;
3658
3560
  }
3659
- if (!response.access)
3660
- throw new Error("Missing access token");
3561
+ if (!response.access) throw new Error("Missing access token");
3661
3562
  return { accessToken: response.access, refreshToken: response.refresh ?? this.getRefreshToken() };
3662
3563
  });
3663
3564
  }
@@ -3713,8 +3614,7 @@ class JWTService extends BaseAuthService {
3713
3614
  return `Bearer ${accessToken}`;
3714
3615
  }
3715
3616
  async prepareAuth() {
3716
- if (!this.tokenIsExpiringSoon())
3717
- return;
3617
+ if (!this.tokenIsExpiringSoon()) return;
3718
3618
  console.debug(this.constructor.name, "preparing auth");
3719
3619
  try {
3720
3620
  await this.renewTokens();
@@ -3722,7 +3622,11 @@ class JWTService extends BaseAuthService {
3722
3622
  if (e instanceof APIError) {
3723
3623
  this.clearAuth();
3724
3624
  }
3725
- return Promise.reject(e);
3625
+ if (e instanceof Error) {
3626
+ return Promise.reject(e);
3627
+ } else {
3628
+ return Promise.reject(new Error((e ?? UNKNOWN_ERROR_MESSAGE).toString()));
3629
+ }
3726
3630
  }
3727
3631
  }
3728
3632
  /* if not successfull in gracefully handling an unauthorized response, throw and APIError */
@@ -3753,7 +3657,7 @@ class JWTService extends BaseAuthService {
3753
3657
  async initAuth(payload) {
3754
3658
  const uuid = v4();
3755
3659
  console.debug(this.constructor.name, "Initiating auth");
3756
- const promise = this.enqueueRequest({
3660
+ return this.enqueueRequest({
3757
3661
  uuid,
3758
3662
  description: "Get token pair",
3759
3663
  method: HttpMethod.POST,
@@ -3761,25 +3665,12 @@ class JWTService extends BaseAuthService {
3761
3665
  payload,
3762
3666
  isAuthNeeded: false,
3763
3667
  checkAuth: false,
3668
+ immediate: true,
3764
3669
  blockers: [],
3765
3670
  blocks: []
3766
- }).then(parseTokens);
3767
- const timeout = 5;
3768
- let timedOut = false;
3769
- const timeoutPromise = new Promise((_, reject) => {
3770
- setTimeout(() => {
3771
- timedOut = true;
3772
- this.dispatch(markForDeletion(uuid));
3773
- reject(new APIError({ message: `Request timed out after ${timeout} seconds` }));
3774
- }, timeout * 1e3);
3775
- });
3776
- const successPromise = promise.then((tokens) => {
3777
- if (timedOut) {
3778
- return void 0;
3779
- }
3780
- this.setTokens(tokens);
3671
+ }).then((tokens) => {
3672
+ this.setTokens(parseTokens(tokens));
3781
3673
  });
3782
- return Promise.race([timeoutPromise, successPromise]);
3783
3674
  }
3784
3675
  }
3785
3676
  class BaseApiService extends BaseService {
@@ -3942,8 +3833,7 @@ class AssetService extends BaseApiService {
3942
3833
  const { store } = this.client;
3943
3834
  const state = store.getState();
3944
3835
  const assetToBeDeleted = selectAssetById(id)(state);
3945
- if (!assetToBeDeleted)
3946
- throw new Error(`No asset with id ${id} found in the store`);
3836
+ if (!assetToBeDeleted) throw new Error(`No asset with id ${id} found in the store`);
3947
3837
  const attachmentsOfAssets = selectAttachmentsOfAsset(id)(state);
3948
3838
  const formSubmissionsOfAssets = selectFormSubmissionsOfAsset(id)(state);
3949
3839
  const issueAssociations = selectIssueAssociationsOfAsset(id)(state);
@@ -3966,12 +3856,12 @@ class AssetService extends BaseApiService {
3966
3856
  url: `/assets/${id}/`,
3967
3857
  blockers: [id],
3968
3858
  blocks: []
3969
- }).catch((err) => {
3859
+ }).catch((e) => {
3970
3860
  this.dispatch(addAsset(assetToBeDeleted));
3971
3861
  this.dispatch(addAssetAttachments(attachmentsOfAssets));
3972
3862
  this.dispatch(addFormSubmissions(formSubmissionsOfAssets));
3973
3863
  this.dispatch(addIssueAssociations(issueAssociations));
3974
- throw err;
3864
+ throw e;
3975
3865
  });
3976
3866
  }
3977
3867
  bulkAdd(payloads, assetTypeId, batchSize) {
@@ -3995,8 +3885,7 @@ class AssetService extends BaseApiService {
3995
3885
  const { batchId, payload } = assetBatch;
3996
3886
  const batchAssetOfflineIds = payload.assets.map((c) => c.offline_id);
3997
3887
  const blockers = [assetTypeId];
3998
- if (prevBatchId)
3999
- blockers.push(prevBatchId);
3888
+ if (prevBatchId) blockers.push(prevBatchId);
4000
3889
  const blocks = batchAssetOfflineIds;
4001
3890
  blocks.push(batchId);
4002
3891
  const promise = this.enqueueRequest({
@@ -4210,8 +4099,7 @@ class AssetStageService extends BaseApiService {
4210
4099
  update(payload) {
4211
4100
  const { store } = this.client;
4212
4101
  const assetStage = selectAssetStageById(payload.offline_id)(store.getState());
4213
- if (!assetStage)
4214
- throw new Error(`No asset stage with id ${payload.offline_id} found in the store`);
4102
+ if (!assetStage) throw new Error(`No asset stage with id ${payload.offline_id} found in the store`);
4215
4103
  const updatedAssetStage = {
4216
4104
  ...assetStage,
4217
4105
  ...payload
@@ -4762,7 +4650,6 @@ class IssueService extends BaseApiService {
4762
4650
  created_by: createdBy
4763
4651
  });
4764
4652
  this.dispatch(addIssue(offlineIssue));
4765
- this.dispatch(addActiveProjectIssuesCount(1));
4766
4653
  const promise = this.enqueueRequest({
4767
4654
  description: "Create issue",
4768
4655
  method: HttpMethod.POST,
@@ -4779,7 +4666,6 @@ class IssueService extends BaseApiService {
4779
4666
  this.dispatch(updateIssue(result));
4780
4667
  }).catch((error) => {
4781
4668
  this.dispatch(deleteIssue(offlineIssue.offline_id));
4782
- this.dispatch(addActiveProjectIssuesCount(-1));
4783
4669
  throw error;
4784
4670
  });
4785
4671
  return [offlineIssue, promise];
@@ -4807,7 +4693,18 @@ class IssueService extends BaseApiService {
4807
4693
  ]) {
4808
4694
  if (issueUpdateChange in payload && payload[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {
4809
4695
  switch (issueUpdateChange) {
4810
- case "category": {
4696
+ case IssueUpdateChange.PRIORITY:
4697
+ case IssueUpdateChange.STATUS: {
4698
+ const val = payload[issueUpdateChange];
4699
+ changes[issueUpdateChange] = val !== void 0 ? Number(val) : null;
4700
+ break;
4701
+ }
4702
+ case IssueUpdateChange.DUE_DATE:
4703
+ case IssueUpdateChange.DESCRIPTION:
4704
+ case IssueUpdateChange.TITLE:
4705
+ changes[issueUpdateChange] = payload[issueUpdateChange] ?? null;
4706
+ break;
4707
+ case IssueUpdateChange.CATEGORY: {
4811
4708
  let categoryOrNull = null;
4812
4709
  const categoryIdOrNull = payload[issueUpdateChange];
4813
4710
  if (categoryIdOrNull) {
@@ -4824,7 +4721,7 @@ class IssueService extends BaseApiService {
4824
4721
  } : null;
4825
4722
  break;
4826
4723
  }
4827
- case "assigned_to": {
4724
+ case IssueUpdateChange.ASSIGNED_TO: {
4828
4725
  let userOrNull = null;
4829
4726
  const userIdOrNull = payload[issueUpdateChange];
4830
4727
  if (userIdOrNull) {
@@ -4840,20 +4737,6 @@ class IssueService extends BaseApiService {
4840
4737
  } : null;
4841
4738
  break;
4842
4739
  }
4843
- case "description":
4844
- changes[issueUpdateChange] = payload[issueUpdateChange] ?? null;
4845
- break;
4846
- case "title":
4847
- changes[issueUpdateChange] = payload[issueUpdateChange] ?? null;
4848
- break;
4849
- case "priority":
4850
- changes[issueUpdateChange] = payload[issueUpdateChange];
4851
- break;
4852
- case "status":
4853
- changes[issueUpdateChange] = payload[issueUpdateChange];
4854
- break;
4855
- case "due_date":
4856
- changes[issueUpdateChange] = payload[issueUpdateChange] ? payload[issueUpdateChange] : null;
4857
4740
  }
4858
4741
  }
4859
4742
  }
@@ -4895,7 +4778,6 @@ class IssueService extends BaseApiService {
4895
4778
  issueAssociationsRecord[issueAssociation.offline_id] = issueAssociation;
4896
4779
  const issueAssociations = Object.values(issueAssociationsRecord);
4897
4780
  this.dispatch(deleteIssue(id));
4898
- this.dispatch(addActiveProjectIssuesCount(-1));
4899
4781
  if (attachmentsOfIssue.length > 0)
4900
4782
  this.dispatch(deleteIssueAttachments(attachmentsOfIssue.map(({ offline_id }) => offline_id)));
4901
4783
  if (updatesOfIssue.length > 0)
@@ -4916,7 +4798,6 @@ class IssueService extends BaseApiService {
4916
4798
  this.dispatch(addIssue(backup));
4917
4799
  this.dispatch(addIssueAttachments(attachmentsOfIssue));
4918
4800
  this.dispatch(addIssueUpdates(updatesOfIssue));
4919
- this.dispatch(addActiveProjectIssuesCount(1));
4920
4801
  this.dispatch(addFormSubmissions(formSubmissionsOfIssue));
4921
4802
  this.dispatch(addIssueAssociations(issueAssociations));
4922
4803
  throw e;
@@ -5058,98 +4939,89 @@ class ProjectAccessService extends BaseApiService {
5058
4939
  this.dispatch(initializeProjectAccesses(result));
5059
4940
  }
5060
4941
  }
5061
- class ProjectFileService extends BaseUploadService {
5062
- async add(payload) {
5063
- var _a2;
5064
- const { store } = this.client;
5065
- const createdBy = (_a2 = store.getState().userReducer.currentUser) == null ? void 0 : _a2.id;
5066
- const { file, ...payloadWithoutFile } = payload;
5067
- const sha1 = await hashFile(file);
5068
- const filePayload = {
5069
- sha1,
5070
- file_type: file.type,
5071
- extension: file.name.split(".").pop(),
5072
- size: file.size
5073
- };
5074
- const offlineProjectFile = offline({
5075
- ...payloadWithoutFile,
5076
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5077
- created_by: createdBy,
5078
- file_name: file.name,
5079
- file_sha1: sha1,
5080
- file: URL.createObjectURL(file)
5081
- });
5082
- this.dispatch(addProjectFile(offlineProjectFile));
4942
+ class ProjectFileService extends BaseApiService {
4943
+ async saveExisting(file) {
4944
+ if (!file.offline_id) {
4945
+ throw new Error(
4946
+ "You can only use this method to save existing project files. The one provided has no offline_id."
4947
+ );
4948
+ }
4949
+ const editableData = { ...file };
4950
+ delete editableData.file;
5083
4951
  const promise = this.enqueueRequest({
5084
- description: "Add project file",
5085
- method: HttpMethod.POST,
5086
- url: `/projects/${payload.project}/files/`,
5087
- payload: {
5088
- offline_id: offlineProjectFile.offline_id,
5089
- submitted_at: offlineProjectFile.submitted_at,
5090
- z_index: offlineProjectFile.z_index,
5091
- canvas_bounds: offlineProjectFile.canvas_bounds,
5092
- bounds: offlineProjectFile.bounds,
5093
- file_name: offlineProjectFile.file_name,
5094
- file_sha1: offlineProjectFile.file_sha1,
5095
- file: offlineProjectFile.file,
5096
- file_payload: filePayload
5097
- },
5098
- blockers: [],
5099
- blocks: [offlineProjectFile.offline_id]
4952
+ method: HttpMethod.PATCH,
4953
+ url: `/projects/files/${file.offline_id}/`,
4954
+ payload: editableData,
4955
+ blockers: [file.offline_id],
4956
+ blocks: [file.offline_id]
5100
4957
  });
5101
- promise.then((result) => {
5102
- this.processPresignedUrls(result.presigned_urls);
5103
- this.dispatch(updateProjectFile(result.project_file));
5104
- }).catch(() => {
5105
- this.dispatch(deleteProjectFile(offlineProjectFile.offline_id));
4958
+ void promise.then((result) => {
4959
+ this.dispatch(addOrReplaceProjectFile(result));
5106
4960
  });
5107
- return [offlineProjectFile, promise.then((result) => result.project_file)];
4961
+ return promise;
5108
4962
  }
5109
- update(payload) {
4963
+ // TODO: This needs to be seperated into a update and create method
4964
+ saveActive() {
5110
4965
  const { store } = this.client;
5111
- const projectFile = selectProjectFileById(payload.offline_id)(store.getState());
5112
- if (!projectFile) {
5113
- throw new Error(`Project file with id ${payload.offline_id} not found`);
4966
+ const state = store.getState();
4967
+ const activeProjectFileId = state.projectFileReducer.activeProjectFileId;
4968
+ if (!activeProjectFileId) {
4969
+ throw new Error("No active project file");
4970
+ }
4971
+ const activeProjectFile = state.projectFileReducer.projectFiles[activeProjectFileId];
4972
+ if (!activeProjectFile) {
4973
+ throw new Error("No active project file");
4974
+ }
4975
+ if (!activeProjectFile.bounds && !activeProjectFile.canvas_bounds) {
4976
+ throw new Error("Project file must either have bounds or canvas_bounds set");
4977
+ }
4978
+ let requestDetails;
4979
+ const existing = typeof activeProjectFile.file === "string" && !activeProjectFile.file.startsWith("blob:");
4980
+ if (existing) {
4981
+ const editableData = { ...activeProjectFile };
4982
+ delete editableData.file;
4983
+ requestDetails = {
4984
+ method: HttpMethod.PATCH,
4985
+ url: `/projects/files/${activeProjectFileId}/`,
4986
+ payload: editableData,
4987
+ blockers: [activeProjectFileId],
4988
+ blocks: [activeProjectFileId]
4989
+ };
4990
+ } else {
4991
+ requestDetails = new Promise((resolve, reject) => {
4992
+ this.client.files.uploadFileToS3(activeProjectFile.file_sha1).then(([fileProps]) => {
4993
+ resolve({
4994
+ method: HttpMethod.POST,
4995
+ url: `/projects/${activeProjectFile.project}/files/`,
4996
+ payload: {
4997
+ ...activeProjectFile,
4998
+ ...fileProps
4999
+ },
5000
+ blockers: [activeProjectFileId],
5001
+ blocks: [activeProjectFileId]
5002
+ });
5003
+ }).catch(reject);
5004
+ });
5114
5005
  }
5115
- const updatedProjectFile = {
5116
- ...projectFile,
5117
- ...payload
5118
- };
5119
- this.dispatch(updateProjectFile(updatedProjectFile));
5120
- const promise = this.enqueueRequest({
5121
- description: "Update project file",
5122
- method: HttpMethod.PATCH,
5123
- url: `/projects/files/${payload.offline_id}/`,
5124
- payload,
5125
- blockers: [payload.offline_id],
5126
- blocks: [payload.offline_id]
5006
+ const promise = Promise.resolve(requestDetails).then((requestDetails2) => {
5007
+ return this.enqueueRequest(requestDetails2);
5127
5008
  });
5128
- promise.then((result) => {
5129
- this.dispatch(updateProjectFile(result));
5130
- }).catch(() => {
5131
- this.dispatch(updateProjectFile(projectFile));
5009
+ void promise.then((result) => {
5010
+ this.dispatch(addOrReplaceProjectFile(result));
5132
5011
  });
5133
- return [updatedProjectFile, promise];
5012
+ this.dispatch(saveActiveProjectFileBounds);
5013
+ this.dispatch(setActiveProjectFileId(null));
5014
+ this.dispatch(setIsImportingProjectFile(false));
5015
+ return [activeProjectFile, promise];
5134
5016
  }
5135
- delete(id) {
5136
- const { store } = this.client;
5137
- const projectFileToDelete = selectProjectFileById(id)(store.getState());
5138
- if (!projectFileToDelete) {
5139
- throw new Error(`Project file with id ${id} not found`);
5140
- }
5141
- this.dispatch(deleteProjectFile(id));
5142
- const promise = this.enqueueRequest({
5143
- description: "Delete project file",
5017
+ delete(projectFileId) {
5018
+ this.dispatch(removeProjectFile(projectFileId));
5019
+ return this.enqueueRequest({
5144
5020
  method: HttpMethod.DELETE,
5145
- url: `/projects/files/${id}/`,
5146
- blockers: [id],
5021
+ url: `/projects/files/${projectFileId}`,
5022
+ blockers: [projectFileId],
5147
5023
  blocks: []
5148
5024
  });
5149
- promise.catch(() => {
5150
- this.dispatch(updateProjectFile(projectFileToDelete));
5151
- });
5152
- return promise;
5153
5025
  }
5154
5026
  async refreshStore(projectId) {
5155
5027
  const result = await this.enqueueRequest({
@@ -5159,7 +5031,8 @@ class ProjectFileService extends BaseUploadService {
5159
5031
  blockers: [],
5160
5032
  blocks: []
5161
5033
  });
5162
- this.dispatch(initializeProjectFiles(result));
5034
+ this.dispatch(addOrReplaceProjectFiles([]));
5035
+ this.dispatch(addOrReplaceProjectFiles(result));
5163
5036
  }
5164
5037
  }
5165
5038
  class ProjectAttachmentService extends BaseAttachmentService {
@@ -5215,7 +5088,7 @@ class ProjectService extends BaseApiService {
5215
5088
  if (!project.bounds && !project.canvas_bounds) {
5216
5089
  throw new Error("Project must either have bounds or canvas_bounds set");
5217
5090
  }
5218
- this.dispatch(updateOrCreateProject(project));
5091
+ this.dispatch(updateProject(project));
5219
5092
  return await this.enqueueRequest({
5220
5093
  description: "Update project",
5221
5094
  method: HttpMethod.PATCH,
@@ -5236,8 +5109,8 @@ class ProjectService extends BaseApiService {
5236
5109
  if (!project) {
5237
5110
  throw new Error("Expected project to exist");
5238
5111
  }
5239
- const projectFiles = selectProjectFiles(state).filter((file) => file.project === projectId);
5240
- this.dispatch(deleteProjectFiles(projectFiles.map(({ offline_id }) => offline_id)));
5112
+ const filesToDelete = selectProjectFiles(state).filter((file) => file.project === projectId);
5113
+ this.dispatch(removeProjectFilesOfProject(project.id));
5241
5114
  const attachmentsOfProject = selectAttachmentsOfProject(project.id)(state);
5242
5115
  this.dispatch(deleteProjectAttachments(attachmentsOfProject.map(({ offline_id }) => offline_id)));
5243
5116
  const projectAccesses = selectProjectAccesses(state);
@@ -5260,7 +5133,7 @@ class ProjectService extends BaseApiService {
5260
5133
  } catch (e) {
5261
5134
  this.dispatch(setProjects(Object.values(projects)));
5262
5135
  this.dispatch(initializeProjectAccesses(Object.values(projectAccesses)));
5263
- this.dispatch(initializeProjectFiles(projectFiles));
5136
+ this.dispatch(addOrReplaceProjectFiles(filesToDelete));
5264
5137
  this.dispatch(setProjectAttachments(attachmentsOfProject));
5265
5138
  this.dispatch({ type: "rehydrated/setRehydrated", payload: true });
5266
5139
  if (license) {
@@ -5575,12 +5448,9 @@ class FormService extends BaseUploadService {
5575
5448
  blockers: [projectId.toString()],
5576
5449
  blocks: []
5577
5450
  });
5578
- for (const form of projectFormsResult.forms)
5579
- forms.push(form);
5580
- for (const revision of projectFormsResult.revisions)
5581
- revisions.push(revision);
5582
- for (const attachment of projectFormsResult.attachments)
5583
- attachments.push(attachment);
5451
+ for (const form of projectFormsResult.forms) forms.push(form);
5452
+ for (const revision of projectFormsResult.revisions) revisions.push(revision);
5453
+ for (const attachment of projectFormsResult.attachments) attachments.push(attachment);
5584
5454
  const organizationFormsResult = await this.enqueueRequest({
5585
5455
  description: "Fetch organization forms",
5586
5456
  method: HttpMethod.GET,
@@ -5588,12 +5458,9 @@ class FormService extends BaseUploadService {
5588
5458
  blockers: [projectId.toString()],
5589
5459
  blocks: []
5590
5460
  });
5591
- for (const form of organizationFormsResult.forms)
5592
- forms.push(form);
5593
- for (const revision of organizationFormsResult.revisions)
5594
- revisions.push(revision);
5595
- for (const attachment of organizationFormsResult.attachments)
5596
- attachments.push(attachment);
5461
+ for (const form of organizationFormsResult.forms) forms.push(form);
5462
+ for (const revision of organizationFormsResult.revisions) revisions.push(revision);
5463
+ for (const attachment of organizationFormsResult.attachments) attachments.push(attachment);
5597
5464
  const assetTypeFormsResult = await this.enqueueRequest({
5598
5465
  description: "Fetch asset type forms",
5599
5466
  method: HttpMethod.GET,
@@ -5601,12 +5468,9 @@ class FormService extends BaseUploadService {
5601
5468
  blockers: [projectId.toString()],
5602
5469
  blocks: []
5603
5470
  });
5604
- for (const form of assetTypeFormsResult.forms)
5605
- forms.push(form);
5606
- for (const revision of assetTypeFormsResult.revisions)
5607
- revisions.push(revision);
5608
- for (const attachment of assetTypeFormsResult.attachments)
5609
- attachments.push(attachment);
5471
+ for (const form of assetTypeFormsResult.forms) forms.push(form);
5472
+ for (const revision of assetTypeFormsResult.revisions) revisions.push(revision);
5473
+ for (const attachment of assetTypeFormsResult.attachments) attachments.push(attachment);
5610
5474
  const issueTypeFormsResult = await this.enqueueRequest({
5611
5475
  description: "Fetch issue type forms",
5612
5476
  method: HttpMethod.GET,
@@ -5614,12 +5478,9 @@ class FormService extends BaseUploadService {
5614
5478
  blockers: [projectId.toString()],
5615
5479
  blocks: []
5616
5480
  });
5617
- for (const form of issueTypeFormsResult.forms)
5618
- forms.push(form);
5619
- for (const revision of issueTypeFormsResult.revisions)
5620
- revisions.push(revision);
5621
- for (const attachment of issueTypeFormsResult.attachments)
5622
- attachments.push(attachment);
5481
+ for (const form of issueTypeFormsResult.forms) forms.push(form);
5482
+ for (const revision of issueTypeFormsResult.revisions) revisions.push(revision);
5483
+ for (const attachment of issueTypeFormsResult.attachments) attachments.push(attachment);
5623
5484
  this.dispatch(initializeForms(forms));
5624
5485
  this.dispatch(initializeFormRevisions(revisions));
5625
5486
  this.dispatch(initializeFormRevisionAttachments(attachments));
@@ -5755,12 +5616,10 @@ class FormSubmissionService extends BaseUploadService {
5755
5616
  files
5756
5617
  );
5757
5618
  promise.then((result) => {
5758
- this.dispatch(addActiveProjectFormSubmissionsCount(1));
5759
5619
  this.dispatch(setFormSubmission(result));
5760
5620
  return result;
5761
5621
  }).catch(() => {
5762
5622
  this.dispatch(deleteFormSubmission(offlineSubmission.offline_id));
5763
- this.dispatch(addActiveProjectFormSubmissionsCount(-1));
5764
5623
  });
5765
5624
  return [offlineSubmission, offlineFormSubmissionAttachments, promise, attachmentsPromise];
5766
5625
  }
@@ -5832,8 +5691,7 @@ class FormSubmissionService extends BaseUploadService {
5832
5691
  const batchSubmissionOfflineIds = payload.submissions.map((x) => x.offline_id);
5833
5692
  const batchAttachmentsOfflineIds = payload.attachments.map((x) => x.offline_id);
5834
5693
  const blockers = batchAssetIds;
5835
- if (prevBatchId)
5836
- blockers.push(prevBatchId);
5694
+ if (prevBatchId) blockers.push(prevBatchId);
5837
5695
  const blocks = [...batchSubmissionOfflineIds, ...batchAttachmentsOfflineIds, batchId];
5838
5696
  const promise = this.enqueueRequest({
5839
5697
  description: "Bulk add form submissions",
@@ -5853,10 +5711,8 @@ class FormSubmissionService extends BaseUploadService {
5853
5711
  const createdSubmissions = [];
5854
5712
  const createdAttachments = [];
5855
5713
  for (const result of results) {
5856
- for (const createdSubmission of result.submissions)
5857
- createdSubmissions.push(createdSubmission);
5858
- for (const createdAttachment of result.attachments)
5859
- createdAttachments.push(createdAttachment);
5714
+ for (const createdSubmission of result.submissions) createdSubmissions.push(createdSubmission);
5715
+ for (const createdAttachment of result.attachments) createdAttachments.push(createdAttachment);
5860
5716
  }
5861
5717
  this.dispatch(addFormSubmissions(createdSubmissions));
5862
5718
  this.dispatch(addFormSubmissionAttachments(createdAttachments));
@@ -5927,7 +5783,6 @@ class FormSubmissionService extends BaseUploadService {
5927
5783
  }
5928
5784
  const submissionAttachments = selectAttachmentsOfFormSubmission(id)(state);
5929
5785
  this.dispatch(deleteFormSubmission(id));
5930
- this.dispatch(addActiveProjectFormSubmissionsCount(-1));
5931
5786
  this.dispatch(deleteFormSubmissionAttachments(submissionAttachments.map((x) => x.offline_id)));
5932
5787
  try {
5933
5788
  return await this.enqueueRequest({
@@ -5938,7 +5793,6 @@ class FormSubmissionService extends BaseUploadService {
5938
5793
  blocks: []
5939
5794
  });
5940
5795
  } catch (e) {
5941
- this.dispatch(addActiveProjectFormSubmissionsCount(1));
5942
5796
  this.dispatch(addFormSubmission(submissionToBeDeleted));
5943
5797
  this.dispatch(addFormSubmissionAttachments(submissionAttachments));
5944
5798
  throw e;
@@ -6054,9 +5908,9 @@ class WorkspaceService extends BaseApiService {
6054
5908
  blockers: [id],
6055
5909
  blocks: []
6056
5910
  });
6057
- void promise.catch((reason) => {
5911
+ void promise.catch((e) => {
6058
5912
  this.dispatch(addWorkspace(originalWorkspace));
6059
- throw reason;
5913
+ throw e;
6060
5914
  });
6061
5915
  return promise;
6062
5916
  }
@@ -6117,7 +5971,7 @@ const summarizeEvery = 20;
6117
5971
  class FileService extends BaseApiService {
6118
5972
  constructor() {
6119
5973
  super(...arguments);
6120
- __publicField(this, "host", {}.REACT_APP_API_URL);
5974
+ __publicField(this, "host");
6121
5975
  // NOTE: If you alter the schema (of the IndexedDB database) in any way, you must increment the version in order to
6122
5976
  // migrate the store. This allows idb to automatically migrate the user's existing data to the new schema.
6123
5977
  __publicField(this, "_dbPromise", openDB("fileCache", 1, {
@@ -6128,8 +5982,7 @@ class FileService extends BaseApiService {
6128
5982
  }
6129
5983
  async renewUploadUrl(sha1) {
6130
5984
  const file = await this.fetchCache(sha1);
6131
- if (!file)
6132
- throw new Error(`File with sha1 ${sha1} not found in cache`);
5985
+ if (!file) throw new Error(`File with sha1 ${sha1} not found in cache`);
6133
5986
  const key = await getFileS3Key(file, sha1);
6134
5987
  const s3UploadUrl = await this.enqueueRequest({
6135
5988
  description: "Get S3 URL",
@@ -6199,8 +6052,7 @@ class FileService extends BaseApiService {
6199
6052
  /** Ensure the file has been added to the file cache before calling `uploadFileToS3()` */
6200
6053
  async uploadFileToS3(sha1) {
6201
6054
  const file = await this.fetchCache(sha1);
6202
- if (!file)
6203
- throw new Error(`File with sha1 ${sha1} not found in cache`);
6055
+ if (!file) throw new Error(`File with sha1 ${sha1} not found in cache`);
6204
6056
  const key = await getFileS3Key(file, sha1);
6205
6057
  const dbFileProperties = {
6206
6058
  file_name: file.name,
@@ -6294,7 +6146,7 @@ class FileService extends BaseApiService {
6294
6146
  isExternalUrl flag in the request details is set to true, because instead of requesting the local
6295
6147
  REST API, you will be requesting localhost:80 (where this app runs), resulting in a transformed blob
6296
6148
  (with an offline_id attached) being returned. Alternatively, you may be running with
6297
- true, which will result in some file requests being treated as
6149
+ import.meta.env.PROD, which will result in some file requests being treated as
6298
6150
  external URLs and therefore not prepended with VITE_API_URL.`;
6299
6151
  throw new Error(message);
6300
6152
  }
@@ -6815,15 +6667,14 @@ class DocumentAttachmentService extends BaseAttachmentService {
6815
6667
  }
6816
6668
  }
6817
6669
  class AgentService extends BaseApiService {
6818
- async startConversation(prompt) {
6819
- const activeProjectId = this.client.store.getState().projectReducer.activeProjectId;
6670
+ async startConversation(prompt, projectId) {
6820
6671
  return this.enqueueRequest({
6821
6672
  description: "Start agent conversation",
6822
6673
  method: HttpMethod.POST,
6823
6674
  url: "/agents/prompt/",
6824
6675
  payload: {
6825
6676
  prompt,
6826
- active_project: activeProjectId
6677
+ active_project: projectId
6827
6678
  },
6828
6679
  blockers: ["prompt"],
6829
6680
  blocks: ["prompt"]
@@ -6832,21 +6683,14 @@ class AgentService extends BaseApiService {
6832
6683
  return response;
6833
6684
  });
6834
6685
  }
6835
- /**
6836
- * Prompt the agent with a message.
6837
- * @param prompt The message to prompt the agent with.
6838
- * @param conversationId If continuing an existing message, the UUID of that conversation.
6839
- */
6840
- async continueConversation(prompt, conversationId) {
6841
- const { store } = this.client;
6842
- const activeProjectId = store.getState().projectReducer.activeProjectId;
6686
+ async continueConversation(prompt, conversationId, projectId) {
6843
6687
  return this.enqueueRequest({
6844
6688
  description: "Prompt agent",
6845
6689
  method: HttpMethod.POST,
6846
6690
  url: "/agents/prompt/",
6847
6691
  payload: {
6848
6692
  prompt,
6849
- active_project: activeProjectId
6693
+ active_project: projectId
6850
6694
  },
6851
6695
  blockers: ["prompt"],
6852
6696
  blocks: ["prompt"],
@@ -7341,6 +7185,7 @@ export {
7341
7185
  ProjectFileService,
7342
7186
  ProjectService,
7343
7187
  TeamService,
7188
+ UNKNOWN_ERROR_MESSAGE,
7344
7189
  UserService,
7345
7190
  VERSION_REDUCER_KEY,
7346
7191
  VerificationCodeType,
@@ -7349,8 +7194,6 @@ export {
7349
7194
  _selectLatestFormRevision,
7350
7195
  _setLatestRetryTime,
7351
7196
  acceptProjectInvite,
7352
- addActiveProjectFormSubmissionsCount,
7353
- addActiveProjectIssuesCount,
7354
7197
  addAsset,
7355
7198
  addAssetAttachment,
7356
7199
  addAssetAttachments,
@@ -7393,11 +7236,10 @@ export {
7393
7236
  addIssueUpdates,
7394
7237
  addIssues,
7395
7238
  addLicenses,
7396
- addOrReplaceProjects,
7239
+ addOrReplaceProjectFile,
7240
+ addOrReplaceProjectFiles,
7397
7241
  addProjectAttachment,
7398
7242
  addProjectAttachments,
7399
- addProjectFile,
7400
- addProjectFiles,
7401
7243
  addTeam,
7402
7244
  addUsers,
7403
7245
  addWorkspace,
@@ -7475,8 +7317,6 @@ export {
7475
7317
  deleteProjectAccesses,
7476
7318
  deleteProjectAttachment,
7477
7319
  deleteProjectAttachments,
7478
- deleteProjectFile,
7479
- deleteProjectFiles,
7480
7320
  deleteTeam,
7481
7321
  deleteWorkspace,
7482
7322
  dequeue,
@@ -7545,7 +7385,6 @@ export {
7545
7385
  initializeOrganizationAccesses,
7546
7386
  initializeProjectAccesses,
7547
7387
  initializeProjectAttachments,
7548
- initializeProjectFiles,
7549
7388
  initializeTeams,
7550
7389
  initializeWorkspaces,
7551
7390
  isToday,
@@ -7598,14 +7437,16 @@ export {
7598
7437
  rehydratedSlice,
7599
7438
  removeDocuments,
7600
7439
  removeIssueType,
7440
+ removeProjectFile,
7441
+ removeProjectFilesOfProject,
7601
7442
  removeUser,
7443
+ resetProjectFileObjectUrls,
7602
7444
  resetStore,
7603
7445
  restructureCreateSelectorWithArgs,
7446
+ saveActiveProjectFileBounds,
7604
7447
  selectAccessToken,
7605
7448
  selectActiveOrganizationAccess,
7606
- selectActiveProject,
7607
- selectActiveProjectAccess,
7608
- selectActiveProjectId,
7449
+ selectActiveProjectFileId,
7609
7450
  selectActiveStatusLicenses,
7610
7451
  selectAllDocumentAttachments,
7611
7452
  selectAllProjectAttachments,
@@ -7696,6 +7537,7 @@ export {
7696
7537
  selectGeoImageMapping,
7697
7538
  selectGeoImages,
7698
7539
  selectGeoImagesOfProject,
7540
+ selectIsImportingProjectFile,
7699
7541
  selectIsLoggedIn,
7700
7542
  selectIssueAssociationById,
7701
7543
  selectIssueAssociationMapping,
@@ -7778,7 +7620,7 @@ export {
7778
7620
  selectWorkspaceById,
7779
7621
  selectWorkspaceMapping,
7780
7622
  selectWorkspaces,
7781
- setActiveProjectId,
7623
+ setActiveProjectFileId,
7782
7624
  setAsset,
7783
7625
  setAssetAttachment,
7784
7626
  setAssetAttachments,
@@ -7804,6 +7646,7 @@ export {
7804
7646
  setFormSubmissions,
7805
7647
  setGeoImage,
7806
7648
  setGeoImages,
7649
+ setIsImportingProjectFile,
7807
7650
  setIssueAssociation,
7808
7651
  setIssueAssociations,
7809
7652
  setIssueAttachment,
@@ -7817,8 +7660,6 @@ export {
7817
7660
  setProfilePicture,
7818
7661
  setProjectAttachment,
7819
7662
  setProjectAttachments,
7820
- setProjectFile,
7821
- setProjectFiles,
7822
7663
  setProjects,
7823
7664
  setRehydrated,
7824
7665
  setTeam,
@@ -7868,13 +7709,11 @@ export {
7868
7709
  updateIssueAttachments,
7869
7710
  updateIssueType,
7870
7711
  updateLicense,
7871
- updateOrCreateProject,
7872
7712
  updateOrganizationAccess,
7713
+ updateProject,
7873
7714
  updateProjectAccess,
7874
7715
  updateProjectAttachment,
7875
7716
  updateProjectAttachments,
7876
- updateProjectFile,
7877
- updateProjectFiles,
7878
7717
  updateTeam,
7879
7718
  updateWorkspace,
7880
7719
  userReducer,