@overmap-ai/core 1.0.43-projects-licensing.5 → 1.0.43-tiptap.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.
@@ -1505,8 +1505,44 @@ var __publicField = (obj, key, value) => {
1505
1505
  return hiddenCategoryCount;
1506
1506
  };
1507
1507
  const categoryReducer = categorySlice.reducer;
1508
+ function setAttachments(state, action) {
1509
+ for (const attachment of action.payload) {
1510
+ state.attachments[attachment.offline_id] = attachment;
1511
+ }
1512
+ }
1513
+ function addAttachment(state, action) {
1514
+ if (action.payload.offline_id in state.attachments) {
1515
+ throw new Error(`Attachment ${action.payload.offline_id} already exists.`);
1516
+ }
1517
+ state.attachments[action.payload.offline_id] = action.payload;
1518
+ }
1519
+ function addAttachments(state, action) {
1520
+ for (const attachment of action.payload) {
1521
+ state.attachments[attachment.offline_id] = attachment;
1522
+ }
1523
+ }
1524
+ function updateAttachment(state, action) {
1525
+ if (action.payload.offline_id in state.attachments) {
1526
+ state.attachments[action.payload.offline_id] = action.payload;
1527
+ } else {
1528
+ throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
1529
+ }
1530
+ }
1531
+ function removeAttachment(state, action) {
1532
+ if (action.payload in state.attachments) {
1533
+ delete state.attachments[action.payload];
1534
+ } else {
1535
+ throw new Error(`Attachment ${action.payload} does not exist.`);
1536
+ }
1537
+ }
1538
+ function removeAttachments(state, action) {
1539
+ for (const attachmentId of action.payload) {
1540
+ delete state.attachments[attachmentId];
1541
+ }
1542
+ }
1508
1543
  const initialState$k = {
1509
- components: {}
1544
+ components: {},
1545
+ attachments: {}
1510
1546
  };
