@overmap-ai/core 1.0.53-add-agent-sdk.0 → 1.0.53-attachment-creation-flows.0

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.
@@ -1567,6 +1567,9 @@ var __publicField = (obj, key, value) => {
1567
1567
  return Object.values(state.issueReducer.issues).filter((issue) => issue.category === categoryId).length;
1568
1568
  };
1569
1569
  const categoryReducer = categorySlice.reducer;
1570
+ function setAttachment(state, action) {
1571
+ state.attachments[action.payload.offline_id] = action.payload;
1572
+ }
1570
1573
  function setAttachments(state, action) {
1571
1574
  state.attachments = {};
1572
1575
  for (const attachment of action.payload) {
@@ -1591,6 +1594,15 @@ var __publicField = (obj, key, value) => {
1591
1594
  throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
1592
1595
  }
1593
1596
  }
1597
+ function updateAttachments(state, action) {
1598
+ for (const attachment of action.payload) {
1599
+ if (attachment.offline_id in state.attachments) {
1600
+ state.attachments[attachment.offline_id] = attachment;
1601
+ } else {
1602
+ throw new Error(`Attachment ${attachment.offline_id} does not exist.`);
1603
+ }
1604
+ }
1605
+ }
1594
1606
  function removeAttachment(state, action) {
1595
1607
  if (action.payload in state.attachments) {
1596
1608
  delete state.attachments[action.payload];
@@ -1624,12 +1636,6 @@ var __publicField = (obj, key, value) => {
1624
1636
  state.components = toOfflineIdRecord(action.payload);
1625
1637
  prevComponents = null;
1626
1638
  },
1627
- setComponentAttachments: setAttachments,
1628
- addComponentAttachment: addAttachment,
1629
- addComponentAttachments: addAttachments,
1630
- updateComponentAttachment: updateAttachment,
1631
- removeComponentAttachment: removeAttachment,
1632
- removeComponentAttachments: removeAttachments,
1633
1639
  updateComponent: (state, action) => {
1634
1640
  if (action.payload.offline_id in state.components) {
1635
1641
  state.components[action.payload.offline_id] = action.payload;
@@ -1654,9 +1660,35 @@ var __publicField = (obj, key, value) => {
1654
1660
  }
1655
1661
  }
1656
1662
  prevComponents = null;
1657
- }
1663
+ },
1664
+ // Attachments
1665
+ setComponentAttachment: setAttachment,
1666
+ setComponentAttachments: setAttachments,
1667
+ addComponentAttachment: addAttachment,
1668
+ addComponentAttachments: addAttachments,
1669
+ updateComponentAttachment: updateAttachment,
1670
+ updateComponentAttachments: updateAttachments,
1671
+ removeComponentAttachment: removeAttachment,
1672
+ removeComponentAttachments: removeAttachments
1658
1673
  }
1659
1674
  });
1675
+ const {
1676
+ addComponent,
1677
+ updateComponent,
1678
+ removeComponent,
1679
+ addComponentsInBatches,
1680
+ setComponents,
1681
+ removeAllComponentsOfType,
1682
+ // Attachments
1683
+ setComponentAttachment,
1684
+ setComponentAttachments,
1685
+ addComponentAttachment,
1686
+ addComponentAttachments,
1687
+ updateComponentAttachment,
1688
+ updateComponentAttachments,
1689
+ removeComponentAttachment,
1690
+ removeComponentAttachments
1691
+ } = componentSlice.actions;
1660
1692
  let prevComponents = null;
1661
1693
  const selectComponents = (state) => {
1662
1694
  if (!prevComponents) {
@@ -1751,20 +1783,6 @@ var __publicField = (obj, key, value) => {
1751
1783
  }
1752
1784
  )
1753
1785
  );
1754
- const {
1755
- addComponent,
1756
- updateComponent,
1757
- removeComponent,
1758
- addComponentsInBatches,
1759
- setComponents,
1760
- setComponentAttachments,
1761
- addComponentAttachment,
1762
- addComponentAttachments,
1763
- updateComponentAttachment,
1764
- removeComponentAttachment,
1765
- removeComponentAttachments,
1766
- removeAllComponentsOfType
1767
- } = componentSlice.actions;
1768
1786
  const componentReducer = componentSlice.reducer;
1769
1787
  const initialState$o = {
1770
1788
  completionsByComponentId: {}
@@ -1955,20 +1973,38 @@ var __publicField = (obj, key, value) => {
1955
1973
  setComponentTypes: (state, action) => {
1956
1974
  state.componentTypes = toOfflineIdRecord(action.payload);
1957
1975
  },
1958
- setComponentTypeAttachments: setAttachments,
1959
- addComponentTypeAttachment: addAttachment,
1960
- addComponentTypeAttachments: addAttachments,
1961
- updateComponentTypeAttachment: updateAttachment,
1962
- removeComponentTypeAttachment: removeAttachment,
1963
- removeComponentTypeAttachments: removeAttachments,
1964
1976
  toggleComponentTypeVisibility: (state, action) => {
1965
1977
  state.hiddenComponentTypeIds[action.payload] = !state.hiddenComponentTypeIds[action.payload];
1966
1978
  },
1967
1979
  deleteComponentType: (state, action) => {
1968
1980
  delete state.componentTypes[action.payload];
1969
- }
1981
+ },
1982
+ // Attachments
1983
+ setComponentTypeAttachment: setAttachment,
1984
+ setComponentTypeAttachments: setAttachments,
1985
+ addComponentTypeAttachment: addAttachment,
1986
+ addComponentTypeAttachments: addAttachments,
1987
+ updateComponentTypeAttachment: updateAttachment,
1988
+ updateComponentTypeAttachments: updateAttachments,
1989
+ removeComponentTypeAttachment: removeAttachment,
1990
+ removeComponentTypeAttachments: removeAttachments
1970
1991
  }
1971
1992
  });
1993
+ const {
1994
+ addComponentType,
1995
+ setComponentTypes,
1996
+ toggleComponentTypeVisibility,
1997
+ deleteComponentType,
1998
+ // Attachmet
1999
+ setComponentTypeAttachment,
2000
+ setComponentTypeAttachments,
2001
+ addComponentTypeAttachment,
2002
+ addComponentTypeAttachments,
2003
+ updateComponentTypeAttachment,
2004
+ updateComponentTypeAttachments,
2005
+ removeComponentTypeAttachment,
2006
+ removeComponentTypeAttachments
2007
+ } = componentTypeSlice.actions;
1972
2008
  const selectComponentTypesMapping = (state) => state.componentTypeReducer.componentTypes;
1973
2009
  const selectComponentTypes = toolkit.createSelector(
1974
2010
  [selectComponentTypesMapping],
@@ -2045,18 +2081,6 @@ var __publicField = (obj, key, value) => {
2045
2081
  }
2046
2082
  )
2047
2083
  );
2048
- const {
2049
- addComponentType,
2050
- setComponentTypes,
2051
- setComponentTypeAttachments,
2052
- addComponentTypeAttachment,
2053
- addComponentTypeAttachments,
2054
- updateComponentTypeAttachment,
2055
- removeComponentTypeAttachment,
2056
- removeComponentTypeAttachments,
2057
- toggleComponentTypeVisibility,
2058
- deleteComponentType
2059
- } = componentTypeSlice.actions;
2060
2084
  const componentTypeReducer = componentTypeSlice.reducer;
2061
2085
  const initialState$l = {
2062
2086
  workspaces: {},
@@ -2146,7 +2170,6 @@ var __publicField = (obj, key, value) => {
2146
2170
  state.issues[issue.offline_id] = issue;
2147
2171
  });
2148
2172
  },
2149
- setIssueAttachments: setAttachments,
2150
2173
  setIssueUpdates: (state, action) => {
2151
2174
  if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2152
2175
  throw new Error("Tried to use setIssues reducer with duplicate ID's");
@@ -2176,8 +2199,6 @@ var __publicField = (obj, key, value) => {
2176
2199
  state.issues[issue.offline_id] = issue;
2177
2200
  }
2178
2201
  },
2179
- addIssueAttachment: addAttachment,
2180
- addIssueAttachments: addAttachments,
2181
2202
  addIssueUpdate: (state, action) => {
2182
2203
  if (action.payload.offline_id in state.updates) {
2183
2204
  throw new Error(`Tried to add duplicate issue update with offline_id: ${action.payload.offline_id}`);
@@ -2199,7 +2220,6 @@ var __publicField = (obj, key, value) => {
2199
2220
  throw new Error(`Tried to update issue with ID that doesn't exist: ${action.payload.offline_id}`);
2200
2221
  }
2201
2222
  },
2202
- updateIssueAttachment: updateAttachment,
2203
2223
  removeIssue: (state, action) => {
2204
2224
  if (action.payload in state.issues) {
2205
2225
  delete state.issues[action.payload];
@@ -2212,7 +2232,6 @@ var __publicField = (obj, key, value) => {
2212
2232
  delete state.issues[issueId];
2213
2233
  }
2214
2234
  },
2215
- removeIssueAttachment: removeAttachment,
2216
2235
  removeIssueUpdate: (state, action) => {
2217
2236
  if (action.payload in state.updates) {
2218
2237
  delete state.updates[action.payload];
@@ -2309,12 +2328,19 @@ var __publicField = (obj, key, value) => {
2309
2328
  if (indexToRemove !== -1) {
2310
2329
  state.recentIssueIds.splice(indexToRemove, 1);
2311
2330
  }
2312
- }
2331
+ },
2332
+ // Attachments
2333
+ setIssueAttachment: setAttachment,
2334
+ setIssueAttachments: setAttachments,
2335
+ addIssueAttachment: addAttachment,
2336
+ addIssueAttachments: addAttachments,
2337
+ updateIssueAttachment: updateAttachment,
2338
+ updateIssueAttachments: updateAttachments,
2339
+ removeIssueAttachment: removeAttachment,
2340
+ removeIssueAttachments: removeAttachments
2313
2341
  }
2314
2342
  });