1511
1547
  const componentSlice = toolkit.createSlice({
1512
1548
  name: "components",
@@ -1525,6 +1561,12 @@ var __publicField = (obj, key, value) => {
1525
1561
  state.components = toOfflineIdRecord(action.payload);
1526
1562
  prevComponents = null;
1527
1563
  },
1564
+ setComponentAttachments: setAttachments,
1565
+ addComponentAttachment: addAttachment,
1566
+ addComponentAttachments: addAttachments,
1567
+ updateComponentAttachment: updateAttachment,
1568
+ removeComponentAttachment: removeAttachment,
1569
+ removeComponentAttachments: removeAttachments,
1528
1570
  updateComponent: (state, action) => {
1529
1571
  if (action.payload.offline_id in state.components) {
1530
1572
  state.components[action.payload.offline_id] = action.payload;
@@ -1614,12 +1656,48 @@ var __publicField = (obj, key, value) => {
1614
1656
  return acc;
1615
1657
  }, []);
1616
1658
  };
1659
+ const selectComponentAttachmentMapping = (state) => state.componentReducer.attachments;
1660
+ const selectAllComponentAttachments = toolkit.createSelector(
1661
+ [selectComponentAttachmentMapping],
1662
+ (mapping) => Object.values(mapping)
1663
+ );
1664
+ const selectAttachmentsOfComponent = restructureCreateSelectorWithArgs(
1665
+ toolkit.createSelector(
1666
+ [selectAllComponentAttachments, (_state, componentId) => componentId],
1667
+ (attachments, componentId) => {
1668
+ return attachments.filter(({ component }) => componentId === component);
1669
+ }
1670
+ )
1671
+ );
1672
+ const selectAttachmentsOfComponentByType = restructureCreateSelectorWithArgs(
1673
+ toolkit.createSelector(
1674
+ [selectAllComponentAttachments, (_state, componentId) => componentId],
1675
+ (attachments, componentId) => {
1676
+ const attachmentsOfComponent = attachments.filter(({ component }) => componentId === component);
1677
+ const fileAttachments = attachmentsOfComponent.filter(
1678
+ // this null check here is necessary, there are cases where file_type is null or undefined
1679
+ ({ file_type }) => !file_type || !file_type.startsWith("image/")
1680
+ );
1681
+ const imageAttachments = attachmentsOfComponent.filter(
1682
+ // this null check here is necessary, there are cases where file_type is null or undefined
1683
+ ({ file_type }) => file_type && file_type.startsWith("image/")
1684
+ );
1685
+ return { fileAttachments, imageAttachments };
1686
+ }
1687
+ )
1688
+ );
1617
1689
  const {
1618
1690
  addComponent,
1619
1691
  updateComponent,
1620
1692
  removeComponent,
1621
1693
  addComponentsInBatches,
1622
1694
  setComponents,
1695
+ setComponentAttachments,
1696
+ addComponentAttachment,
1697
+ addComponentAttachments,
1698
+ updateComponentAttachment,
1699
+ removeComponentAttachment,
1700
+ removeComponentAttachments,
1623
1701
  removeAllComponentsOfType
1624
1702
  } = componentSlice.actions;
1625
1703
  const componentReducer = componentSlice.reducer;
@@ -1779,7 +1857,8 @@ var __publicField = (obj, key, value) => {
1779
1857
  const componentStageReducer = componentStageSlice.reducer;
1780
1858
  const initialState$h = {
1781
1859
  componentTypes: {},
1782
- hiddenComponentTypeIds: {}
1860
+ hiddenComponentTypeIds: {},
1861
+ attachments: {}
1783
1862
  };
1784
1863
  const componentTypeSlice = toolkit.createSlice({
1785
1864
  name: "componentTypes",
@@ -1792,6 +1871,12 @@ var __publicField = (obj, key, value) => {
1792
1871
  setComponentTypes: (state, action) => {
1793
1872
  state.componentTypes = toOfflineIdRecord(action.payload);
1794
1873
  },
1874
+ setComponentTypeAttachments: setAttachments,
1875
+ addComponentTypeAttachment: addAttachment,
1876
+ addComponentTypeAttachments: addAttachments,
1877
+ updateComponentTypeAttachment: updateAttachment,
1878
+ removeComponentTypeAttachment: removeAttachment,
1879
+ removeComponentTypeAttachments: removeAttachments,
1795
1880
  toggleComponentTypeVisibility: (state, action) => {
1796
1881
  state.hiddenComponentTypeIds[action.payload] = !state.hiddenComponentTypeIds[action.payload];
1797
1882
  },
@@ -1841,7 +1926,50 @@ var __publicField = (obj, key, value) => {
1841
1926
  )
1842
1927
  );
1843
1928
  const selectHiddenComponentTypeIds = (state) => state.componentTypeReducer.hiddenComponentTypeIds;
1844
- const { addComponentType, setComponentTypes, toggleComponentTypeVisibility, deleteComponentType } = componentTypeSlice.actions;
1929
+ const selectComponentTypeAttachmentMapping = (state) => state.componentTypeReducer.attachments;
1930
+ const selectAllComponentTypeAttachments = toolkit.createSelector(
1931
+ [selectComponentTypeAttachmentMapping],
1932
+ (mapping) => Object.values(mapping)
1933
+ );
1934
+ const selectAttachmentsOfComponentType = restructureCreateSelectorWithArgs(
1935
+ toolkit.createSelector(
1936
+ [selectAllComponentTypeAttachments, (_state, componentTypeId) => componentTypeId],
1937
+ (attachments, componentTypeId) => {
1938
+ return attachments.filter(({ component_type }) => componentTypeId === component_type);
1939
+ }
1940
+ )
1941
+ );
1942
+ const selectAttachmentsOfComponentTypeByType = restructureCreateSelectorWithArgs(
1943
+ toolkit.createSelector(
1944
+ [selectAllComponentTypeAttachments, (_state, componentTypeId) => componentTypeId],
1945
+ (attachments, componentTypeId) => {
1946
+ const attachmentsOfComponent = attachments.filter(
1947
+ ({ component_type }) => component_type === componentTypeId
1948
+ );
1949
+ const fileAttachments = attachmentsOfComponent.filter(
1950
+ // 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/")
1952
+ );
1953
+ const imageAttachments = attachmentsOfComponent.filter(
1954
+ // 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/")
1956
+ );
1957
+ return { fileAttachments, imageAttachments };
1958
+ }
1959
+ )
1960
+ );
1961
+ const {
1962
+ addComponentType,
1963
+ setComponentTypes,
1964
+ setComponentTypeAttachments,
1965
+ addComponentTypeAttachment,
1966
+ addComponentTypeAttachments,
1967
+ updateComponentTypeAttachment,
1968
+ removeComponentTypeAttachment,
1969
+ removeComponentTypeAttachments,
1970
+ toggleComponentTypeVisibility,
1971
+ deleteComponentType
1972
+ } = componentTypeSlice.actions;
1845
1973
  const componentTypeReducer = componentTypeSlice.reducer;
1846
1974
  const initialState$g = {
1847
1975
  workspaces: {},
@@ -1931,11 +2059,7 @@ var __publicField = (obj, key, value) => {
1931
2059
  });
1932
2060
  },
1933
2061
  // TODO: Reusable function
1934
- setAttachments: (state, action) => {
1935
- for (const attachment of action.payload) {
1936
- state.attachments[attachment.offline_id] = attachment;
1937
- }
1938
- },
2062
+ setIssueAttachments: setAttachments,
1939
2063
  setActiveIssueId: (state, action) => {
1940
2064
  state.activeIssueId = action.payload;
1941
2065
  },
@@ -1946,17 +2070,8 @@ var __publicField = (obj, key, value) => {
1946
2070
  state.issues[action.payload.offline_id] = action.payload;
1947
2071
  },
1948
2072
  // TODO: Reusable function
1949
- addAttachment: (state, action) => {
1950
- if (action.payload.offline_id in state.attachments) {
1951
- throw new Error(`Attachment ${action.payload.offline_id} already exists.`);
1952
- }
1953
- state.attachments[action.payload.offline_id] = action.payload;
1954
- },
1955
- addAttachments: (state, action) => {
1956
- for (const attachment of action.payload) {
1957
- state.attachments[attachment.offline_id] = attachment;
1958
- }
1959
- },
2073
+ addIssueAttachment: addAttachment,
2074
+ addIssueAttachments: addAttachments,
1960
2075
  updateIssue: (state, action) => {
1961
2076
  if (action.payload.offline_id in state.issues) {
1962
2077
  state.issues[action.payload.offline_id] = {
@@ -1968,13 +2083,7 @@ var __publicField = (obj, key, value) => {
1968
2083
  }
1969
2084
  },
1970
2085
  // TODO: Reusable function
1971
- updateAttachment: (state, action) => {
1972
- if (action.payload.offline_id in state.attachments) {
1973
- state.attachments[action.payload.offline_id] = action.payload;
1974
- } else {
1975
- throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
1976
- }
1977
- },
2086
+ updateIssueAttachment: updateAttachment,
1978
2087
  removeIssue: (state, action) => {
1979
2088
  if (action.payload in state.issues) {
1980
2089
  delete state.issues[action.payload];
@@ -1982,15 +2091,9 @@ var __publicField = (obj, key, value) => {
1982
2091
  throw new Error(`Failed to remove issue because ID doesn't exist: ${action.payload}`);
1983
2092
  }
1984
2093
  },
1985
- removeAttachment: (state, action) => {
1986
- if (action.payload in state.attachments) {
1987
- delete state.attachments[action.payload];
1988
- } else {
1989
- throw new Error(`Attachment ${action.payload} does not exist.`);
1990
- }
1991
- },
2094
+ removeIssueAttachment: removeAttachment,
1992
2095
  removeAttachmentsOfIssue: (state, action) => {
1993
- const attachments = Object.values(state.attachments).filter((a) => a.issue_id === action.payload);
2096
+ const attachments = Object.values(state.attachments).filter((a) => a.issue === action.payload);
1994
2097
  for (const attachment of attachments) {
1995
2098
  delete state.attachments[attachment.offline_id];
1996
2099
  }
@@ -2042,25 +2145,25 @@ var __publicField = (obj, key, value) => {
2042
2145
  }
2043
2146
  });
2044
2147
  const {
2045
- addAttachment,
2046
- addAttachments,
2148
+ addIssueAttachment,
2149
+ addIssueAttachments,
2047
2150
  addIssue,
2048
2151
  addOrReplaceIssueComment,
2049
2152
  addToRecentIssues,
2050
2153
  cleanRecentIssues,
2051
- removeAttachment,
2154
+ removeIssueAttachment,
2052
2155
  removeAttachmentsOfIssue,
2053
2156
  removeIssue,
2054
2157
  removeIssueComment,
2055
2158
  removeRecentIssue,
2056
2159
  resetRecentIssues,
2057
2160
  setActiveIssueId,
2058
- setAttachments,
2161
+ setIssueAttachments,
2059
2162
  setIssueComments,
2060
2163
  setIssues,
2061
2164
  setVisibleStatuses,
2062
2165
  setVisibleUserIds,
2063
- updateAttachment,
2166
+ updateIssueAttachment,
2064
2167
  updateIssue
2065
2168
  } = issueSlice.actions;
2066
2169
  const selectIssueMapping = (state) => state.issueReducer.issues;
@@ -2120,10 +2223,8 @@ var __publicField = (obj, key, value) => {
2120
2223
  toolkit.createSelector(
2121
2224
  [selectIssueAttachmentMapping, (_state, issueId) => issueId],
2122
2225
  (attachmentMapping, issueId) => {
2123
- if (!issueId)
2124
- return void 0;
2125
2226
  return Object.values(attachmentMapping).filter(
2126
- (attachment) => attachment.issue_id === issueId && attachment.file_type && attachment.file_type.startsWith("image/")
2227
+ (attachment) => attachment.issue === issueId && attachment.file_type && attachment.file_type.startsWith("image/")
2127
2228
  );
2128
2229
  }
2129
2230
  )
@@ -2134,6 +2235,31 @@ var __publicField = (obj, key, value) => {
2134
2235
  return Object.values(commentMapping).filter((comment) => comment.issue === issueId);
2135
2236
  })
2136
2237
  );
2238
+ const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(
2239
+ toolkit.createSelector(
2240
+ [selectIssueAttachments, (_state, issueId) => issueId],
2241
+ (attachments, issueId) => {
2242
+ return attachments.filter(({ issue }) => issueId === issue);
2243
+ }
2244
+ )
2245
+ );
2246
+ const selectAttachmentsOfIssueByType = restructureCreateSelectorWithArgs(
2247
+ toolkit.createSelector(
2248
+ [selectIssueAttachments, (_state, issueId) => issueId],
2249
+ (attachments, issueId) => {
2250
+ const attachmentsOfIssue = attachments.filter(({ issue }) => issue === issueId);
2251
+ const fileAttachments = attachmentsOfIssue.filter(
2252
+ // this null check here is necessary, there are cases where file_type is null or undefined
2253
+ ({ file_type }) => !file_type || !file_type.startsWith("image/")
2254
+ );
2255
+ const imageAttachments = attachmentsOfIssue.filter(
2256
+ // this null check here is necessary, there are cases where file_type is null or undefined
2257
+ ({ file_type }) => file_type && file_type.startsWith("image/")
2258
+ );
2259
+ return { fileAttachments, imageAttachments };
2260
+ }
2261
+ )
2262
+ );
2137
2263
  const selectFileAttachmentsOfIssue = restructureCreateSelectorWithArgs(
2138
2264
  toolkit.createSelector(
2139
2265
  [selectIssueAttachmentMapping, (_state, issueId) => issueId],
@@ -2143,7 +2269,7 @@ var __publicField = (obj, key, value) => {
2143
2269
  return Object.values(attachmentMapping).filter(
2144
2270
  (attachment) => (
2145
2271
  // Files with file_type that is null or not an image file
2146
- attachment.issue_id === issueId && (!attachment.file_type || !attachment.file_type.startsWith("image/"))
2272
+ attachment.issue === issueId && (!attachment.file_type || !attachment.file_type.startsWith("image/"))
2147
2273
  )
2148
2274
  );
2149
2275
  }
@@ -4072,12 +4198,50 @@ var __publicField = (obj, key, value) => {
4072
4198
  blocks: [],
4073
4199
  blockers: []
4074
4200
  });
4075
- const allAttachments = Object.values(this.client.store.getState().issueReducer.attachments);
4201
+ const allAttachments = {
4202
+ issue_attachments: Object.values(this.client.store.getState().issueReducer.attachments),
4203
+ component_attachments: Object.values(this.client.store.getState().componentReducer.attachments),
4204
+ component_type_attachments: Object.values(this.client.store.getState().componentTypeReducer.attachments)
4205
+ };
4076
4206
  return [allAttachments, promise];
4077
4207
  }
4078
4208
  // Attachments aren't models, so we use the OptimisticGenericResult type instead
4079
- async add(attachmentPayload) {
4080
- const { description: description2, issue_id, file_sha1, offline_id } = attachmentPayload;
4209
+ async addIssueAttachment(attachmentPayload) {
4210
+ const { description: description2, issue, file_sha1, offline_id } = attachmentPayload;
4211
+ if (!attachmentPayload.file.objectURL) {
4212
+ throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4213
+ }
4214
+ const offlineAttachment = {
4215
+ ...attachmentPayload,
4216
+ file: attachmentPayload.file.objectURL,
4217
+ file_name: attachmentPayload.file.name,
4218
+ file_type: attachmentPayload.file.type
4219
+ };
4220
+ await this.client.files.addCache(attachmentPayload.file, file_sha1);
4221
+ this.client.store.dispatch(addIssueAttachment(offlineAttachment));
4222
+ const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
4223
+ const promise = this.enqueueRequest({
4224
+ description: "Create attachment",
4225
+ method: HttpMethod.POST,
4226
+ url: `/issues/${issue}/attach/`,
4227
+ blocks: [offline_id, issue],
4228
+ blockers: [file_sha1],
4229
+ payload: {
4230
+ offline_id,
4231
+ issue,
4232
+ description: description2 ?? "",
4233
+ submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4234
+ ...fileProps
4235
+ }
4236
+ });
4237
+ promise.catch((error2) => {
4238
+ this.client.store.dispatch(removeIssueAttachment(offlineAttachment.offline_id));
4239
+ throw error2;
4240
+ });
4241
+ return [offlineAttachment, promise];
4242
+ }
4243
+ async addComponentAttachment(attachmentPayload) {
4244
+ const { description: description2, component, file_sha1, offline_id } = attachmentPayload;
4081
4245
  if (!attachmentPayload.file.objectURL) {
4082
4246
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4083
4247
  }
@@ -4088,45 +4252,123 @@ var __publicField = (obj, key, value) => {
4088
4252
  file_type: attachmentPayload.file.type
4089
4253
  };
4090
4254
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4091
- this.client.store.dispatch(addAttachment(offlineAttachment));
4255
+ this.client.store.dispatch(addComponentAttachment(offlineAttachment));
4092
4256
  const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
4093
4257
  const promise = this.enqueueRequest({
4094
4258
  description: "Create attachment",
4095
4259
  method: HttpMethod.POST,
4096
- url: `/issues/${issue_id}/attach/`,
4097
- blocks: [offline_id, issue_id],
4260
+ url: `/components/${component}/attach/`,
4261
+ blocks: [offline_id, component],
4098
4262
  blockers: [file_sha1],
4099
4263
  payload: {
4100
4264
  offline_id,
4101
- issue: issue_id,
4265
+ component,
4102
4266
  description: description2 ?? "",
4103
4267
  submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4104
4268
  ...fileProps
4105
4269
  }
4106
4270
  });
4271
+ promise.catch((error2) => {
4272
+ this.client.store.dispatch(removeComponentAttachment(offlineAttachment.offline_id));
4273
+ throw error2;
4274
+ });
4107
4275
  return [offlineAttachment, promise];
4108
4276
  }
4109
- async attachFilesToIssue(filesToSubmit, issueId) {
4110
- return Promise.allSettled(
4111
- filesToSubmit.map((file) => {
4112
- if (!(file instanceof File)) {
4113
- throw new Error("Expected a File instance.");
4114
- }
4115
- const photoAttachmentPromise = async (file2) => {
4116
- const hash = await hashFile(file2);
4117
- const attachment = offline({
4118
- file: file2,
4119
- // No description for now
4120
- issue_id: issueId,
4121
- file_sha1: hash
4122
- });
4123
- return await this.add(attachment);
4124
- };
4125
- return photoAttachmentPromise(file);
4126
- })
4127
- );
4277
+ async addComponentTypeAttachment(attachmentPayload) {
4278
+ const { description: description2, component_type, file_sha1, offline_id } = attachmentPayload;
4279
+ if (!attachmentPayload.file.objectURL) {
4280
+ throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4281
+ }
4282
+ const offlineAttachment = {
4283
+ ...attachmentPayload,
4284
+ file: attachmentPayload.file.objectURL,
4285
+ file_name: attachmentPayload.file.name,
4286
+ file_type: attachmentPayload.file.type
4287
+ };
4288
+ await this.client.files.addCache(attachmentPayload.file, file_sha1);
4289
+ this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
4290
+ const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
4291
+ const promise = this.enqueueRequest({
4292
+ description: "Create attachment",
4293
+ method: HttpMethod.POST,
4294
+ url: `/components/types/${component_type}/attach/`,
4295
+ blocks: [offline_id, component_type],
4296
+ blockers: [file_sha1],
4297
+ payload: {
4298
+ offline_id,
4299
+ component_type,
4300
+ description: description2 ?? "",
4301
+ submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4302
+ ...fileProps
4303
+ }
4304
+ });
4305
+ promise.catch((error2) => {
4306
+ this.client.store.dispatch(removeComponentTypeAttachment(offlineAttachment.offline_id));
4307
+ throw error2;
4308
+ });
4309
+ return [offlineAttachment, promise];
4128
4310
  }
4129
- async replaceFile(attachmentId, newFile) {
4311
+ /** the outer Promise is needed to await the hashing of each file, which is required before offline use. If wanting to
4312
+ * attach promise handlers to the request to add the attachment in the backend, apply it on the promise returned from the
4313
+ * OptimisticModelResult. */
4314
+ attachFilesToIssue(filesToSubmit, issueId) {
4315
+ return filesToSubmit.map((file) => {
4316
+ if (!(file instanceof File)) {
4317
+ throw new Error("Expected a File instance.");
4318
+ }
4319
+ const photoAttachmentPromise = async (file2) => {
4320
+ const hash = await hashFile(file2);
4321
+ const attachment = offline({
4322
+ file: file2,
4323
+ file_name: file2.name,
4324
+ file_type: file2.type,
4325
+ issue: issueId,
4326
+ file_sha1: hash
4327
+ });
4328
+ return this.addIssueAttachment(attachment);
4329
+ };
4330
+ return photoAttachmentPromise(file);
4331
+ });
4332
+ }
4333
+ attachFilesToComponent(filesToSubmit, componentId) {
4334
+ return filesToSubmit.map((file) => {
4335
+ if (!(file instanceof File)) {
4336
+ throw new Error("Expected a File instance.");
4337
+ }
4338
+ const photoAttachmentPromise = async (file2) => {
4339
+ const hash = await hashFile(file2);
4340
+ const attachment = offline({
4341
+ file: file2,
4342
+ file_name: file2.name,
4343
+ file_type: file2.type,
4344
+ component: componentId,
4345
+ file_sha1: hash
4346
+ });
4347
+ return this.addComponentAttachment(attachment);
4348
+ };
4349
+ return photoAttachmentPromise(file);
4350
+ });
4351
+ }
4352
+ attachFilesToComponentType(filesToSubmit, componentTypeId) {
4353
+ return filesToSubmit.map((file) => {
4354
+ if (!(file instanceof File)) {
4355
+ throw new Error("Expected a File instance.");
4356
+ }
4357
+ const photoAttachmentPromise = async (file2) => {
4358
+ const hash = await hashFile(file2);
4359
+ const attachment = offline({
4360
+ file: file2,
4361
+ file_name: file2.name,
4362
+ file_type: file2.type,
4363
+ component_type: componentTypeId,
4364
+ file_sha1: hash
4365
+ });
4366
+ return this.addComponentTypeAttachment(attachment);
4367
+ };
4368
+ return photoAttachmentPromise(file);
4369
+ });
4370
+ }
4371
+ async replaceIssueAttachmentFile(attachmentId, newFile) {
4130
4372
  const { store } = this.client;
4131
4373
  const attachment = store.getState().issueReducer.attachments[attachmentId];
4132
4374
  if (!attachment)
@@ -4141,16 +4383,18 @@ var __publicField = (obj, key, value) => {
4141
4383
  if (!newFile.objectURL) {
4142
4384
  throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
4143
4385
  }
4144
- store.dispatch(updateAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) }));
4386
+ store.dispatch(
4387
+ updateIssueAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) })
4388
+ );
4145
4389
  await this.client.files.addCache(newFile, newSha1);
4146
4390
  const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
4147
- store.dispatch(updateAttachment(attachment));
4391
+ store.dispatch(updateIssueAttachment(attachment));
4148
4392
  throw e;
4149
4393
  });
4150
4394
  const promise2 = this.enqueueRequest({
4151
4395
  description: "Edit attachment",
4152
4396
  method: HttpMethod.PATCH,
4153
- url: `/attachments/${attachment.offline_id}/`,
4397
+ url: `/attachments/issues/${attachment.offline_id}/`,
4154
4398
  isResponseBlob: false,
4155
4399
  payload: fileProps,
4156
4400
  blockers: [attachmentId, newSha1],
@@ -4163,7 +4407,125 @@ var __publicField = (obj, key, value) => {
4163
4407
  } catch (e) {
4164
4408
  if (oldFile) {
4165
4409
  store.dispatch(
4166
- updateAttachment({
4410
+ updateIssueAttachment({
4411
+ ...attachment,
4412
+ file_sha1: attachment.file_sha1,
4413
+ file: URL.createObjectURL(oldFile)
4414
+ })
4415
+ );
4416
+ }
4417
+ throw e;
4418
+ }
4419
+ };
4420
+ const offlineAttachment = {
4421
+ ...attachment,
4422
+ file_sha1: newSha1,
4423
+ file: URL.createObjectURL(newFile)
4424
+ };
4425
+ const promise = performRequest2();
4426
+ return [offlineAttachment, promise];
4427
+ }
4428
+ async replaceComponentAttachmentFile(attachmentId, newFile) {
4429
+ const { store } = this.client;
4430
+ const attachment = store.getState().componentReducer.attachments[attachmentId];
4431
+ if (!attachment)
4432
+ throw new Error(`Attachment ${attachmentId} not found`);
4433
+ let oldFile = void 0;
4434
+ const newSha1 = await hashFile(newFile);
4435
+ const performRequest2 = async () => {
4436
+ oldFile = await this.client.files.fetchCache(attachment.file_sha1);
4437
+ if (!oldFile) {
4438
+ console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
4439
+ }
4440
+ if (!newFile.objectURL) {
4441
+ throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
4442
+ }
4443
+ store.dispatch(
4444
+ updateComponentAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) })
4445
+ );
4446
+ await this.client.files.addCache(newFile, newSha1);
4447
+ const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
4448
+ store.dispatch(updateComponentAttachment(attachment));
4449
+ throw e;
4450
+ });
4451
+ const promise2 = this.enqueueRequest({
4452
+ description: "Edit attachment",
4453
+ method: HttpMethod.PATCH,
4454
+ url: `/attachments/components/${attachment.offline_id}/`,
4455
+ isResponseBlob: false,
4456
+ payload: fileProps,
4457
+ blockers: [attachmentId, newSha1],
4458
+ blocks: [attachmentId, newSha1]
4459
+ });
4460
+ try {
4461
+ const result = await promise2;
4462
+ void this.client.files.removeCache(attachment.file_sha1);
4463
+ return result;
4464
+ } catch (e) {
4465
+ if (oldFile) {
4466
+ store.dispatch(
4467
+ updateComponentAttachment({
4468
+ ...attachment,
4469
+ file_sha1: attachment.file_sha1,
4470
+ file: URL.createObjectURL(oldFile)
4471
+ })
4472
+ );
4473
+ }
4474
+ throw e;
4475
+ }
4476
+ };
4477
+ const offlineAttachment = {
4478
+ ...attachment,
4479
+ file_sha1: newSha1,
4480
+ file: URL.createObjectURL(newFile)
4481
+ };
4482
+ const promise = performRequest2();
4483
+ return [offlineAttachment, promise];
4484
+ }
4485
+ async replaceComponentTypeAttachmentFile(attachmentId, newFile) {
4486
+ const { store } = this.client;
4487
+ const attachment = store.getState().componentTypeReducer.attachments[attachmentId];
4488
+ if (!attachment)
4489
+ throw new Error(`Attachment ${attachmentId} not found`);
4490
+ let oldFile = void 0;
4491
+ const newSha1 = await hashFile(newFile);
4492
+ const performRequest2 = async () => {
4493
+ oldFile = await this.client.files.fetchCache(attachment.file_sha1);
4494
+ if (!oldFile) {
4495
+ console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
4496
+ }
4497
+ if (!newFile.objectURL) {
4498
+ throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
4499
+ }
4500
+ store.dispatch(
4501
+ updateComponentTypeAttachment({
4502
+ ...attachment,
4503
+ file_sha1: newSha1,
4504
+ file: URL.createObjectURL(newFile)
4505
+ })
4506
+ );
4507
+ await this.client.files.addCache(newFile, newSha1);
4508
+ const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
4509
+ store.dispatch(updateComponentTypeAttachment(attachment));
4510
+ throw e;
4511
+ });
4512
+ const promise2 = this.enqueueRequest({
4513
+ description: "Edit attachment",
4514
+ method: HttpMethod.PATCH,
4515
+ url: `/attachments/component_types/${attachment.offline_id}/`,
4516
+ isResponseBlob: false,
4517
+ payload: fileProps,
4518
+ blockers: [attachmentId, newSha1],
4519
+ blocks: [attachmentId, newSha1]
4520
+ });
4521
+ try {
4522
+ const result = await promise2;
4523
+ void this.client.files.removeCache(attachment.file_sha1);
4524
+ return result;
4525
+ } catch (e) {
4526
+ if (oldFile) {
4527
+ store.dispatch(
4528
+ updateComponentTypeAttachment({
4167
4529
  ...attachment,
4168
4530
  file_sha1: attachment.file_sha1,
4169
4531
  file: URL.createObjectURL(oldFile)
@@ -4183,23 +4545,54 @@ var __publicField = (obj, key, value) => {
4183
4545
  }
4184
4546
  /**
4185
4547
  * Deletes an attachment and associated data in the cloud, in the Redux store and the cache.
4186
- * @param attachmentId
4548
+ * @param issueAttachmentId
4187
4549
  */
4188
- delete(attachmentId) {
4550
+ deleteIssueAttachment(issueAttachmentId) {
4189
4551
  const { store } = this.client;
4190
- const storeStateIssueReducer = store.getState().issueReducer;
4191
- const attachment = storeStateIssueReducer.attachments[attachmentId];
4552
+ const attachment = selectIssueAttachmentMapping(store.getState())[issueAttachmentId];
4192
4553
  if (!attachment) {
4193
- throw new Error(`Attachment ${attachmentId} not found`);
4554
+ throw new Error(`Attachment ${issueAttachmentId} not found`);
4555
+ }
4556
+ store.dispatch(removeIssueAttachment(issueAttachmentId));
4557
+ void this.client.files.removeCache(attachment.file_sha1);
4558
+ return this.enqueueRequest({
4559
+ description: "Delete attachment",
4560
+ method: HttpMethod.DELETE,
4561
+ url: `/attachments/issues/${issueAttachmentId}/`,
4562
+ blockers: [issueAttachmentId],
4563
+ blocks: [issueAttachmentId]
4564
+ });
4565
+ }
4566
+ deleteComponentAttachment(componentAttachmentId) {
4567
+ const { store } = this.client;
4568
+ const attachment = selectComponentAttachmentMapping(store.getState())[componentAttachmentId];
4569
+ if (!attachment) {
4570
+ throw new Error(`Attachment ${componentAttachmentId} not found`);
4194
4571
  }
4195
- store.dispatch(removeAttachment(attachmentId));
4572
+ store.dispatch(removeComponentAttachment(componentAttachmentId));
4196
4573
  void this.client.files.removeCache(attachment.file_sha1);
4197
4574
  return this.enqueueRequest({
4198
4575
  description: "Delete attachment",
4199
4576
  method: HttpMethod.DELETE,
4200
- url: `/attachments/${attachmentId}/`,
4201
- blockers: [attachmentId],
4202
- blocks: [attachmentId]
4577
+ url: `/attachments/components/${componentAttachmentId}/`,
4578
+ blockers: [componentAttachmentId],
4579
+ blocks: [componentAttachmentId]
4580
+ });
4581
+ }
4582
+ deleteComponentTypeAttachment(componentTypeAttachmentId) {
4583
+ const { store } = this.client;
4584
+ const attachment = selectComponentTypeAttachmentMapping(store.getState())[componentTypeAttachmentId];
4585
+ if (!attachment) {
4586
+ throw new Error(`Attachment ${componentTypeAttachmentId} not found`);
4587
+ }
4588
+ store.dispatch(removeComponentTypeAttachment(componentTypeAttachmentId));
4589
+ void this.client.files.removeCache(attachment.file_sha1);
4590
+ return this.enqueueRequest({
4591
+ description: "Delete attachment",
4592
+ method: HttpMethod.DELETE,
4593
+ url: `/attachments/component_types/${componentTypeAttachmentId}/`,
4594
+ blockers: [componentTypeAttachmentId],
4595
+ blocks: [componentTypeAttachmentId]
4203
4596
  });
4204
4597
  }
4205
4598
  }
@@ -4591,13 +4984,26 @@ var __publicField = (obj, key, value) => {
4591
4984
  return [component, promise];
4592
4985
  }
4593
4986
  async remove(id) {
4594
- this.client.store.dispatch(removeComponent(id));
4987
+ const { store } = this.client;
4988
+ const backupComponent = selectComponent(id)(store.getState());
4989
+ if (!backupComponent)
4990
+ throw new Error(`No component with id ${id} found in the store`);
4991
+ const attachmentsOfComponent = selectAttachmentsOfComponent(id)(store.getState());
4992
+ store.dispatch(removeComponent(id));
4993
+ if (attachmentsOfComponent.length > 0) {
4994
+ const attachmentsOfComponentIds = attachmentsOfComponent.map(({ offline_id }) => offline_id);
4995
+ store.dispatch(removeComponentAttachments(attachmentsOfComponentIds));
4996
+ }
4595
4997
  return this.enqueueRequest({
4596
4998
  description: "Delete issue",
4597
4999
  method: HttpMethod.DELETE,
4598
5000
  url: `/components/${id}/`,
4599
5001
  blockers: [id],
4600
5002
  blocks: []
5003
+ }).catch((err) => {
5004
+ store.dispatch(addComponent(backupComponent));
5005
+ store.dispatch(addComponentAttachments(attachmentsOfComponent));
5006
+ throw err;
4601
5007
  });
4602
5008
  }
4603
5009
  async deleteAllByComponentType(componentTypeId) {
@@ -4908,13 +5314,19 @@ var __publicField = (obj, key, value) => {
4908
5314
  if (!componentType) {
4909
5315
  throw new Error("Expected componentType to exist");
4910
5316
  }
4911
- const componentTypeStages = selectStagesFromComponentType(componentTypeId)(state) ?? [];
4912
- store.dispatch(
4913
- removeStages(
4914
- componentTypeStages.map((componentTypeStage) => componentTypeStage.offline_id)
4915
- )
4916
- );
5317
+ const stagesOfComponentType = selectStagesFromComponentType(componentTypeId)(state) ?? [];
5318
+ const attachmentsOfComponentType = selectAttachmentsOfComponentType(componentTypeId)(state);
4917
5319
  store.dispatch(deleteComponentType(componentTypeId));
5320
+ if (stagesOfComponentType.length > 0) {
5321
+ const stagesOfComponentTypeIds = stagesOfComponentType.map(
5322
+ (componentTypeStage) => componentTypeStage.offline_id
5323
+ );
5324
+ store.dispatch(removeStages(stagesOfComponentTypeIds));
5325
+ }
5326
+ if (attachmentsOfComponentType.length > 0) {
5327
+ const attachmentsOfComponentTypeIds = attachmentsOfComponentType.map(({ offline_id }) => offline_id);
5328
+ store.dispatch(removeComponentTypeAttachments(attachmentsOfComponentTypeIds));
5329
+ }
4918
5330
  return this.enqueueRequest({
4919
5331
  description: "Delete ComponentType",
4920
5332
  method: HttpMethod.DELETE,
@@ -4923,7 +5335,8 @@ var __publicField = (obj, key, value) => {
4923
5335
  blocks: []
4924
5336
  }).catch((e) => {
4925
5337
  store.dispatch(addComponentType(componentType));
4926
- store.dispatch(addStages(componentTypeStages));
5338
+ store.dispatch(addStages(stagesOfComponentType));
5339
+ store.dispatch(addComponentTypeAttachments(attachmentsOfComponentType));
4927
5340
  throw e;
4928
5341
  });
4929
5342
  }
@@ -5101,12 +5514,12 @@ var __publicField = (obj, key, value) => {
5101
5514
  if (!backup) {
5102
5515
  throw new Error(`No issue with id ${id} found in the store`);
5103
5516
  }
5104
- const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue_id === id);
5105
- const attachmentsOfIssue = selectPhotoAttachmentsOfIssue(id)(state);
5106
- store.dispatch(removeIssue(id));
5517
+ const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue === id);
5518
+ const attachmentsOfIssue = selectAttachmentsOfIssue(id)(state);
5519
+ this.client.store.dispatch(removeIssue(id));
5107
5520
  store.dispatch(addActiveProjectIssuesCount(-1));
5108
- if (attachmentsOfIssue) {
5109
- store.dispatch(removeAttachmentsOfIssue(id));
5521
+ if (attachmentsOfIssue.length > 0) {
5522
+ this.client.store.dispatch(removeAttachmentsOfIssue(id));
5110
5523
  }
5111
5524
  try {
5112
5525
  return await this.enqueueRequest({
@@ -5117,8 +5530,8 @@ var __publicField = (obj, key, value) => {
5117
5530
  blocks: []
5118
5531
  });
5119
5532
  } catch (e) {
5120
- store.dispatch(addIssue(backup));
5121
- store.dispatch(addAttachments(attachments));
5533
+ this.client.store.dispatch(addIssue(backup));
5534
+ this.client.store.dispatch(addIssueAttachments(attachments));
5122
5535
  store.dispatch(addActiveProjectIssuesCount(1));
5123
5536
  throw e;
5124
5537
  }
@@ -5294,7 +5707,10 @@ var __publicField = (obj, key, value) => {
5294
5707
  if (currentProjectId) {
5295
5708
  const [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId);
5296
5709
  void promise.then((result) => {
5297
- store.dispatch(setAttachments(result));
5710
+ const { issue_attachments, component_type_attachments, component_attachments } = result;
5711
+ store.dispatch(setIssueAttachments(issue_attachments));
5712
+ store.dispatch(setComponentAttachments(component_attachments));
5713
+ store.dispatch(setComponentTypeAttachments(component_type_attachments));
5298
5714
  });
5299
5715
  }
5300
5716
  store.dispatch(setIsFetchingInitialData(false));
@@ -6272,17 +6688,22 @@ var __publicField = (obj, key, value) => {
6272
6688
  let promise = cachedRequestPromises[requestCacheKey];
6273
6689
  let isFirstRequest = true;
6274
6690
  if (!promise) {
6275
- promise = this.enqueueRequest({
6276
- description: "Download file",
6277
- method: HttpMethod.GET,
6278
- url,
6279
- // If in development, we should assume the files are saved at localhost by the Django development server.
6280
- // Setting this to true will lead to localhost:8000 being prepended to the URL.
6281
- isExternalUrl: true,
6282
- isResponseBlob: true,
6283
- isAuthNeeded: false,
6284
- blockers: [expectedSha1],
6285
- blocks: [expectedSha1]
6691
+ promise = new Promise((resolve) => {
6692
+ void this.enqueueRequest({
6693
+ description: "Download file",
6694
+ method: HttpMethod.GET,
6695
+ url,
6696
+ // If in development, we should assume the files are saved at localhost by the Django development server.
6697
+ // Setting this to true will lead to localhost:8000 being prepended to the URL.
6698
+ isExternalUrl: true,
6699
+ isResponseBlob: true,
6700
+ isAuthNeeded: false,
6701
+ blockers: [expectedSha1],
6702
+ blocks: [expectedSha1]
6703
+ }).then((blob) => {
6704
+ const blobToFile = new File([blob], downloadedName ?? expectedSha1, { type: blob.type });
6705
+ resolve(blobToFile);
6706
+ });
6286
6707
  });
6287
6708
  cachedRequestPromises[requestCacheKey] = promise;
6288
6709
  } else {
@@ -6688,8 +7109,8 @@ var __publicField = (obj, key, value) => {
6688
7109
  }
6689
7110
  }
6690
7111
  const emptyBaseField = {
6691
- label: "Question",
6692
- description: "Optional description",
7112
+ label: "",
7113
+ description: "",
6693
7114
  required: false
6694
7115
  };
6695
7116
  class BaseField extends BaseFormElement {
@@ -12392,7 +12813,7 @@ var __publicField = (obj, key, value) => {
12392
12813
  gap: "0",
12393
12814
  ...rest,
12394
12815
  children: [
12395
- !file && /* @__PURE__ */ jsxRuntime.jsx(Flex, { width: "100%", height: "100%", align: "center", justify: "center", position: "absolute", children: /* @__PURE__ */ jsxRuntime.jsx(blocks.Spinner, {}) }),
12816
+ !file && !error2 && /* @__PURE__ */ jsxRuntime.jsx(Flex, { width: "100%", height: "100%", align: "center", justify: "center", position: "absolute", children: /* @__PURE__ */ jsxRuntime.jsx(blocks.Spinner, {}) }),
12396
12817
  /* @__PURE__ */ jsxRuntime.jsx(Inset, { className: styles$4.ImageInset, ref: imageInsetRef, clip: "padding-box", side: "y", pb: "0", children: file && !error2 && /* @__PURE__ */ jsxRuntime.jsx("img", { className: styles$4.Image, src: URL.createObjectURL(file), alt: alt ?? file.name }) }),
12397
12818
  /* @__PURE__ */ jsxRuntime.jsx(
12398
12819
  blocks.OvermapItem,
@@ -13485,14 +13906,16 @@ var __publicField = (obj, key, value) => {
13485
13906
  key: "duplicate",
13486
13907
  text: "Duplicate",
13487
13908
  buttonProps: { onClick: duplicate }
13488
- },
13489
- {
13909
+ }
13910
+ ];
13911
+ if (index2 === 0) {
13912
+ actions2.push({
13490
13913
  Icon: TrashIcon,
13491
13914
  key: "delete",
13492
13915
  text: "Delete",
13493
13916
  buttonProps: { onClick: remove2 }
13494
- }
13495
- ];
13917
+ });
13918
+ }
13496
13919
  if (type !== "section") {
13497
13920
  actions2.unshift({
13498
13921
  Icon: ImageIcon,
@@ -14665,15 +15088,19 @@ var __publicField = (obj, key, value) => {
14665
15088
  exports2.acceptProjectInvite = acceptProjectInvite;
14666
15089
  exports2.addActiveProjectFormSubmissionsCount = addActiveProjectFormSubmissionsCount;
14667
15090
  exports2.addActiveProjectIssuesCount = addActiveProjectIssuesCount;
14668
- exports2.addAttachment = addAttachment;
14669
- exports2.addAttachments = addAttachments;
14670
15091
  exports2.addCategory = addCategory;
14671
15092
  exports2.addComponent = addComponent;
15093
+ exports2.addComponentAttachment = addComponentAttachment;
15094
+ exports2.addComponentAttachments = addComponentAttachments;
14672
15095
  exports2.addComponentType = addComponentType;
15096
+ exports2.addComponentTypeAttachment = addComponentTypeAttachment;
15097
+ exports2.addComponentTypeAttachments = addComponentTypeAttachments;
14673
15098
  exports2.addComponentsInBatches = addComponentsInBatches;
14674
15099
  exports2.addEmailDomain = addEmailDomain;
14675
15100
  exports2.addFavouriteProjectId = addFavouriteProjectId;
14676
15101
  exports2.addIssue = addIssue;
15102
+ exports2.addIssueAttachment = addIssueAttachment;
15103
+ exports2.addIssueAttachments = addIssueAttachments;
14677
15104
  exports2.addLicenses = addLicenses;
14678
15105
  exports2.addOrReplaceCategories = addOrReplaceCategories;
14679
15106
  exports2.addOrReplaceIssueComment = addOrReplaceIssueComment;
@@ -14814,14 +15241,18 @@ var __publicField = (obj, key, value) => {
14814
15241
  exports2.rehydratedReducer = rehydratedReducer;
14815
15242
  exports2.rehydratedSlice = rehydratedSlice;
14816
15243
  exports2.removeAllComponentsOfType = removeAllComponentsOfType;
14817
- exports2.removeAttachment = removeAttachment;
14818
15244
  exports2.removeAttachmentsOfIssue = removeAttachmentsOfIssue;
14819
15245
  exports2.removeCategory = removeCategory;
14820
15246
  exports2.removeColor = removeColor;
14821
15247
  exports2.removeComponent = removeComponent;
15248
+ exports2.removeComponentAttachment = removeComponentAttachment;
15249
+ exports2.removeComponentAttachments = removeComponentAttachments;
15250
+ exports2.removeComponentTypeAttachment = removeComponentTypeAttachment;
15251
+ exports2.removeComponentTypeAttachments = removeComponentTypeAttachments;
14822
15252
  exports2.removeEmailDomain = removeEmailDomain;
14823
15253
  exports2.removeFavouriteProjectId = removeFavouriteProjectId;
14824
15254
  exports2.removeIssue = removeIssue;
15255
+ exports2.removeIssueAttachment = removeIssueAttachment;
14825
15256
  exports2.removeIssueComment = removeIssueComment;
14826
15257
  exports2.removeOrganizationAccess = removeOrganizationAccess;
14827
15258
  exports2.removeProjectAccess = removeProjectAccess;
@@ -14857,7 +15288,15 @@ var __publicField = (obj, key, value) => {
14857
15288
  exports2.selectActiveWorkspace = selectActiveWorkspace;
14858
15289
  exports2.selectActiveWorkspaceId = selectActiveWorkspaceId;
14859
15290
  exports2.selectAllAttachments = selectAllAttachments;
15291
+ exports2.selectAllComponentAttachments = selectAllComponentAttachments;
15292
+ exports2.selectAllComponentTypeAttachments = selectAllComponentTypeAttachments;
14860
15293
  exports2.selectAppearance = selectAppearance;
15294
+ exports2.selectAttachmentsOfComponent = selectAttachmentsOfComponent;
15295
+ exports2.selectAttachmentsOfComponentByType = selectAttachmentsOfComponentByType;
15296
+ exports2.selectAttachmentsOfComponentType = selectAttachmentsOfComponentType;
15297
+ exports2.selectAttachmentsOfComponentTypeByType = selectAttachmentsOfComponentTypeByType;
15298
+ exports2.selectAttachmentsOfIssue = selectAttachmentsOfIssue;
15299
+ exports2.selectAttachmentsOfIssueByType = selectAttachmentsOfIssueByType;
14861
15300
  exports2.selectCategories = selectCategories;
14862
15301
  exports2.selectCategoriesOfWorkspace = selectCategoriesOfWorkspace;
14863
15302
  exports2.selectCategory = selectCategory;
@@ -14869,7 +15308,9 @@ var __publicField = (obj, key, value) => {
14869
15308
  exports2.selectCompletedStageIdsForComponent = selectCompletedStageIdsForComponent;
14870
15309
  exports2.selectCompletedStages = selectCompletedStages;
14871
15310
  exports2.selectComponent = selectComponent;
15311
+ exports2.selectComponentAttachmentMapping = selectComponentAttachmentMapping;
14872
15312
  exports2.selectComponentType = selectComponentType;
15313
+ exports2.selectComponentTypeAttachmentMapping = selectComponentTypeAttachmentMapping;
14873
15314
  exports2.selectComponentTypeForm = selectComponentTypeForm;
14874
15315
  exports2.selectComponentTypeFromComponent = selectComponentTypeFromComponent;
14875
15316
  exports2.selectComponentTypeFromComponents = selectComponentTypeFromComponents;
@@ -14981,9 +15422,10 @@ var __publicField = (obj, key, value) => {
14981
15422
  exports2.setActiveProjectId = setActiveProjectId;
14982
15423
  exports2.setActiveWorkspaceId = setActiveWorkspaceId;
14983
15424
  exports2.setAppearance = setAppearance;
14984
- exports2.setAttachments = setAttachments;
14985
15425
  exports2.setCategories = setCategories;
14986
15426
  exports2.setCenterMapToProject = setCenterMapToProject;
15427
+ exports2.setComponentAttachments = setComponentAttachments;
15428
+ exports2.setComponentTypeAttachments = setComponentTypeAttachments;
14987
15429
  exports2.setComponentTypes = setComponentTypes;
14988
15430
  exports2.setComponents = setComponents;
14989
15431
  exports2.setCreateProjectType = setCreateProjectType;
@@ -14995,6 +15437,7 @@ var __publicField = (obj, key, value) => {
14995
15437
  exports2.setIsFetchingInitialData = setIsFetchingInitialData;
14996
15438
  exports2.setIsImportingProjectFile = setIsImportingProjectFile;
14997
15439
  exports2.setIsLoading = setIsLoading;
15440
+ exports2.setIssueAttachments = setIssueAttachments;
14998
15441
  exports2.setIssueComments = setIssueComments;
14999
15442
  exports2.setIssues = setIssues;
15000
15443
  exports2.setLicenses = setLicenses;
@@ -15034,9 +15477,11 @@ var __publicField = (obj, key, value) => {
15034
15477
  exports2.unhideCategory = unhideCategory;
15035
15478
  exports2.unlinkStageToForm = unlinkStageToForm;
15036
15479
  exports2.updateActiveOrganization = updateActiveOrganization;
15037
- exports2.updateAttachment = updateAttachment;
15038
15480
  exports2.updateComponent = updateComponent;
15481
+ exports2.updateComponentAttachment = updateComponentAttachment;
15482
+ exports2.updateComponentTypeAttachment = updateComponentTypeAttachment;
15039
15483
  exports2.updateIssue = updateIssue;
15484
+ exports2.updateIssueAttachment = updateIssueAttachment;
15040
15485
  exports2.updateLicense = updateLicense;
15041
15486
  exports2.updateOrCreateProject = updateOrCreateProject;
15042
15487
  exports2.updateOrCreateUserFormSubmission = updateOrCreateUserFormSubmission;