2315
2343
  const {
2316
- addIssueAttachment,
2317
- addIssueAttachments,
2318
2344
  addIssue,
2319
2345
  addIssues,
2320
2346
  addIssueUpdate,
@@ -2322,7 +2348,6 @@ var __publicField = (obj, key, value) => {
2322
2348
  addOrReplaceIssueComment,
2323
2349
  addToRecentIssues,
2324
2350
  cleanRecentIssues,
2325
- removeIssueAttachment,
2326
2351
  removeAttachmentsOfIssue,
2327
2352
  removeIssue,
2328
2353
  removeIssues,
@@ -2331,13 +2356,20 @@ var __publicField = (obj, key, value) => {
2331
2356
  removeRecentIssue,
2332
2357
  resetRecentIssues,
2333
2358
  setActiveIssueId,
2334
- setIssueAttachments,
2335
2359
  setIssueUpdates,
2336
2360
  setIssues,
2337
2361
  setVisibleStatuses,
2338
2362
  setVisibleUserIds,
2339
- updateIssueAttachment,
2340
2363
  updateIssue,
2364
+ // Attachments
2365
+ setIssueAttachment,
2366
+ setIssueAttachments,
2367
+ addIssueAttachment,
2368
+ addIssueAttachments,
2369
+ updateIssueAttachment,
2370
+ updateIssueAttachments,
2371
+ removeIssueAttachment,
2372
+ removeIssueAttachments,
2341
2373
  // Commments
2342
2374
  addIssueComment,
2343
2375
  addIssueComments,
@@ -2706,6 +2738,14 @@ var __publicField = (obj, key, value) => {
2706
2738
  OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
2707
2739
  return OrganizationAccessLevel2;
2708
2740
  })(OrganizationAccessLevel || {});
2741
+ var AttachmentModel = /* @__PURE__ */ ((AttachmentModel2) => {
2742
+ AttachmentModel2["Issue"] = "issue";
2743
+ AttachmentModel2["Component"] = "component";
2744
+ AttachmentModel2["ComponentType"] = "component_type";
2745
+ AttachmentModel2["Project"] = "project";
2746
+ AttachmentModel2["Document"] = "document";
2747
+ return AttachmentModel2;
2748
+ })(AttachmentModel || {});
2709
2749
  var IssueUpdateChange = /* @__PURE__ */ ((IssueUpdateChange2) => {
2710
2750
  IssueUpdateChange2["STATUS"] = "status";
2711
2751
  IssueUpdateChange2["PRIORITY"] = "priority";
@@ -3093,11 +3133,13 @@ var __publicField = (obj, key, value) => {
3093
3133
  throw new Error("Update form submissions count: no active project");
3094
3134
  }
3095
3135
  },
3096
- // Attachment related
3136
+ // Attachments
3137
+ setProjectAttachment: setAttachment,
3097
3138
  setProjectAttachments: setAttachments,
3098
3139
  addProjectAttachment: addAttachment,
3099
3140
  addProjectAttachments: addAttachments,
3100
3141
  updateProjectAttachment: updateAttachment,
3142
+ updateProjectAttachments: updateAttachments,
3101
3143
  removeProjectAttachment: removeAttachment,
3102
3144
  removeProjectAttachments: removeAttachments
3103
3145
  }
@@ -3112,11 +3154,13 @@ var __publicField = (obj, key, value) => {
3112
3154
  acceptProjectInvite,
3113
3155
  addActiveProjectIssuesCount,
3114
3156
  addActiveProjectFormSubmissionsCount,
3115
- // Attachment related
3157
+ // Attachments
3158
+ setProjectAttachment,
3116
3159
  setProjectAttachments,
3117
3160
  addProjectAttachment,
3118
3161
  addProjectAttachments,
3119
3162
  updateProjectAttachment,
3163
+ updateProjectAttachments,
3120
3164
  removeProjectAttachment,
3121
3165
  removeProjectAttachments
3122
3166
  } = projectSlice.actions;
@@ -3187,6 +3231,9 @@ var __publicField = (obj, key, value) => {
3187
3231
  [selectProjectAttachmentMapping],
3188
3232
  (mapping) => Object.values(mapping)
3189
3233
  );
3234
+ const selectProjectAttachment = (attachmentId) => (state) => {
3235
+ return state.projectReducer.attachments[attachmentId];
3236
+ };
3190
3237
  const selectAttachmentsOfProject = restructureCreateSelectorWithArgs(
3191
3238
  toolkit.createSelector(
3192
3239
  [selectAllProjectAttachments, (_state, projectId) => projectId],
@@ -4302,10 +4349,13 @@ var __publicField = (obj, key, value) => {
4302
4349
  delete state.documents[documentId];
4303
4350
  }
4304
4351
  },
4352
+ // Attachments
4353
+ setDocumentAttachment: setAttachment,
4305
4354
  setDocumentAttachments: setAttachments,
4306
4355
  addDocumentAttachment: addAttachment,
4307
4356
  addDocumentAttachments: addAttachments,
4308
4357
  updateDocumentAttachment: updateAttachment,
4358
+ updateDocumentAttachments: updateAttachments,
4309
4359
  removeDocumentAttachment: removeAttachment,
4310
4360
  removeDocumentAttachments: removeAttachments
4311
4361
  }
@@ -4316,10 +4366,13 @@ var __publicField = (obj, key, value) => {
4316
4366
  updateDocuments,
4317
4367
  moveDocument,
4318
4368
  removeDocuments,
4369
+ // Attachments
4370
+ setDocumentAttachment,
4319
4371
  setDocumentAttachments,
4320
4372
  addDocumentAttachment,
4321
4373
  addDocumentAttachments,
4322
4374
  updateDocumentAttachment,
4375
+ updateDocumentAttachments,
4323
4376
  removeDocumentAttachment,
4324
4377
  removeDocumentAttachments
4325
4378
  } = documentSlice.actions;
@@ -5009,553 +5062,6 @@ var __publicField = (obj, key, value) => {
5009
5062
  return promise;
5010
5063
  }
5011
5064
  }
5012
- class AttachmentService extends BaseApiService {
5013
- fetchAll(projectId) {
5014
- const promise = this.enqueueRequest({
5015
- description: "Fetch attachments",
5016
- method: HttpMethod.GET,
5017
- url: `/attachments/${projectId}/`,
5018
- blocks: [],
5019
- blockers: []
5020
- });
5021
- const state = this.client.store.getState();
5022
- const allAttachments = {
5023
- issue_attachments: Object.values(state.issueReducer.attachments),
5024
- component_attachments: Object.values(state.componentReducer.attachments),
5025
- component_type_attachments: Object.values(state.componentTypeReducer.attachments),
5026
- project_attachments: Object.values(state.projectReducer.attachments),
5027
- document_attachments: Object.values(state.documentsReducer.attachments)
5028
- };
5029
- return [allAttachments, promise];
5030
- }
5031
- // Attachments aren't models, so we use the OptimisticGenericResult type instead
5032
- async addIssueAttachment(attachmentPayload) {
5033
- const { issue, file_sha1, offline_id } = attachmentPayload;
5034
- if (!attachmentPayload.file.objectURL) {
5035
- throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
5036
- }
5037
- const offlineAttachment = {
5038
- ...attachmentPayload,
5039
- file: attachmentPayload.file.objectURL,
5040
- file_name: attachmentPayload.file.name,
5041
- file_type: attachmentPayload.file.type,
5042
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5043
- created_by: this.client.store.getState().userReducer.currentUser.id
5044
- };
5045
- await this.client.files.addCache(attachmentPayload.file, file_sha1);
5046
- this.client.store.dispatch(addIssueAttachment(offlineAttachment));
5047
- const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
5048
- const promise = this.enqueueRequest({
5049
- description: "Create attachment",
5050
- method: HttpMethod.POST,
5051
- url: `/issues/${issue}/attach/`,
5052
- blocks: [offline_id, issue],
5053
- blockers: [file_sha1],
5054
- payload: {
5055
- ...offlineAttachment,
5056
- ...fileProps
5057
- }
5058
- });
5059
- promise.catch((error2) => {
5060
- this.client.store.dispatch(removeIssueAttachment(offlineAttachment.offline_id));
5061
- throw error2;
5062
- });
5063
- return [offlineAttachment, promise];
5064
- }
5065
- async addComponentAttachment(attachmentPayload) {
5066
- const { component, file_sha1, offline_id } = attachmentPayload;
5067
- if (!attachmentPayload.file.objectURL) {
5068
- throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
5069
- }
5070
- const offlineAttachment = {
5071
- ...attachmentPayload,
5072
- file: attachmentPayload.file.objectURL,
5073
- file_name: attachmentPayload.file.name,
5074
- file_type: attachmentPayload.file.type,
5075
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5076
- created_by: this.client.store.getState().userReducer.currentUser.id
5077
- };
5078
- await this.client.files.addCache(attachmentPayload.file, file_sha1);
5079
- this.client.store.dispatch(addComponentAttachment(offlineAttachment));
5080
- const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
5081
- const promise = this.enqueueRequest({
5082
- description: "Create attachment",
5083
- method: HttpMethod.POST,
5084
- url: `/components/${component}/attach/`,
5085
- blocks: [offline_id, component],
5086
- blockers: [file_sha1],
5087
- payload: {
5088
- ...offlineAttachment,
5089
- ...fileProps
5090
- }
5091
- });
5092
- promise.catch((error2) => {
5093
- this.client.store.dispatch(removeComponentAttachment(offlineAttachment.offline_id));
5094
- throw error2;
5095
- });
5096
- return [offlineAttachment, promise];
5097
- }
5098
- async addComponentTypeAttachment(attachmentPayload) {
5099
- const { component_type, file_sha1, offline_id } = attachmentPayload;
5100
- if (!attachmentPayload.file.objectURL) {
5101
- throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
5102
- }
5103
- const offlineAttachment = {
5104
- ...attachmentPayload,
5105
- file: attachmentPayload.file.objectURL,
5106
- file_name: attachmentPayload.file.name,
5107
- file_type: attachmentPayload.file.type,
5108
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5109
- created_by: this.client.store.getState().userReducer.currentUser.id
5110
- };
5111
- await this.client.files.addCache(attachmentPayload.file, file_sha1);
5112
- this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
5113
- const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
5114
- const promise = this.enqueueRequest({
5115
- description: "Create attachment",
5116
- method: HttpMethod.POST,
5117
- url: `/components/types/${component_type}/attach/`,
5118
- blocks: [offline_id, component_type],
5119
- blockers: [file_sha1],
5120
- payload: {
5121
- ...offlineAttachment,
5122
- ...fileProps
5123
- }
5124
- });
5125
- promise.catch((error2) => {
5126
- this.client.store.dispatch(removeComponentTypeAttachment(offlineAttachment.offline_id));
5127
- throw error2;
5128
- });
5129
- return [offlineAttachment, promise];
5130
- }
5131
- async addDocumentAttachment(attachmentPayload) {
5132
- const { description: description2, document: document2, file_sha1, offline_id } = attachmentPayload;
5133
- if (!attachmentPayload.file.objectURL) {
5134
- throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
5135
- }
5136
- const offlineAttachment = {
5137
- ...attachmentPayload,
5138
- file: attachmentPayload.file.objectURL,
5139
- file_name: attachmentPayload.file.name,
5140
- file_type: attachmentPayload.file.type,
5141
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5142
- created_by: this.client.store.getState().userReducer.currentUser.id
5143
- };
5144
- await this.client.files.addCache(attachmentPayload.file, file_sha1);
5145
- this.client.store.dispatch(addDocumentAttachment(offlineAttachment));
5146
- const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
5147
- const promise = this.enqueueRequest({
5148
- description: "Create attachment",
5149
- method: HttpMethod.POST,
5150
- url: `/documents/${document2}/attach/`,
5151
- blocks: [offline_id, document2],
5152
- blockers: [file_sha1],
5153
- payload: {
5154
- offline_id,
5155
- document: document2,
5156
- description: description2 ?? "",
5157
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5158
- ...fileProps
5159
- }
5160
- });
5161
- promise.catch((error2) => {
5162
- this.client.store.dispatch(removeDocumentAttachment(offlineAttachment.offline_id));
5163
- throw error2;
5164
- });
5165
- return [offlineAttachment, promise];
5166
- }
5167
- /** the outer Promise is needed to await the hashing of each file, which is required before offline use. If wanting to
5168
- * attach promise handlers to the request to add the attachment in the backend, apply it on the promise returned from the
5169
- * OptimisticModelResult. */
5170
- attachFilesToIssue(filesToSubmit, issueId) {
5171
- return filesToSubmit.map((file) => {
5172
- if (!(file instanceof File)) {
5173
- throw new Error("Expected a File instance.");
5174
- }
5175
- const photoAttachmentPromise = async (file2) => {
5176
- const hash = await hashFile(file2);
5177
- const attachment = offline({
5178
- file: file2,
5179
- file_name: file2.name,
5180
- file_type: file2.type,
5181
- issue: issueId,
5182
- file_sha1: hash,
5183
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5184
- created_by: this.client.store.getState().userReducer.currentUser.id
5185
- });
5186
- return this.addIssueAttachment(attachment);
5187
- };
5188
- return photoAttachmentPromise(file);
5189
- });
5190
- }
5191
- attachFilesToComponent(filesToSubmit, componentId) {
5192
- return filesToSubmit.map((file) => {
5193
- if (!(file instanceof File)) {
5194
- throw new Error("Expected a File instance.");
5195
- }
5196
- const photoAttachmentPromise = async (file2) => {
5197
- const hash = await hashFile(file2);
5198
- const attachment = offline({
5199
- file: file2,
5200
- file_name: file2.name,
5201
- file_type: file2.type,
5202
- component: componentId,
5203
- file_sha1: hash,
5204
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5205
- created_by: this.client.store.getState().userReducer.currentUser.id
5206
- });
5207
- return this.addComponentAttachment(attachment);
5208
- };
5209
- return photoAttachmentPromise(file);
5210
- });
5211
- }
5212
- attachFilesToComponentType(filesToSubmit, componentTypeId) {
5213
- return filesToSubmit.map((file) => {
5214
- if (!(file instanceof File)) {
5215
- throw new Error("Expected a File instance.");
5216
- }
5217
- const photoAttachmentPromise = async (file2) => {
5218
- const hash = await hashFile(file2);
5219
- const attachment = offline({
5220
- file: file2,
5221
- file_name: file2.name,
5222
- file_type: file2.type,
5223
- component_type: componentTypeId,
5224
- file_sha1: hash,
5225
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5226
- created_by: this.client.store.getState().userReducer.currentUser.id
5227
- });
5228
- return this.addComponentTypeAttachment(attachment);
5229
- };
5230
- return photoAttachmentPromise(file);
5231
- });
5232
- }
5233
- attachFilesToDocument(filesToSubmit, documentId) {
5234
- return filesToSubmit.map((file) => {
5235
- if (!(file instanceof File)) {
5236
- throw new Error("Expected a File instance.");
5237
- }
5238
- const photoAttachmentPromise = async (file2) => {
5239
- const hash = await hashFile(file2);
5240
- const attachment = offline({
5241
- file: file2,
5242
- file_name: file2.name,
5243
- file_type: file2.type,
5244
- document: documentId,
5245
- file_sha1: hash,
5246
- submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
5247
- created_by: this.client.store.getState().userReducer.currentUser.id
5248
- });
5249
- return this.addDocumentAttachment(attachment);
5250
- };
5251
- return photoAttachmentPromise(file);
5252
- });
5253
- }
5254
- async replaceIssueAttachmentFile(attachmentId, newFile) {
5255
- const { store } = this.client;
5256
- const attachment = store.getState().issueReducer.attachments[attachmentId];
5257
- if (!attachment)
5258
- throw new Error(`Attachment ${attachmentId} not found`);
5259
- let oldFile = void 0;
5260
- const newSha1 = await hashFile(newFile);
5261
- const performRequest2 = async () => {
5262
- oldFile = await this.client.files.fetchCache(attachment.file_sha1);
5263
- if (!oldFile) {
5264
- console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
5265
- }
5266
- if (!newFile.objectURL) {
5267
- throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
5268
- }
5269
- store.dispatch(
5270
- updateIssueAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) })
5271
- );
5272
- await this.client.files.addCache(newFile, newSha1);
5273
- const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
5274
- store.dispatch(updateIssueAttachment(attachment));
5275
- throw e;
5276
- });
5277
- const promise2 = this.enqueueRequest({
5278
- description: "Edit attachment",
5279
- method: HttpMethod.PATCH,
5280
- url: `/attachments/issues/${attachment.offline_id}/`,
5281
- isResponseBlob: false,
5282
- payload: fileProps,
5283
- blockers: [attachmentId, newSha1],
5284
- blocks: [attachmentId, newSha1]
5285
- });
5286
- try {
5287
- const result = await promise2;
5288
- void this.client.files.removeCache(attachment.file_sha1);
5289
- return result;
5290
- } catch (e) {
5291
- if (oldFile) {
5292
- store.dispatch(
5293
- updateIssueAttachment({
5294
- ...attachment,
5295
- file_sha1: attachment.file_sha1,
5296
- file: URL.createObjectURL(oldFile)
5297
- })
5298
- );
5299
- }
5300
- throw e;
5301
- }
5302
- };
5303
- const offlineAttachment = {
5304
- ...attachment,
5305
- file_sha1: newSha1,
5306
- file: URL.createObjectURL(newFile)
5307
- };
5308
- const promise = performRequest2();
5309
- return [offlineAttachment, promise];
5310
- }
5311
- async replaceComponentAttachmentFile(attachmentId, newFile) {
5312
- const { store } = this.client;
5313
- const attachment = store.getState().componentReducer.attachments[attachmentId];
5314
- if (!attachment)
5315
- throw new Error(`Attachment ${attachmentId} not found`);
5316
- let oldFile = void 0;
5317
- const newSha1 = await hashFile(newFile);
5318
- const performRequest2 = async () => {
5319
- oldFile = await this.client.files.fetchCache(attachment.file_sha1);
5320
- if (!oldFile) {
5321
- console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
5322
- }
5323
- if (!newFile.objectURL) {
5324
- throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
5325
- }
5326
- store.dispatch(
5327
- updateComponentAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) })
5328
- );
5329
- await this.client.files.addCache(newFile, newSha1);
5330
- const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
5331
- store.dispatch(updateComponentAttachment(attachment));
5332
- throw e;
5333
- });
5334
- const promise2 = this.enqueueRequest({
5335
- description: "Edit attachment",
5336
- method: HttpMethod.PATCH,
5337
- url: `/attachments/components/${attachment.offline_id}/`,
5338
- isResponseBlob: false,
5339
- payload: fileProps,
5340
- blockers: [attachmentId, newSha1],
5341
- blocks: [attachmentId, newSha1]
5342
- });
5343
- try {
5344
- const result = await promise2;
5345
- void this.client.files.removeCache(attachment.file_sha1);
5346
- return result;
5347
- } catch (e) {
5348
- if (oldFile) {
5349
- store.dispatch(
5350
- updateComponentAttachment({
5351
- ...attachment,
5352
- file_sha1: attachment.file_sha1,
5353
- file: URL.createObjectURL(oldFile)
5354
- })
5355
- );
5356
- }
5357
- throw e;
5358
- }
5359
- };
5360
- const offlineAttachment = {
5361
- ...attachment,
5362
- file_sha1: newSha1,
5363
- file: URL.createObjectURL(newFile)
5364
- };
5365
- const promise = performRequest2();
5366
- return [offlineAttachment, promise];
5367
- }
5368
- async replaceComponentTypeAttachmentFile(attachmentId, newFile) {
5369
- const { store } = this.client;
5370
- const attachment = store.getState().componentTypeReducer.attachments[attachmentId];
5371
- if (!attachment)
5372
- throw new Error(`Attachment ${attachmentId} not found`);
5373
- let oldFile = void 0;
5374
- const newSha1 = await hashFile(newFile);
5375
- const performRequest2 = async () => {
5376
- oldFile = await this.client.files.fetchCache(attachment.file_sha1);
5377
- if (!oldFile) {
5378
- console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
5379
- }
5380
- if (!newFile.objectURL) {
5381
- throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
5382
- }
5383
- store.dispatch(
5384
- updateComponentTypeAttachment({
5385
- ...attachment,
5386
- file_sha1: newSha1,
5387
- file: URL.createObjectURL(newFile)
5388
- })
5389
- );
5390
- await this.client.files.addCache(newFile, newSha1);
5391
- const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
5392
- store.dispatch(updateComponentTypeAttachment(attachment));
5393
- throw e;
5394
- });
5395
- const promise2 = this.enqueueRequest({
5396
- description: "Edit attachment",
5397
- method: HttpMethod.PATCH,
5398
- url: `/attachments/component_types/${attachment.offline_id}/`,
5399
- isResponseBlob: false,
5400
- payload: fileProps,
5401
- blockers: [attachmentId, newSha1],
5402
- blocks: [attachmentId, newSha1]
5403
- });
5404
- try {
5405
- const result = await promise2;
5406
- void this.client.files.removeCache(attachment.file_sha1);
5407
- return result;
5408
- } catch (e) {
5409
- if (oldFile) {
5410
- store.dispatch(
5411
- updateComponentTypeAttachment({
5412
- ...attachment,
5413
- file_sha1: attachment.file_sha1,
5414
- file: URL.createObjectURL(oldFile)
5415
- })
5416
- );
5417
- }
5418
- throw e;
5419
- }
5420
- };
5421
- const offlineAttachment = {
5422
- ...attachment,
5423
- file_sha1: newSha1,
5424
- file: URL.createObjectURL(newFile)
5425
- };
5426
- const promise = performRequest2();
5427
- return [offlineAttachment, promise];
5428
- }
5429
- async replaceDocumentAttachmentFile(attachmentId, newFile) {
5430
- const { store } = this.client;
5431
- const attachment = store.getState().documentsReducer.attachments[attachmentId];
5432
- if (!attachment)
5433
- throw new Error(`Attachment ${attachmentId} not found`);
5434
- let oldFile = void 0;
5435
- const newSha1 = await hashFile(newFile);
5436
- const performRequest2 = async () => {
5437
- oldFile = await this.client.files.fetchCache(attachment.file_sha1);
5438
- if (!oldFile) {
5439
- console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
5440
- }
5441
- if (!newFile.objectURL) {
5442
- throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
5443
- }
5444
- store.dispatch(
5445
- updateDocumentAttachment({
5446
- ...attachment,
5447
- file_sha1: newSha1,
5448
- file: URL.createObjectURL(newFile)
5449
- })
5450
- );
5451
- await this.client.files.addCache(newFile, newSha1);
5452
- const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
5453
- store.dispatch(updateDocumentAttachment(attachment));
5454
- throw e;
5455
- });
5456
- const promise2 = this.enqueueRequest({
5457
- description: "Edit attachment",
5458
- method: HttpMethod.PATCH,
5459
- url: `/attachments/documents/${attachment.offline_id}/`,
5460
- isResponseBlob: false,
5461
- payload: fileProps,
5462
- blockers: [attachmentId, newSha1],
5463
- blocks: [attachmentId, newSha1]
5464
- });
5465
- try {
5466
- const result = await promise2;
5467
- void this.client.files.removeCache(attachment.file_sha1);
5468
- return result;
5469
- } catch (e) {
5470
- if (oldFile) {
5471
- store.dispatch(
5472
- updateDocumentAttachment({
5473
- ...attachment,
5474
- file_sha1: attachment.file_sha1,
5475
- file: URL.createObjectURL(oldFile)
5476
- })
5477
- );
5478
- }
5479
- throw e;
5480
- }
5481
- };
5482
- const offlineAttachment = {
5483
- ...attachment,
5484
- file_sha1: newSha1,
5485
- file: URL.createObjectURL(newFile)
5486
- };
5487
- const promise = performRequest2();
5488
- return [offlineAttachment, promise];
5489
- }
5490
- /**
5491
- * Deletes an attachment and associated data in the cloud, in the Redux store and the cache.
5492
- * @param issueAttachmentId
5493
- */
5494
- deleteIssueAttachment(issueAttachmentId) {
5495
- const { store } = this.client;
5496
- const attachment = selectIssueAttachmentMapping(store.getState())[issueAttachmentId];
5497
- if (!attachment) {
5498
- throw new Error(`Attachment ${issueAttachmentId} not found`);
5499
- }
5500
- store.dispatch(removeIssueAttachment(issueAttachmentId));
5501
- void this.client.files.removeCache(attachment.file_sha1);
5502
- return this.enqueueRequest({
5503
- description: "Delete attachment",
5504
- method: HttpMethod.DELETE,
5505
- url: `/attachments/issues/${issueAttachmentId}/`,
5506
- blockers: [issueAttachmentId],
5507
- blocks: [issueAttachmentId]
5508
- });
5509
- }
5510
- deleteComponentAttachment(componentAttachmentId) {
5511
- const { store } = this.client;
5512
- const attachment = selectComponentAttachmentMapping(store.getState())[componentAttachmentId];
5513
- if (!attachment) {
5514
- throw new Error(`Attachment ${componentAttachmentId} not found`);
5515
- }
5516
- store.dispatch(removeComponentAttachment(componentAttachmentId));
5517
- void this.client.files.removeCache(attachment.file_sha1);
5518
- return this.enqueueRequest({
5519
- description: "Delete attachment",
5520
- method: HttpMethod.DELETE,
5521
- url: `/attachments/components/${componentAttachmentId}/`,
5522
- blockers: [componentAttachmentId],
5523
- blocks: [componentAttachmentId]
5524
- });
5525
- }
5526
- deleteComponentTypeAttachment(componentTypeAttachmentId) {
5527
- const { store } = this.client;
5528
- const attachment = selectComponentTypeAttachmentMapping(store.getState())[componentTypeAttachmentId];
5529
- if (!attachment) {
5530
- throw new Error(`Attachment ${componentTypeAttachmentId} not found`);
5531
- }
5532
- store.dispatch(removeComponentTypeAttachment(componentTypeAttachmentId));
5533
- void this.client.files.removeCache(attachment.file_sha1);
5534
- return this.enqueueRequest({
5535
- description: "Delete attachment",
5536
- method: HttpMethod.DELETE,
5537
- url: `/attachments/component_types/${componentTypeAttachmentId}/`,
5538
- blockers: [componentTypeAttachmentId],
5539
- blocks: [componentTypeAttachmentId]
5540
- });
5541
- }
5542
- deleteDocumentAttachment(documentAttachmentId) {
5543
- const { store } = this.client;
5544
- const attachment = store.getState().documentsReducer.attachments[documentAttachmentId];
5545
- if (!attachment) {
5546
- throw new Error(`Attachment ${documentAttachmentId} not found`);
5547
- }
5548
- store.dispatch(removeDocumentAttachment(documentAttachmentId));
5549
- void this.client.files.removeCache(attachment.file_sha1);
5550
- return this.enqueueRequest({
5551
- description: "Delete document attachment",
5552
- method: HttpMethod.DELETE,
5553
- url: `/attachments/documents/${documentAttachmentId}/`,
5554
- blockers: [documentAttachmentId],
5555
- blocks: [documentAttachmentId]
5556
- });
5557
- }
5558
- }
5559
5065
  const EXPIRING_SOON_THRESHOLD = 1800;
5560
5066
  function parseTokens(response) {
5561
5067
  if (!response.access)
@@ -6247,6 +5753,221 @@ var __publicField = (obj, key, value) => {
6247
5753
  store.dispatch(addStages(result));
6248
5754
  }
6249
5755
  }
5756
+ const AttachmentModelMeta = {
5757
+ [AttachmentModel.Issue]: {
5758
+ name: "issue",
5759
+ attachUrlPrefix: "/issues",
5760
+ deleteUrlPrefix: "/issues",
5761
+ fetchUrlPostfix: "/issue-attachments"
5762
+ },
5763
+ [AttachmentModel.Component]: {
5764
+ name: "component",
5765
+ attachUrlPrefix: "/components",
5766
+ deleteUrlPrefix: "/components",
5767
+ fetchUrlPostfix: "/component-attachments"
5768
+ },
5769
+ [AttachmentModel.ComponentType]: {
5770
+ name: "component type",
5771
+ attachUrlPrefix: "/components/types",
5772
+ deleteUrlPrefix: "/components/types",
5773
+ fetchUrlPostfix: "/component-type-attachments"
5774
+ },
5775
+ [AttachmentModel.Project]: {
5776
+ name: "component project",
5777
+ attachUrlPrefix: "/projects",
5778
+ deleteUrlPrefix: "/projects",
5779
+ fetchUrlPostfix: "/attachments"
5780
+ },
5781
+ [AttachmentModel.Document]: {
5782
+ name: "document",
5783
+ attachUrlPrefix: "/documents",
5784
+ deleteUrlPrefix: "/documents",
5785
+ fetchUrlPostfix: "/document-attachments"
5786
+ }
5787
+ };
5788
+ class BaseAttachmentService extends BaseApiService {
5789
+ getNumberOfAttachmentsWithSha1(sha1) {
5790
+ const {
5791
+ issueReducer: issueReducer2,
5792
+ componentReducer: componentReducer2,
5793
+ componentTypeReducer: componentTypeReducer2,
5794
+ documentsReducer: documentsReducer2,
5795
+ projectReducer: projectReducer2,
5796
+ formSubmissionReducer: formSubmissionReducer2,
5797
+ formRevisionReducer: formRevisionReducer2
5798
+ } = this.client.store.getState();
5799
+ const objectsWithSha1 = [].concat(
5800
+ Object.values(issueReducer2.attachments),
5801
+ Object.values(componentReducer2.attachments),
5802
+ Object.values(componentTypeReducer2.attachments),
5803
+ Object.values(documentsReducer2.attachments),
5804
+ Object.values(projectReducer2.attachments),
5805
+ Object.values(formRevisionReducer2.attachments),
5806
+ Object.values(formSubmissionReducer2.attachments)
5807
+ );
5808
+ return objectsWithSha1.filter((object) => object.file_sha1 === sha1).length;
5809
+ }
5810
+ processPresignedUrls(presignedUrls) {
5811
+ for (const [sha1, presignedUrl] of Object.entries(presignedUrls)) {
5812
+ void this.enqueueRequest({
5813
+ url: presignedUrl.url,
5814
+ description: "Upload file to S3",
5815
+ method: HttpMethod.POST,
5816
+ isExternalUrl: true,
5817
+ isAuthNeeded: false,
5818
+ attachmentHash: sha1,
5819
+ // TODO: can we use the sha1 as the blocker?
5820
+ blockers: [`s3-${presignedUrl.fields.key}`],
5821
+ blocks: [sha1],
5822
+ s3url: presignedUrl
5823
+ });
5824
+ }
5825
+ }
5826
+ // Note that currently the fetching of attachments for all models dependds on the active projectId. This may change in the future. And
5827
+ // so for some attachment model services, this method will have to be overridden.
5828
+ async getAttachments(actions) {
5829
+ const { store } = this.client;
5830
+ const activeProjectId = store.getState().projectReducer.activeProjectId;
5831
+ const meta = AttachmentModelMeta[this.attachmentModel];
5832
+ const result = await this.enqueueRequest({
5833
+ description: `Get ${meta.name} attachments`,
5834
+ method: HttpMethod.GET,
5835
+ url: `/projects/${activeProjectId}${meta.fetchUrlPostfix}/`,
5836
+ blocks: [],
5837
+ blockers: []
5838
+ });
5839
+ store.dispatch(actions.setAttachments(result));
5840
+ }
5841
+ async attachFiles(files, modelId, buildOfflineAttachment, actions) {
5842
+ const { store } = this.client;
5843
+ const currentUser = store.getState().userReducer.currentUser;
5844
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5845
+ const offlineAttachments = [];
5846
+ const attachmentPayloads = [];
5847
+ const filePayloads = {};
5848
+ for (const file of files) {
5849
+ const sha1 = await hashFile(file);
5850
+ if (!(sha1 in filePayloads)) {
5851
+ filePayloads[sha1] = {
5852
+ sha1,
5853
+ file_type: file.type,
5854
+ extension: file.name.split(".").pop(),
5855
+ size: file.size
5856
+ };
5857
+ await this.client.files.addCache(file, sha1);
5858
+ }
5859
+ const offlineAttachment = buildOfflineAttachment({
5860
+ file,
5861
+ sha1,
5862
+ submittedAt,
5863
+ createdBy: currentUser.id,
5864
+ description: "",
5865
+ modelId
5866
+ });
5867
+ offlineAttachments.push(offlineAttachment);
5868
+ attachmentPayloads.push({
5869
+ offline_id: offlineAttachment.offline_id,
5870
+ name: offlineAttachment.file_name,
5871
+ sha1: offlineAttachment.file_sha1,
5872
+ description: offlineAttachment.description
5873
+ });
5874
+ }
5875
+ store.dispatch(actions.addAttachments(offlineAttachments));
5876
+ const meta = AttachmentModelMeta[this.attachmentModel];
5877
+ const promise = this.enqueueRequest({
5878
+ description: `Attach files to ${meta.name}`,
5879
+ method: HttpMethod.POST,
5880
+ url: `${meta.attachUrlPrefix}/${modelId}/attach/`,
5881
+ payload: {
5882
+ submitted_at: submittedAt,
5883
+ attachments: attachmentPayloads,
5884
+ files: Object.values(filePayloads)
5885
+ },
5886
+ blocks: offlineAttachments.map((attachment) => attachment.offline_id),
5887
+ blockers: offlineAttachments.map((attachment) => attachment.file_sha1)
5888
+ });
5889
+ promise.then(({ attachments, presigned_urls }) => {
5890
+ store.dispatch(actions.updateAttachments(attachments));
5891
+ this.processPresignedUrls(presigned_urls);
5892
+ }).catch(() => {
5893
+ store.dispatch(actions.removeAttachments(offlineAttachments.map((attachment) => attachment.offline_id)));
5894
+ });
5895
+ return [offlineAttachments, promise.then(({ attachments }) => attachments)];
5896
+ }
5897
+ async deleteAttachment(attachmendId, actions, selectors) {
5898
+ const { store } = this.client;
5899
+ const attachment = selectors.selectAttachment(attachmendId)(store.getState());
5900
+ if (!attachment) {
5901
+ throw new Error(
5902
+ `Attempting to delete attachment with offline_id ${attachmendId} that does not exist in the store`
5903
+ );
5904
+ }
5905
+ store.dispatch(actions.removeAttachment(attachment.offline_id));
5906
+ const meta = AttachmentModelMeta[this.attachmentModel];
5907
+ const promise = this.enqueueRequest({
5908
+ description: "Delete attachment",
5909
+ method: HttpMethod.DELETE,
5910
+ url: `${meta.deleteUrlPrefix}/attachments/${attachmendId}/`,
5911
+ blockers: [attachmendId],
5912
+ blocks: []
5913
+ });
5914
+ promise.then(() => {
5915
+ if (this.getNumberOfAttachmentsWithSha1(attachment.file_sha1) === 0) {
5916
+ void this.client.files.removeCache(attachment.file_sha1);
5917
+ }
5918
+ }).catch(() => {
5919
+ store.dispatch(actions.setAttachment(attachment));
5920
+ });
5921
+ return promise;
5922
+ }
5923
+ }
5924
+ class ComponentAttachmentService extends BaseAttachmentService {
5925
+ constructor() {
5926
+ super(...arguments);
5927
+ __publicField(this, "attachmentModel", AttachmentModel.Component);
5928
+ }
5929
+ buildOfflineAttachment(data) {
5930
+ return offline({
5931
+ file: URL.createObjectURL(data.file),
5932
+ file_sha1: data.sha1,
5933
+ created_by: data.createdBy,
5934
+ file_name: data.file.name,
5935
+ file_type: data.file.type,
5936
+ submitted_at: data.submittedAt,
5937
+ description: data.description,
5938
+ component: data.modelId
5939
+ });
5940
+ }
5941
+ async attachFilesToComponent(files, componentId) {
5942
+ return this.attachFiles(
5943
+ files,
5944
+ componentId,
5945
+ this.buildOfflineAttachment.bind(this),
5946
+ {
5947
+ addAttachments: addComponentAttachments,
5948
+ updateAttachments: updateComponentAttachments,
5949
+ removeAttachments: removeComponentAttachments
5950
+ }
5951
+ );
5952
+ }
5953
+ deleteComponentAttachment(attachmentId) {
5954
+ return this.deleteAttachment(
5955
+ attachmentId,
5956
+ {
5957
+ setAttachment: setComponentAttachment,
5958
+ removeAttachment: removeComponentAttachment
5959
+ },
5960
+ {
5961
+ selectAttachment: selectComponentAttachment
5962
+ }
5963
+ );
5964
+ }
5965
+ async refreshStore() {
5966
+ return this.getAttachments({
5967
+ setAttachments: setComponentAttachments
5968
+ });
5969
+ }
5970
+ }
6250
5971
  class ComponentTypeService extends BaseApiService {
6251
5972
  add(componentType) {
6252
5973
  const offlineComponentType = offline(componentType);
@@ -6319,6 +6040,53 @@ var __publicField = (obj, key, value) => {
6319
6040
  store.dispatch(setComponentTypes(result));
6320
6041
  }
6321
6042
  }
6043
+ class ComponentTypeAttachmentService extends BaseAttachmentService {
6044
+ constructor() {
6045
+ super(...arguments);
6046
+ __publicField(this, "attachmentModel", AttachmentModel.ComponentType);
6047
+ }
6048
+ buildOfflineAttachment(data) {
6049
+ return offline({
6050
+ file: URL.createObjectURL(data.file),
6051
+ file_sha1: data.sha1,
6052
+ created_by: data.createdBy,
6053
+ file_name: data.file.name,
6054
+ file_type: data.file.type,
6055
+ submitted_at: data.submittedAt,
6056
+ description: data.description,
6057
+ component_type: data.modelId
6058
+ });
6059
+ }
6060
+ async attachFilesToComponentType(files, componentTypeId) {
6061
+ return this.attachFiles(
6062
+ files,
6063
+ componentTypeId,
6064
+ this.buildOfflineAttachment.bind(this),
6065
+ {
6066
+ addAttachments: addComponentTypeAttachments,
6067
+ updateAttachments: updateComponentTypeAttachments,
6068
+ removeAttachments: removeComponentTypeAttachments
6069
+ }
6070
+ );
6071
+ }
6072
+ deleteComponentTypeAttachment(attachmentId) {
6073
+ return this.deleteAttachment(
6074
+ attachmentId,
6075
+ {
6076
+ setAttachment: setComponentTypeAttachment,
6077
+ removeAttachment: removeComponentTypeAttachment
6078
+ },
6079
+ {
6080
+ selectAttachment: selectComponentTypeAttachment
6081
+ }
6082
+ );
6083
+ }
6084
+ async refreshStore() {
6085
+ return this.getAttachments({
6086
+ setAttachments: setComponentTypeAttachments
6087
+ });
6088
+ }
6089
+ }
6322
6090
  class IssueCommentService extends BaseApiService {
6323
6091
  // Omit author and submitted_at since these will always be set internally
6324
6092
  add(comment) {
@@ -6415,6 +6183,48 @@ var __publicField = (obj, key, value) => {
6415
6183
  store.dispatch(setIssueUpdates(filteredResult));
6416
6184
  }
6417
6185
  }
6186
+ class IssueAttachmentService extends BaseAttachmentService {
6187
+ constructor() {
6188
+ super(...arguments);
6189
+ __publicField(this, "attachmentModel", AttachmentModel.Issue);
6190
+ }
6191
+ buildOfflineAttachment(data) {
6192
+ return offline({
6193
+ file: URL.createObjectURL(data.file),
6194
+ file_sha1: data.sha1,
6195
+ created_by: data.createdBy,
6196
+ file_name: data.file.name,
6197
+ file_type: data.file.type,
6198
+ submitted_at: data.submittedAt,
6199
+ description: data.description,
6200
+ issue: data.modelId
6201
+ });
6202
+ }
6203
+ async attachFilesToIssue(files, issueId) {
6204
+ return this.attachFiles(files, issueId, this.buildOfflineAttachment.bind(this), {
6205
+ addAttachments: addIssueAttachments,
6206
+ updateAttachments: updateIssueAttachments,
6207
+ removeAttachments: removeIssueAttachments
6208
+ });
6209
+ }
6210
+ deleteIssueAttachment(attachmentId) {
6211
+ return this.deleteAttachment(
6212
+ attachmentId,
6213
+ {
6214
+ setAttachment: setIssueAttachment,
6215
+ removeAttachment: removeIssueAttachment
6216
+ },
6217
+ {
6218
+ selectAttachment: selectIssueAttachment
6219
+ }
6220
+ );
6221
+ }
6222
+ async refreshStore() {
6223
+ return this.getAttachments({
6224
+ setAttachments: setIssueAttachments
6225
+ });
6226
+ }
6227
+ }
6418
6228
  class IssueService extends BaseApiService {
6419
6229
  // Basic CRUD functions
6420
6230
  // TODO: Once all models are represented in `Created<TModel>`, use `Created` in `OptimisticModelResult`, so we don't
@@ -6859,6 +6669,7 @@ var __publicField = (obj, key, value) => {
6859
6669
  const usersResult = await usersResultPromise;
6860
6670
  await projectAccessRefreshPromise;
6861
6671
  store.dispatch(addUsers(usersResult));
6672
+ void this.client.projectAttachments.refreshStore();
6862
6673
  }
6863
6674
  let currentWorkspaceId;
6864
6675
  const oldWorkspaceId = this.client.store.getState().workspaceReducer.activeWorkspaceId;
@@ -6871,35 +6682,29 @@ var __publicField = (obj, key, value) => {
6871
6682
  store.dispatch(setActiveWorkspaceId(currentWorkspaceId));
6872
6683
  void this.client.categories.refreshStore().then(() => {
6873
6684
  void this.client.issues.refreshStore().then(() => {
6685
+ void this.client.issueAttachments.refreshStore().then();
6874
6686
  void this.client.issueComments.refreshStore().then();
6687
+ void this.client.issueUpdates.refreshStore().then();
6875
6688
  });
6876
6689
  });
6877
6690
  void this.client.projectFiles.refreshStore().then();
6878
6691
  void this.client.componentTypes.refreshStore().then(() => {
6879
- void this.client.componentStages.refreshStore().then(() => {
6880
- void this.client.components.refreshStore(overwrite).then();
6692
+ void this.client.componentTypeAttachments.refreshStore().then(() => {
6693
+ void this.client.componentStages.refreshStore().then(() => {
6694
+ void this.client.components.refreshStore(overwrite).then(() => {
6695
+ void this.client.componentAttachments.refreshStore().then();
6696
+ });
6697
+ });
6698
+ void this.client.componentStageCompletions.refreshStore().then();
6881
6699
  });
6882
- void this.client.componentStageCompletions.refreshStore().then();
6883
6700
  });
6884
6701
  void this.client.userForms.refreshStore().then(() => {
6885
6702
  void this.client.userFormSubmissions.refreshStore().then();
6886
6703
  });
6887
6704
  }
6888
6705
  if (currentProjectId) {
6889
- const [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId);
6890
- void promise.then((result) => {
6891
- const {
6892
- issue_attachments,
6893
- component_type_attachments,
6894
- component_attachments,
6895
- project_attachments,
6896
- document_attachments
6897
- } = result;
6898
- store.dispatch(setIssueAttachments(issue_attachments));
6899
- store.dispatch(setComponentAttachments(component_attachments));
6900
- store.dispatch(setComponentTypeAttachments(component_type_attachments));
6901
- store.dispatch(setProjectAttachments(project_attachments));
6902
- store.dispatch(setDocumentAttachments(document_attachments));
6706
+ void this.client.documents.refreshStore().then(() => {
6707
+ void this.client.documentAttachments.refreshStore().then();
6903
6708
  });
6904
6709
  void this.client.documents.refreshStore();
6905
6710
  void this.client.issueUpdates.refreshStore();
@@ -7002,6 +6807,7 @@ var __publicField = (obj, key, value) => {
7002
6807
  });
7003
6808
  return promise;
7004
6809
  }
6810
+ // TODO: This needs to be seperated into a update and create method
7005
6811
  saveActive() {
7006
6812
  const { store } = this.client;
7007
6813
  const state = store.getState();
@@ -7067,6 +6873,48 @@ var __publicField = (obj, key, value) => {
7067
6873
  });
7068
6874
  }
7069
6875
  }
6876
+ class ProjectAttachmentService extends BaseAttachmentService {
6877
+ constructor() {
6878
+ super(...arguments);
6879
+ __publicField(this, "attachmentModel", AttachmentModel.Project);
6880
+ }
6881
+ buildOfflineAttachment(data) {
6882
+ return offline({
6883
+ file: URL.createObjectURL(data.file),
6884
+ file_sha1: data.sha1,
6885
+ created_by: data.createdBy,
6886
+ file_name: data.file.name,
6887
+ file_type: data.file.type,
6888
+ submitted_at: data.submittedAt,
6889
+ description: data.description,
6890
+ project: data.modelId
6891
+ });
6892
+ }
6893
+ async attachFilesToProject(files, projectId) {
6894
+ return this.attachFiles(files, projectId, this.buildOfflineAttachment.bind(this), {
6895
+ addAttachments: addProjectAttachments,
6896
+ updateAttachments: updateProjectAttachments,
6897
+ removeAttachments: removeProjectAttachments
6898
+ });
6899
+ }
6900
+ deleteProjectAttachment(attachmentId) {
6901
+ return this.deleteAttachment(
6902
+ attachmentId,
6903
+ {
6904
+ setAttachment: setProjectAttachment,
6905
+ removeAttachment: removeProjectAttachment
6906
+ },
6907
+ {
6908
+ selectAttachment: selectProjectAttachment
6909
+ }
6910
+ );
6911
+ }
6912
+ async refreshStore() {
6913
+ return this.getAttachments({
6914
+ setAttachments: setProjectAttachments
6915
+ });
6916
+ }
6917
+ }
7070
6918
  class ProjectService extends BaseApiService {
7071
6919
  /**
7072
6920
  * Creates a new project. Due to the nature of project creation,
@@ -8458,6 +8306,48 @@ var __publicField = (obj, key, value) => {
8458
8306
  store.dispatch(addDocuments(await organizationDocumentsPromise));
8459
8307
  }
8460
8308
  }
8309
+ class DocumentAttachmentService extends BaseAttachmentService {
8310
+ constructor() {
8311
+ super(...arguments);
8312
+ __publicField(this, "attachmentModel", AttachmentModel.Document);
8313
+ }
8314
+ buildOfflineAttachment(data) {
8315
+ return offline({
8316
+ file: URL.createObjectURL(data.file),
8317
+ file_sha1: data.sha1,
8318
+ created_by: data.createdBy,
8319
+ file_name: data.file.name,
8320
+ file_type: data.file.type,
8321
+ submitted_at: data.submittedAt,
8322
+ description: data.description,
8323
+ document: data.modelId
8324
+ });
8325
+ }
8326
+ async attachFilesToDocument(files, documentId) {
8327
+ return this.attachFiles(files, documentId, this.buildOfflineAttachment.bind(this), {
8328
+ addAttachments: addDocumentAttachments,
8329
+ updateAttachments: updateDocumentAttachments,
8330
+ removeAttachments: removeDocumentAttachments
8331
+ });
8332
+ }
8333
+ deleteDocumentAttachment(attachmentId) {
8334
+ return this.deleteAttachment(
8335
+ attachmentId,
8336
+ {
8337
+ setAttachment: setDocumentAttachment,
8338
+ removeAttachment: removeDocumentAttachment
8339
+ },
8340
+ {
8341
+ selectAttachment: selectDocumentAttachment
8342
+ }
8343
+ );
8344
+ }
8345
+ async refreshStore() {
8346
+ return this.getAttachments({
8347
+ setAttachments: setDocumentAttachments
8348
+ });
8349
+ }
8350
+ }
8461
8351
  class AgentService extends BaseApiService {
8462
8352
  /**
8463
8353
  * Prompt the agent with a message.
@@ -8479,16 +8369,6 @@ var __publicField = (obj, key, value) => {
8479
8369
  queryParams: conversationId ? { conversation_id: conversationId } : {}
8480
8370
  });
8481
8371
  }
8482
- async fetchAll() {
8483
- const activeProjectId = this.client.store.getState().projectReducer.activeProjectId;
8484
- return this.enqueueRequest({
8485
- description: "Fetch agent conversations",
8486
- method: HttpMethod.GET,
8487
- url: `/projects/${activeProjectId}/agents-conversations/`,
8488
- blockers: ["fetch-agent-conversations"],
8489
- blocks: ["fetch-agent-conversations"]
8490
- });
8491
- }
8492
8372
  async rate(responseId, rating) {
8493
8373
  return this.enqueueRequest({
8494
8374
  description: "Rate agent response",
@@ -8642,7 +8522,6 @@ var __publicField = (obj, key, value) => {
8642
8522
  __publicField(this, "store");
8643
8523
  __publicField(this, "agent", new AgentService(this));
8644
8524
  __publicField(this, "files", new FileService(this));
8645
- __publicField(this, "attachments", new AttachmentService(this));
8646
8525
  __publicField(this, "auth", new AuthService(this));
8647
8526
  __publicField(this, "categories", new CategoryService(this));
8648
8527
  __publicField(this, "projectAccesses", new ProjectAccessService(this));
@@ -8652,21 +8531,26 @@ var __publicField = (obj, key, value) => {
8652
8531
  __publicField(this, "issueTypes", new IssueTypeService(this));
8653
8532
  __publicField(this, "issueComments", new IssueCommentService(this));
8654
8533
  __publicField(this, "issueUpdates", new IssueUpdateService(this));
8534
+ __publicField(this, "issueAttachments", new IssueAttachmentService(this));
8655
8535
  __publicField(this, "workspaces", new WorkspaceService(this));
8656
8536
  __publicField(this, "main", new MainService(this));
8657
8537
  __publicField(this, "components", new ComponentService(this));
8538
+ __publicField(this, "componentAttachments", new ComponentAttachmentService(this));
8658
8539
  __publicField(this, "componentTypes", new ComponentTypeService(this));
8540
+ __publicField(this, "componentTypeAttachments", new ComponentTypeAttachmentService(this));
8659
8541
  __publicField(this, "componentStages", new ComponentStageService(this));
8660
8542
  __publicField(this, "componentStageCompletions", new ComponentStageCompletionService(this));
8661
8543
  __publicField(this, "userForms", new UserFormService(this));
8662
8544
  __publicField(this, "userFormSubmissions", new UserFormSubmissionService(this));
8663
8545
  __publicField(this, "projects", new ProjectService(this));
8664
8546
  __publicField(this, "projectFiles", new ProjectFileService(this));
8547
+ __publicField(this, "projectAttachments", new ProjectAttachmentService(this));
8665
8548
  __publicField(this, "emailVerification", new EmailVerificationService(this));
8666
8549
  __publicField(this, "emailDomains", new EmailDomainsService(this));
8667
8550
  __publicField(this, "licenses", new LicenseService(this));
8668
8551
  __publicField(this, "documents", new DocumentService(this));
8669
8552
  __publicField(this, "teams", new TeamService(this));
8553
+ __publicField(this, "documentAttachments", new DocumentAttachmentService(this));
8670
8554
  this.API_URL = apiUrl;
8671
8555
  this.store = store;
8672
8556
  }
@@ -16498,7 +16382,7 @@ var __publicField = (obj, key, value) => {
16498
16382
  }, Symbol.toStringTag, { value: "Module" }));
16499
16383
  exports2.APIError = APIError;
16500
16384
  exports2.AgentService = AgentService;
16501
- exports2.AttachmentService = AttachmentService;
16385
+ exports2.AttachmentModel = AttachmentModel;
16502
16386
  exports2.AuthService = AuthService;
16503
16387
  exports2.BaseApiService = BaseApiService;
16504
16388
  exports2.BaseField = BaseField;
@@ -16509,15 +16393,18 @@ var __publicField = (obj, key, value) => {
16509
16393
  exports2.ColorPicker = ColorPicker;
16510
16394
  exports2.Colors = Colors;
16511
16395
  exports2.ColorsToString = ColorsToString;
16396
+ exports2.ComponentAttachmentService = ComponentAttachmentService;
16512
16397
  exports2.ComponentService = ComponentService;
16513
16398
  exports2.ComponentStageColors = ComponentStageColors;
16514
16399
  exports2.ComponentStageCompletionService = ComponentStageCompletionService;
16515
16400
  exports2.ComponentStageService = ComponentStageService;
16401
+ exports2.ComponentTypeAttachmentService = ComponentTypeAttachmentService;
16516
16402
  exports2.ComponentTypeService = ComponentTypeService;
16517
16403
  exports2.DEFAULT_ISSUE_PRIORITY = DEFAULT_ISSUE_PRIORITY;
16518
16404
  exports2.DEFAULT_ISSUE_STATUS = DEFAULT_ISSUE_STATUS;
16519
16405
  exports2.DateField = DateField;
16520
16406
  exports2.DateInput = DateInput;
16407
+ exports2.DocumentAttachmentService = DocumentAttachmentService;
16521
16408
  exports2.DocumentService = DocumentService;
16522
16409
  exports2.EmailDomainsService = EmailDomainsService;
16523
16410
  exports2.EmailVerificationService = EmailVerificationService;
@@ -16541,6 +16428,7 @@ var __publicField = (obj, key, value) => {
16541
16428
  exports2.InputWithHelpText = InputWithHelpText;
16542
16429
  exports2.InputWithLabel = InputWithLabel;
16543
16430
  exports2.InputWithLabelAndHelpText = InputWithLabelAndHelpText;
16431
+ exports2.IssueAttachmentService = IssueAttachmentService;
16544
16432
  exports2.IssueCommentService = IssueCommentService;
16545
16433
  exports2.IssuePriority = IssuePriority;
16546
16434
  exports2.IssueService = IssueService;
@@ -16573,6 +16461,7 @@ var __publicField = (obj, key, value) => {
16573
16461
  exports2.PatchFormProvider = PatchFormProvider;
16574
16462
  exports2.ProjectAccessLevel = ProjectAccessLevel;
16575
16463
  exports2.ProjectAccessService = ProjectAccessService;
16464
+ exports2.ProjectAttachmentService = ProjectAttachmentService;
16576
16465
  exports2.ProjectFileService = ProjectFileService;
16577
16466
  exports2.ProjectService = ProjectService;
16578
16467
  exports2.ProjectType = ProjectType;
@@ -16803,6 +16692,7 @@ var __publicField = (obj, key, value) => {
16803
16692
  exports2.removeFavouriteProjectId = removeFavouriteProjectId;
16804
16693
  exports2.removeIssue = removeIssue;
16805
16694
  exports2.removeIssueAttachment = removeIssueAttachment;
16695
+ exports2.removeIssueAttachments = removeIssueAttachments;
16806
16696
  exports2.removeIssueComment = removeIssueComment;
16807
16697
  exports2.removeIssueComments = removeIssueComments;
16808
16698
  exports2.removeIssueType = removeIssueType;
@@ -16977,6 +16867,7 @@ var __publicField = (obj, key, value) => {
16977
16867
  exports2.selectProjectAccessForUser = selectProjectAccessForUser;
16978
16868
  exports2.selectProjectAccessUserMapping = selectProjectAccessUserMapping;
16979
16869
  exports2.selectProjectAccesses = selectProjectAccesses;
16870
+ exports2.selectProjectAttachment = selectProjectAttachment;
16980
16871
  exports2.selectProjectAttachmentMapping = selectProjectAttachmentMapping;
16981
16872
  exports2.selectProjectFileVisibility = selectProjectFileVisibility;
16982
16873
  exports2.selectProjectFiles = selectProjectFiles;
@@ -17026,12 +16917,15 @@ var __publicField = (obj, key, value) => {
17026
16917
  exports2.setAppearance = setAppearance;
17027
16918
  exports2.setCategories = setCategories;
17028
16919
  exports2.setCenterMapToProject = setCenterMapToProject;
16920
+ exports2.setComponentAttachment = setComponentAttachment;
17029
16921
  exports2.setComponentAttachments = setComponentAttachments;
16922
+ exports2.setComponentTypeAttachment = setComponentTypeAttachment;
17030
16923
  exports2.setComponentTypeAttachments = setComponentTypeAttachments;
17031
16924
  exports2.setComponentTypes = setComponentTypes;
17032
16925
  exports2.setComponents = setComponents;
17033
16926
  exports2.setCreateProjectType = setCreateProjectType;
17034
16927
  exports2.setCurrentUser = setCurrentUser;
16928
+ exports2.setDocumentAttachment = setDocumentAttachment;
17035
16929
  exports2.setDocumentAttachments = setDocumentAttachments;
17036
16930
  exports2.setDocuments = setDocuments;
17037
16931
  exports2.setEmailDomains = setEmailDomains;
@@ -17048,6 +16942,7 @@ var __publicField = (obj, key, value) => {
17048
16942
  exports2.setIsFetchingInitialData = setIsFetchingInitialData;
17049
16943
  exports2.setIsImportingProjectFile = setIsImportingProjectFile;
17050
16944
  exports2.setIsLoading = setIsLoading;
16945
+ exports2.setIssueAttachment = setIssueAttachment;
17051
16946
  exports2.setIssueAttachments = setIssueAttachments;
17052
16947
  exports2.setIssueComment = setIssueComment;
17053
16948
  exports2.setIssueComments = setIssueComments;
@@ -17062,6 +16957,7 @@ var __publicField = (obj, key, value) => {
17062
16957
  exports2.setOrganizations = setOrganizations;
17063
16958
  exports2.setProfilePicture = setProfilePicture;
17064
16959
  exports2.setProjectAccesses = setProjectAccesses;
16960
+ exports2.setProjectAttachment = setProjectAttachment;
17065
16961
  exports2.setProjectAttachments = setProjectAttachments;
17066
16962
  exports2.setProjectFileVisible = setProjectFileVisible;
17067
16963
  exports2.setProjects = setProjects;
@@ -17096,20 +16992,25 @@ var __publicField = (obj, key, value) => {
17096
16992
  exports2.updateActiveOrganization = updateActiveOrganization;
17097
16993
  exports2.updateComponent = updateComponent;
17098
16994
  exports2.updateComponentAttachment = updateComponentAttachment;
16995
+ exports2.updateComponentAttachments = updateComponentAttachments;
17099
16996
  exports2.updateComponentTypeAttachment = updateComponentTypeAttachment;
16997
+ exports2.updateComponentTypeAttachments = updateComponentTypeAttachments;
17100
16998
  exports2.updateDocumentAttachment = updateDocumentAttachment;
16999
+ exports2.updateDocumentAttachments = updateDocumentAttachments;
17101
17000
  exports2.updateDocuments = updateDocuments;
17102
17001
  exports2.updateFormSubmission = updateFormSubmission;
17103
17002
  exports2.updateFormSubmissionAttachments = updateFormSubmissionAttachments;
17104
17003
  exports2.updateFormSubmissions = updateFormSubmissions;
17105
17004
  exports2.updateIssue = updateIssue;
17106
17005
  exports2.updateIssueAttachment = updateIssueAttachment;
17006
+ exports2.updateIssueAttachments = updateIssueAttachments;
17107
17007
  exports2.updateIssueType = updateIssueType;
17108
17008
  exports2.updateLicense = updateLicense;
17109
17009
  exports2.updateOrCreateProject = updateOrCreateProject;
17110
17010
  exports2.updateOrganizationAccess = updateOrganizationAccess;
17111
17011
  exports2.updateProjectAccess = updateProjectAccess;
17112
17012
  exports2.updateProjectAttachment = updateProjectAttachment;
17013
+ exports2.updateProjectAttachments = updateProjectAttachments;
17113
17014
  exports2.updateStages = updateStages;
17114
17015
  exports2.updateTeam = updateTeam;
17115
17016
  exports2.useAppDispatch = useAppDispatch;