@overmap-ai/core 1.0.48-menu-improvements.0 → 1.0.48-tanstack-table.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.
@@ -1798,6 +1798,11 @@ var __publicField = (obj, key, value) => {
1798
1798
  }
1799
1799
  });
1800
1800
  const selectStageMapping = (state) => state.componentStageReducer.stages;
1801
+ const selectStage = restructureCreateSelectorWithArgs(
1802
+ toolkit.createSelector([selectStageMapping, (_state, stageId) => stageId], (stageMapping, stageId) => {
1803
+ return stageMapping[stageId];
1804
+ })
1805
+ );
1801
1806
  const selectStages = toolkit.createSelector(
1802
1807
  [selectStageMapping],
1803
1808
  (stageMapping) => {
@@ -2038,6 +2043,7 @@ var __publicField = (obj, key, value) => {
2038
2043
  issues: {},
2039
2044
  attachments: {},
2040
2045
  comments: {},
2046
+ updates: {},
2041
2047
  visibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],
2042
2048
  visibleUserIds: null,
2043
2049
  recentIssueIds: [],
@@ -2059,6 +2065,16 @@ var __publicField = (obj, key, value) => {
2059
2065
  });
2060
2066
  },
2061
2067
  setIssueAttachments: setAttachments,
2068
+ setIssueUpdates: (state, action) => {
2069
+ if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2070
+ throw new Error("Tried to use setIssues reducer with duplicate ID's");
2071
+ }
2072
+ const newUpdates = {};
2073
+ for (const update of action.payload) {
2074
+ newUpdates[update.offline_id] = update;
2075
+ }
2076
+ state.updates = newUpdates;
2077
+ },
2062
2078
  setActiveIssueId: (state, action) => {
2063
2079
  state.activeIssueId = action.payload;
2064
2080
  },
@@ -2070,6 +2086,17 @@ var __publicField = (obj, key, value) => {
2070
2086
  },
2071
2087
  addIssueAttachment: addAttachment,
2072
2088
  addIssueAttachments: addAttachments,
2089
+ addIssueUpdate: (state, action) => {
2090
+ if (action.payload.offline_id in state.updates) {
2091
+ throw new Error(`Tried to add duplicate issue update with offline_id: ${action.payload.offline_id}`);
2092
+ }
2093
+ state.updates[action.payload.offline_id] = action.payload;
2094
+ },
2095
+ addIssueUpdates: (state, action) => {
2096
+ for (const update of action.payload) {
2097
+ state.updates[update.offline_id] = update;
2098
+ }
2099
+ },
2073
2100
  updateIssue: (state, action) => {
2074
2101
  if (action.payload.offline_id in state.issues) {
2075
2102
  state.issues[action.payload.offline_id] = {
@@ -2089,6 +2116,18 @@ var __publicField = (obj, key, value) => {
2089
2116
  }
2090
2117
  },
2091
2118
  removeIssueAttachment: removeAttachment,
2119
+ removeIssueUpdate: (state, action) => {
2120
+ if (action.payload in state.updates) {
2121
+ delete state.updates[action.payload];
2122
+ } else {
2123
+ throw new Error(`Failed to remove issue update because offline_id doesn't exist: ${action.payload}`);
2124
+ }
2125
+ },
2126
+ removeIssueUpdates: (state, action) => {
2127
+ for (const updateId of action.payload) {
2128
+ delete state.updates[updateId];
2129
+ }
2130
+ },
2092
2131
  removeAttachmentsOfIssue: (state, action) => {
2093
2132
  const attachments = Object.values(state.attachments).filter((a) => a.issue === action.payload);
2094
2133
  for (const attachment of attachments) {
@@ -2101,20 +2140,55 @@ var __publicField = (obj, key, value) => {
2101
2140
  setVisibleUserIds: (state, action) => {
2102
2141
  state.visibleUserIds = [...new Set(action.payload)];
2103
2142
  },
2104
- setIssueComments: (state, action) => {
2143
+ // Comments
2144
+ addIssueComment: (state, action) => {
2145
+ if (action.payload.offline_id in state.comments) {
2146
+ throw new Error(
2147
+ `Tried to add issue comment with offline_id: ${action.payload.offline_id} that already exists`
2148
+ );
2149
+ }
2150
+ state.comments[action.payload.offline_id] = action.payload;
2151
+ },
2152
+ addIssueComments: (state, action) => {
2153
+ for (const comment of action.payload) {
2154
+ if (comment.offline_id in state.comments) {
2155
+ throw new Error(
2156
+ `Tried to add issue comment with offline_id: ${comment.offline_id} that already exists`
2157
+ );
2158
+ }
2159
+ }
2105
2160
  for (const comment of action.payload) {
2106
2161
  state.comments[comment.offline_id] = comment;
2107
2162
  }
2108
2163
  },
2164
+ setIssueComment: (state, action) => {
2165
+ state.comments[action.payload.offline_id] = action.payload;
2166
+ },
2167
+ setIssueComments: (state, action) => {
2168
+ const newComments = {};
2169
+ for (const comment of action.payload) {
2170
+ newComments[comment.offline_id] = comment;
2171
+ }
2172
+ state.comments = newComments;
2173
+ },
2109
2174
  addOrReplaceIssueComment: (state, action) => {
2110
2175
  state.comments[action.payload.offline_id] = action.payload;
2111
2176
  },
2112
2177
  removeIssueComment: (state, action) => {
2113
- if (action.payload in state.comments) {
2114
- delete state.comments[action.payload];
2115
- } else {
2178
+ if (!(action.payload in state.comments)) {
2116
2179
  throw new Error(`Failed to remove issue comment because ID doesn't exist: ${action.payload}`);
2117
2180
  }
2181
+ delete state.comments[action.payload];
2182
+ },
2183
+ removeIssueComments: (state, action) => {
2184
+ for (const commentId of action.payload) {
2185
+ if (!(commentId in state.comments)) {
2186
+ throw new Error(`Failed to remove issue comment because ID doesn't exist: ${commentId}`);
2187
+ }
2188
+ }
2189
+ for (const commentId of action.payload) {
2190
+ delete state.comments[commentId];
2191
+ }
2118
2192
  },
2119
2193
  cleanRecentIssues: (state) => {
2120
2194
  state.recentIssueIds = state.recentIssueIds.filter((recentIssue) => state.issues[recentIssue.offlineId]);
@@ -2145,23 +2219,33 @@ var __publicField = (obj, key, value) => {
2145
2219
  addIssueAttachment,
2146
2220
  addIssueAttachments,
2147
2221
  addIssue,
2222
+ addIssueUpdate,
2223
+ addIssueUpdates,
2148
2224
  addOrReplaceIssueComment,
2149
2225
  addToRecentIssues,
2150
2226
  cleanRecentIssues,
2151
2227
  removeIssueAttachment,
2152
2228
  removeAttachmentsOfIssue,
2153
2229
  removeIssue,
2154
- removeIssueComment,
2230
+ removeIssueUpdate,
2231
+ removeIssueUpdates,
2155
2232
  removeRecentIssue,
2156
2233
  resetRecentIssues,
2157
2234
  setActiveIssueId,
2158
2235
  setIssueAttachments,
2159
- setIssueComments,
2236
+ setIssueUpdates,
2160
2237
  setIssues,
2161
2238
  setVisibleStatuses,
2162
2239
  setVisibleUserIds,
2163
2240
  updateIssueAttachment,
2164
- updateIssue
2241
+ updateIssue,
2242
+ // Commments
2243
+ addIssueComment,
2244
+ addIssueComments,
2245
+ setIssueComment,
2246
+ setIssueComments,
2247
+ removeIssueComment,
2248
+ removeIssueComments
2165
2249
  } = issueSlice.actions;
2166
2250
  const selectIssueMapping = (state) => state.issueReducer.issues;
2167
2251
  const selectRecentIssueIds = (state) => state.issueReducer.recentIssueIds;
@@ -2232,6 +2316,12 @@ var __publicField = (obj, key, value) => {
2232
2316
  return Object.values(commentMapping).filter((comment) => comment.issue === issueId);
2233
2317
  })
2234
2318
  );
2319
+ const selectIssueUpdateMapping = (state) => state.issueReducer.updates;
2320
+ const selectIssueUpdatesOfIssue = restructureCreateSelectorWithArgs(
2321
+ toolkit.createSelector([selectIssueUpdateMapping, (_state, issueId) => issueId], (updates, issueId) => {
2322
+ return Object.values(updates).filter((update) => update.issue === issueId);
2323
+ })
2324
+ );
2235
2325
  const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(
2236
2326
  toolkit.createSelector(
2237
2327
  [selectIssueAttachments, (_state, issueId) => issueId],
@@ -2440,6 +2530,16 @@ var __publicField = (obj, key, value) => {
2440
2530
  OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
2441
2531
  return OrganizationAccessLevel2;
2442
2532
  })(OrganizationAccessLevel || {});
2533
+ var IssueUpdateChange = /* @__PURE__ */ ((IssueUpdateChange2) => {
2534
+ IssueUpdateChange2["STATUS"] = "status";
2535
+ IssueUpdateChange2["PRIORITY"] = "priority";
2536
+ IssueUpdateChange2["CATEGORY"] = "category";
2537
+ IssueUpdateChange2["DESCRIPTION"] = "description";
2538
+ IssueUpdateChange2["TITLE"] = "title";
2539
+ IssueUpdateChange2["ASSIGNED_TO"] = "assigned_to";
2540
+ IssueUpdateChange2["DUE_DATE"] = "due_date";
2541
+ return IssueUpdateChange2;
2542
+ })(IssueUpdateChange || {});
2443
2543
  var ProjectType = /* @__PURE__ */ ((ProjectType2) => {
2444
2544
  ProjectType2[ProjectType2["PERSONAL"] = 0] = "PERSONAL";
2445
2545
  ProjectType2[ProjectType2["ORGANIZATION"] = 2] = "ORGANIZATION";
@@ -4428,7 +4528,7 @@ var __publicField = (obj, key, value) => {
4428
4528
  }
4429
4529
  // Attachments aren't models, so we use the OptimisticGenericResult type instead
4430
4530
  async addIssueAttachment(attachmentPayload) {
4431
- const { description: description2, issue, file_sha1, offline_id } = attachmentPayload;
4531
+ const { issue, file_sha1, offline_id } = attachmentPayload;
4432
4532
  if (!attachmentPayload.file.objectURL) {
4433
4533
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4434
4534
  }
@@ -4436,7 +4536,9 @@ var __publicField = (obj, key, value) => {
4436
4536
  ...attachmentPayload,
4437
4537
  file: attachmentPayload.file.objectURL,
4438
4538
  file_name: attachmentPayload.file.name,
4439
- file_type: attachmentPayload.file.type
4539
+ file_type: attachmentPayload.file.type,
4540
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4541
+ created_by: this.client.store.getState().userReducer.currentUser.id
4440
4542
  };
4441
4543
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4442
4544
  this.client.store.dispatch(addIssueAttachment(offlineAttachment));
@@ -4448,10 +4550,7 @@ var __publicField = (obj, key, value) => {
4448
4550
  blocks: [offline_id, issue],
4449
4551
  blockers: [file_sha1],
4450
4552
  payload: {
4451
- offline_id,
4452
- issue,
4453
- description: description2 ?? "",
4454
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4553
+ ...offlineAttachment,
4455
4554
  ...fileProps
4456
4555
  }
4457
4556
  });
@@ -4462,7 +4561,7 @@ var __publicField = (obj, key, value) => {
4462
4561
  return [offlineAttachment, promise];
4463
4562
  }
4464
4563
  async addComponentAttachment(attachmentPayload) {
4465
- const { description: description2, component, file_sha1, offline_id } = attachmentPayload;
4564
+ const { component, file_sha1, offline_id } = attachmentPayload;
4466
4565
  if (!attachmentPayload.file.objectURL) {
4467
4566
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4468
4567
  }
@@ -4470,7 +4569,9 @@ var __publicField = (obj, key, value) => {
4470
4569
  ...attachmentPayload,
4471
4570
  file: attachmentPayload.file.objectURL,
4472
4571
  file_name: attachmentPayload.file.name,
4473
- file_type: attachmentPayload.file.type
4572
+ file_type: attachmentPayload.file.type,
4573
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4574
+ created_by: this.client.store.getState().userReducer.currentUser.id
4474
4575
  };
4475
4576
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4476
4577
  this.client.store.dispatch(addComponentAttachment(offlineAttachment));
@@ -4482,10 +4583,7 @@ var __publicField = (obj, key, value) => {
4482
4583
  blocks: [offline_id, component],
4483
4584
  blockers: [file_sha1],
4484
4585
  payload: {
4485
- offline_id,
4486
- component,
4487
- description: description2 ?? "",
4488
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4586
+ ...offlineAttachment,
4489
4587
  ...fileProps
4490
4588
  }
4491
4589
  });
@@ -4496,7 +4594,7 @@ var __publicField = (obj, key, value) => {
4496
4594
  return [offlineAttachment, promise];
4497
4595
  }
4498
4596
  async addComponentTypeAttachment(attachmentPayload) {
4499
- const { description: description2, component_type, file_sha1, offline_id } = attachmentPayload;
4597
+ const { component_type, file_sha1, offline_id } = attachmentPayload;
4500
4598
  if (!attachmentPayload.file.objectURL) {
4501
4599
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4502
4600
  }
@@ -4504,7 +4602,9 @@ var __publicField = (obj, key, value) => {
4504
4602
  ...attachmentPayload,
4505
4603
  file: attachmentPayload.file.objectURL,
4506
4604
  file_name: attachmentPayload.file.name,
4507
- file_type: attachmentPayload.file.type
4605
+ file_type: attachmentPayload.file.type,
4606
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4607
+ created_by: this.client.store.getState().userReducer.currentUser.id
4508
4608
  };
4509
4609
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4510
4610
  this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
@@ -4516,10 +4616,7 @@ var __publicField = (obj, key, value) => {
4516
4616
  blocks: [offline_id, component_type],
4517
4617
  blockers: [file_sha1],
4518
4618
  payload: {
4519
- offline_id,
4520
- component_type,
4521
- description: description2 ?? "",
4522
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4619
+ ...offlineAttachment,
4523
4620
  ...fileProps
4524
4621
  }
4525
4622
  });
@@ -4538,7 +4635,9 @@ var __publicField = (obj, key, value) => {
4538
4635
  ...attachmentPayload,
4539
4636
  file: attachmentPayload.file.objectURL,
4540
4637
  file_name: attachmentPayload.file.name,
4541
- file_type: attachmentPayload.file.type
4638
+ file_type: attachmentPayload.file.type,
4639
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4640
+ created_by: this.client.store.getState().userReducer.currentUser.id
4542
4641
  };
4543
4642
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4544
4643
  this.client.store.dispatch(addProjectAttachment(offlineAttachment));
@@ -4578,7 +4677,9 @@ var __publicField = (obj, key, value) => {
4578
4677
  file_name: file2.name,
4579
4678
  file_type: file2.type,
4580
4679
  issue: issueId,
4581
- file_sha1: hash
4680
+ file_sha1: hash,
4681
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4682
+ created_by: this.client.store.getState().userReducer.currentUser.id
4582
4683
  });
4583
4684
  return this.addIssueAttachment(attachment);
4584
4685
  };
@@ -4597,7 +4698,9 @@ var __publicField = (obj, key, value) => {
4597
4698
  file_name: file2.name,
4598
4699
  file_type: file2.type,
4599
4700
  component: componentId,
4600
- file_sha1: hash
4701
+ file_sha1: hash,
4702
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4703
+ created_by: this.client.store.getState().userReducer.currentUser.id
4601
4704
  });
4602
4705
  return this.addComponentAttachment(attachment);
4603
4706
  };
@@ -4616,7 +4719,9 @@ var __publicField = (obj, key, value) => {
4616
4719
  file_name: file2.name,
4617
4720
  file_type: file2.type,
4618
4721
  component_type: componentTypeId,
4619
- file_sha1: hash
4722
+ file_sha1: hash,
4723
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4724
+ created_by: this.client.store.getState().userReducer.currentUser.id
4620
4725
  });
4621
4726
  return this.addComponentTypeAttachment(attachment);
4622
4727
  };
@@ -4635,7 +4740,9 @@ var __publicField = (obj, key, value) => {
4635
4740
  file_name: file2.name,
4636
4741
  file_type: file2.type,
4637
4742
  project: projectId,
4638
- file_sha1: hash
4743
+ file_sha1: hash,
4744
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4745
+ created_by: this.client.store.getState().userReducer.currentUser.id
4639
4746
  });
4640
4747
  return this.addProjectAttachment(attachment);
4641
4748
  };
@@ -5712,49 +5819,35 @@ var __publicField = (obj, key, value) => {
5712
5819
  }
5713
5820
  }
5714
5821
  class IssueCommentService extends BaseApiService {
5822
+ // Omit author and submitted_at since these will always be set internally
5715
5823
  add(comment) {
5716
- const offlinePayload = offline(comment);
5717
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5718
5824
  const { store } = this.client;
5719
- const offlineComment = {
5720
- ...offlinePayload,
5825
+ const offlineComment = offline({
5826
+ ...comment,
5721
5827
  author: store.getState().userReducer.currentUser.id,
5722
- created_at: submittedAt
5723
- };
5724
- store.dispatch(addOrReplaceIssueComment(offlineComment));
5828
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString()
5829
+ });
5830
+ store.dispatch(addIssueComment(offlineComment));
5725
5831
  const promise = this.enqueueRequest({
5726
5832
  description: `${truncate(comment.content, 80)}`,
5727
5833
  method: HttpMethod.POST,
5728
5834
  url: `/issues/${comment.issue}/comment/`,
5729
- payload: { ...offlinePayload, submitted_at: submittedAt },
5835
+ payload: offlineComment,
5730
5836
  blockers: [comment.issue],
5731
- blocks: [offlinePayload.offline_id]
5837
+ blocks: [offlineComment.offline_id]
5838
+ });
5839
+ promise.catch(() => {
5840
+ store.dispatch(removeIssueComment(offlineComment.offline_id));
5732
5841
  });
5733
5842
  return [offlineComment, promise];
5734
5843
  }
5735
- async refreshStore() {
5844
+ update(comment) {
5736
5845
  const { store } = this.client;
5737
- const result = await this.enqueueRequest({
5738
- description: "Get comments",
5739
- method: HttpMethod.GET,
5740
- // TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
5741
- url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
5742
- blockers: [],
5743
- blocks: []
5744
- });
5745
- let filteredResult = result.filter(onlyUniqueOfflineIds);
5746
- filteredResult = filteredResult.map((comment) => {
5747
- return { ...comment };
5748
- });
5749
- if (result.length !== filteredResult.length) {
5750
- console.error(
5751
- `Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
5752
- );
5846
+ const commentToUpdate = store.getState().issueReducer.comments[comment.offline_id];
5847
+ if (!commentToUpdate) {
5848
+ throw new Error(`Comment with offline_id ${comment.offline_id} not found in store`);
5753
5849
  }
5754
- store.dispatch(setIssueComments(filteredResult));
5755
- }
5756
- update(comment) {
5757
- this.client.store.dispatch(addOrReplaceIssueComment(comment));
5850
+ store.dispatch(setIssueComment(comment));
5758
5851
  const promise = this.enqueueRequest({
5759
5852
  description: `Edit comment: ${truncate(comment.content, 80)}`,
5760
5853
  method: HttpMethod.PATCH,
@@ -5763,17 +5856,62 @@ var __publicField = (obj, key, value) => {
5763
5856
  blockers: [comment.issue],
5764
5857
  blocks: [comment.offline_id]
5765
5858
  });
5859
+ promise.catch(() => {
5860
+ store.dispatch(setIssueComment(commentToUpdate));
5861
+ });
5766
5862
  return [comment, promise];
5767
5863
  }
5768
5864
  remove(offline_id) {
5865
+ const commentToRemove = this.client.store.getState().issueReducer.comments[offline_id];
5866
+ if (!commentToRemove) {
5867
+ throw new Error(`Comment with offline_id ${offline_id} not found in store`);
5868
+ }
5769
5869
  this.client.store.dispatch(removeIssueComment(offline_id));
5770
- return this.enqueueRequest({
5870
+ const promise = this.enqueueRequest({
5771
5871
  description: "Delete comment",
5772
5872
  method: HttpMethod.DELETE,
5773
5873
  url: `/issues/comments/${offline_id}/`,
5774
5874
  blockers: [offline_id],
5775
5875
  blocks: []
5776
5876
  });
5877
+ promise.catch(() => {
5878
+ this.client.store.dispatch(addIssueComment(commentToRemove));
5879
+ });
5880
+ return promise;
5881
+ }
5882
+ async refreshStore() {
5883
+ const { store } = this.client;
5884
+ const result = await this.enqueueRequest({
5885
+ description: "Get comments",
5886
+ method: HttpMethod.GET,
5887
+ // TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
5888
+ url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
5889
+ blockers: [],
5890
+ blocks: []
5891
+ });
5892
+ store.dispatch(setIssueComments(result));
5893
+ }
5894
+ }
5895
+ class IssueUpdateService extends BaseApiService {
5896
+ async refreshStore() {
5897
+ const { store } = this.client;
5898
+ const result = await this.enqueueRequest({
5899
+ description: "Get issue updates",
5900
+ method: HttpMethod.GET,
5901
+ url: `/projects/${store.getState().projectReducer.activeProjectId}/issues/updates/`,
5902
+ blockers: [],
5903
+ blocks: []
5904
+ });
5905
+ let filteredResult = result.filter(onlyUniqueOfflineIds);
5906
+ filteredResult = filteredResult.map((comment) => {
5907
+ return { ...comment };
5908
+ });
5909
+ if (result.length !== filteredResult.length) {
5910
+ console.error(
5911
+ `Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
5912
+ );
5913
+ }
5914
+ store.dispatch(setIssueUpdates(filteredResult));
5777
5915
  }
5778
5916
  }
5779
5917
  class IssueService extends BaseApiService {
@@ -5854,7 +5992,83 @@ var __publicField = (obj, key, value) => {
5854
5992
  return [offlineIssues, promise];
5855
5993
  }
5856
5994
  update(issue) {
5995
+ const state = this.client.store.getState();
5996
+ const issueToBeUpdated = state.issueReducer.issues[issue.offline_id];
5997
+ if (!issueToBeUpdated) {
5998
+ throw new Error(
5999
+ `Attempting to update an issue with offline_id ${issue.offline_id} that doesn't exist in the store`
6000
+ );
6001
+ }
5857
6002
  this.client.store.dispatch(updateIssue(issue));
6003
+ const changes = {};
6004
+ for (const issueUpdateChange of [
6005
+ IssueUpdateChange.TITLE,
6006
+ IssueUpdateChange.DESCRIPTION,
6007
+ IssueUpdateChange.STATUS,
6008
+ IssueUpdateChange.CATEGORY,
6009
+ IssueUpdateChange.PRIORITY,
6010
+ IssueUpdateChange.ASSIGNED_TO,
6011
+ IssueUpdateChange.DUE_DATE
6012
+ ]) {
6013
+ if (issueUpdateChange in issue && issue[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {
6014
+ switch (issueUpdateChange) {
6015
+ case "category": {
6016
+ let categoryOrNull = null;
6017
+ const categoryIdOrNull = issue[issueUpdateChange];
6018
+ if (categoryIdOrNull) {
6019
+ categoryOrNull = state.categoryReducer.categories[categoryIdOrNull] ?? null;
6020
+ if (!categoryOrNull)
6021
+ throw new Error(
6022
+ `Trying to update issue category to ${categoryIdOrNull} which does not exist in store`
6023
+ );
6024
+ }
6025
+ changes[issueUpdateChange] = categoryOrNull ? {
6026
+ name: categoryOrNull.name,
6027
+ color: categoryOrNull.color,
6028
+ offline_id: categoryOrNull.offline_id
6029
+ } : null;
6030
+ break;
6031
+ }
6032
+ case "assigned_to": {
6033
+ let userOrNull = null;
6034
+ const userIdOrNull = issue[issueUpdateChange];
6035
+ if (userIdOrNull) {
6036
+ userOrNull = state.userReducer.users[userIdOrNull] ?? null;
6037
+ if (!userOrNull)
6038
+ throw new Error(
6039
+ `Trying to update issue assigned_to to ${userIdOrNull} which does not exist in store`
6040
+ );
6041
+ }
6042
+ changes[issueUpdateChange] = userOrNull ? {
6043
+ full_name: userOrNull.username,
6044
+ id: userOrNull.id
6045
+ } : null;
6046
+ break;
6047
+ }
6048
+ case "description":
6049
+ changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
6050
+ break;
6051
+ case "title":
6052
+ changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
6053
+ break;
6054
+ case "priority":
6055
+ changes[issueUpdateChange] = issue[issueUpdateChange];
6056
+ break;
6057
+ case "status":
6058
+ changes[issueUpdateChange] = issue[issueUpdateChange];
6059
+ break;
6060
+ case "due_date":
6061
+ changes[issueUpdateChange] = issue[issueUpdateChange] ? issue[issueUpdateChange] : null;
6062
+ }
6063
+ }
6064
+ }
6065
+ const offlineIssueUpdate = offline({
6066
+ created_by: state.userReducer.currentUser.id,
6067
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
6068
+ issue: issueToBeUpdated.offline_id,
6069
+ changes
6070
+ });
6071
+ this.client.store.dispatch(addIssueUpdate(offlineIssueUpdate));
5858
6072
  const promise = this.enqueueRequest({
5859
6073
  description: "Edit issue",
5860
6074
  method: HttpMethod.PATCH,
@@ -5863,23 +6077,30 @@ var __publicField = (obj, key, value) => {
5863
6077
  blockers: [issue.offline_id],
5864
6078
  blocks: [issue.offline_id]
5865
6079
  });
6080
+ promise.catch(() => {
6081
+ this.client.store.dispatch(updateIssue(issueToBeUpdated));
6082
+ this.client.store.dispatch(removeIssueUpdate(offlineIssueUpdate.offline_id));
6083
+ });
5866
6084
  const fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id];
5867
6085
  return [fullIssue, promise];
5868
6086
  }
5869
6087
  async remove(id) {
5870
6088
  const { store } = this.client;
5871
6089
  const state = store.getState();
6090
+ const dispatch = store.dispatch;
5872
6091
  const backup = state.issueReducer.issues[id];
5873
6092
  if (!backup) {
5874
6093
  throw new Error(`No issue with id ${id} found in the store`);
5875
6094
  }
5876
6095
  const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue === id);
5877
6096
  const attachmentsOfIssue = selectAttachmentsOfIssue(id)(state);
5878
- this.client.store.dispatch(removeIssue(id));
5879
- store.dispatch(addActiveProjectIssuesCount(-1));
5880
- if (attachmentsOfIssue.length > 0) {
5881
- this.client.store.dispatch(removeAttachmentsOfIssue(id));
5882
- }
6097
+ const updatesOfIssue = selectIssueUpdatesOfIssue(id)(state);
6098
+ dispatch(removeIssue(id));
6099
+ dispatch(addActiveProjectIssuesCount(-1));
6100
+ if (attachmentsOfIssue.length > 0)
6101
+ dispatch(removeAttachmentsOfIssue(id));
6102
+ if (updatesOfIssue.length > 0)
6103
+ dispatch(removeIssueUpdates(updatesOfIssue.map(({ offline_id }) => offline_id)));
5883
6104
  try {
5884
6105
  return await this.enqueueRequest({
5885
6106
  description: "Delete issue",
@@ -5889,9 +6110,10 @@ var __publicField = (obj, key, value) => {
5889
6110
  blocks: []
5890
6111
  });
5891
6112
  } catch (e) {
5892
- this.client.store.dispatch(addIssue(backup));
5893
- this.client.store.dispatch(addIssueAttachments(attachments));
5894
- store.dispatch(addActiveProjectIssuesCount(1));
6113
+ dispatch(addIssue(backup));
6114
+ dispatch(addIssueAttachments(attachments));
6115
+ dispatch(addIssueUpdates(updatesOfIssue));
6116
+ dispatch(addActiveProjectIssuesCount(1));
5895
6117
  throw e;
5896
6118
  }
5897
6119
  }
@@ -6073,6 +6295,7 @@ var __publicField = (obj, key, value) => {
6073
6295
  store.dispatch(setProjectAttachments(project_attachments));
6074
6296
  });
6075
6297
  void this.client.documents.refreshStore();
6298
+ void this.client.issueUpdates.refreshStore();
6076
6299
  }
6077
6300
  store.dispatch(setIsFetchingInitialData(false));
6078
6301
  if (overwrite) {
@@ -7540,6 +7763,7 @@ var __publicField = (obj, key, value) => {
7540
7763
  __publicField(this, "organizationAccess", new OrganizationAccessService(this));
7541
7764
  __publicField(this, "issues", new IssueService(this));
7542
7765
  __publicField(this, "issueComments", new IssueCommentService(this));
7766
+ __publicField(this, "issueUpdates", new IssueUpdateService(this));
7543
7767
  __publicField(this, "workspaces", new WorkspaceService(this));
7544
7768
  __publicField(this, "main", new MainService(this));
7545
7769
  __publicField(this, "components", new ComponentService(this));
@@ -14197,17 +14421,15 @@ var __publicField = (obj, key, value) => {
14197
14421
  Action.key
14198
14422
  )) }),
14199
14423
  /* @__PURE__ */ jsxRuntime.jsx(Box, { display: forMobile(true, "block"), children: /* @__PURE__ */ jsxRuntime.jsx(
14200
- blocks.DropdownItemMenu,
14424
+ blocks.OvermapDropdownMenu,
14201
14425
  {
14202
14426
  trigger: /* @__PURE__ */ jsxRuntime.jsx(blocks.IconButton, { variant: "ghost", "aria-label": "Actions menu", children: /* @__PURE__ */ jsxRuntime.jsx(blocks.RiIcon, { icon: "RiMore2Line" }) }),
14203
14427
  items: actions.map((Action) => {
14204
14428
  var _a2;
14205
14429
  return {
14206
- content: /* @__PURE__ */ jsxRuntime.jsxs(blocks.Flex, { gap: "2", align: "center", children: [
14207
- /* @__PURE__ */ jsxRuntime.jsx(Action.Icon, {}),
14208
- Action.text
14209
- ] }, Action.key),
14210
- onSelect: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
14430
+ leftSlot: /* @__PURE__ */ jsxRuntime.jsx(Action.Icon, {}),
14431
+ children: Action.text,
14432
+ onClick: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
14211
14433
  };
14212
14434
  })
14213
14435
  }
@@ -14265,10 +14487,8 @@ var __publicField = (obj, key, value) => {
14265
14487
  const field = FieldTypeToClsMapping[identifier];
14266
14488
  const Icon = field.Icon;
14267
14489
  return {
14268
- content: /* @__PURE__ */ jsxRuntime.jsxs(blocks.Flex, { align: "center", gap: "2", children: [
14269
- /* @__PURE__ */ jsxRuntime.jsx(Icon, {}),
14270
- /* @__PURE__ */ jsxRuntime.jsx(blocks.Text, { children: field.fieldTypeName })
14271
- ] }, identifier),
14490
+ children: field.fieldTypeName,
14491
+ leftSlot: /* @__PURE__ */ jsxRuntime.jsx(Icon, {}),
14272
14492
  value: identifier,
14273
14493
  onSelect: () => {
14274
14494
  onSelect(identifier);
@@ -14472,7 +14692,7 @@ var __publicField = (obj, key, value) => {
14472
14692
  }
14473
14693
  ),
14474
14694
  /* @__PURE__ */ jsxRuntime.jsxs(blocks.Flex, { align: "center", gap: "3", children: [
14475
- /* @__PURE__ */ jsxRuntime.jsx(blocks.Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.content }),
14695
+ /* @__PURE__ */ jsxRuntime.jsx(blocks.Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.children }),
14476
14696
  showPopoverInputs && /* @__PURE__ */ jsxRuntime.jsx(FieldSettingsPopover, { popoverInputs, hasError: popoverHasErrors })
14477
14697
  ] }),
14478
14698
  resolvedImage && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -14833,7 +15053,7 @@ var __publicField = (obj, key, value) => {
14833
15053
  )),
14834
15054
  droppableProvided.placeholder,
14835
15055
  /* @__PURE__ */ jsxRuntime.jsx(
14836
- blocks.DropdownItemMenu,
15056
+ blocks.OvermapDropdownMenu,
14837
15057
  {
14838
15058
  trigger: /* @__PURE__ */ jsxRuntime.jsxs(blocks.Button, { type: "button", variant: "soft", children: [
14839
15059
  /* @__PURE__ */ jsxRuntime.jsx(blocks.RiIcon, { icon: "RiAddLine" }),
@@ -15268,6 +15488,8 @@ var __publicField = (obj, key, value) => {
15268
15488
  exports2.IssuePriority = IssuePriority;
15269
15489
  exports2.IssueService = IssueService;
15270
15490
  exports2.IssueStatus = IssueStatus;
15491
+ exports2.IssueUpdateChange = IssueUpdateChange;
15492
+ exports2.IssueUpdateService = IssueUpdateService;
15271
15493
  exports2.LicenseLevel = LicenseLevel;
15272
15494
  exports2.LicenseService = LicenseService;
15273
15495
  exports2.LicenseStatus = LicenseStatus;
@@ -15331,6 +15553,10 @@ var __publicField = (obj, key, value) => {
15331
15553
  exports2.addIssue = addIssue;
15332
15554
  exports2.addIssueAttachment = addIssueAttachment;
15333
15555
  exports2.addIssueAttachments = addIssueAttachments;
15556
+ exports2.addIssueComment = addIssueComment;
15557
+ exports2.addIssueComments = addIssueComments;
15558
+ exports2.addIssueUpdate = addIssueUpdate;
15559
+ exports2.addIssueUpdates = addIssueUpdates;
15334
15560
  exports2.addLicenses = addLicenses;
15335
15561
  exports2.addOrReplaceCategories = addOrReplaceCategories;
15336
15562
  exports2.addOrReplaceIssueComment = addOrReplaceIssueComment;
@@ -15490,6 +15716,9 @@ var __publicField = (obj, key, value) => {
15490
15716
  exports2.removeIssue = removeIssue;
15491
15717
  exports2.removeIssueAttachment = removeIssueAttachment;
15492
15718
  exports2.removeIssueComment = removeIssueComment;
15719
+ exports2.removeIssueComments = removeIssueComments;
15720
+ exports2.removeIssueUpdate = removeIssueUpdate;
15721
+ exports2.removeIssueUpdates = removeIssueUpdates;
15493
15722
  exports2.removeOrganizationAccess = removeOrganizationAccess;
15494
15723
  exports2.removeProjectAccess = removeProjectAccess;
15495
15724
  exports2.removeProjectAccessesOfProject = removeProjectAccessesOfProject;
@@ -15591,6 +15820,8 @@ var __publicField = (obj, key, value) => {
15591
15820
  exports2.selectIssueAttachmentMapping = selectIssueAttachmentMapping;
15592
15821
  exports2.selectIssueAttachments = selectIssueAttachments;
15593
15822
  exports2.selectIssueMapping = selectIssueMapping;
15823
+ exports2.selectIssueUpdateMapping = selectIssueUpdateMapping;
15824
+ exports2.selectIssueUpdatesOfIssue = selectIssueUpdatesOfIssue;
15594
15825
  exports2.selectIssues = selectIssues;
15595
15826
  exports2.selectLatestFormRevision = selectLatestFormRevision;
15596
15827
  exports2.selectLatestRetryTime = selectLatestRetryTime;
@@ -15642,6 +15873,7 @@ var __publicField = (obj, key, value) => {
15642
15873
  exports2.selectSortedOrganizationUsers = selectSortedOrganizationUsers;
15643
15874
  exports2.selectSortedProjectUsers = selectSortedProjectUsers;
15644
15875
  exports2.selectSortedProjects = selectSortedProjects;
15876
+ exports2.selectStage = selectStage;
15645
15877
  exports2.selectStageFormIdsFromStageIds = selectStageFormIdsFromStageIds;
15646
15878
  exports2.selectStageMapping = selectStageMapping;
15647
15879
  exports2.selectStages = selectStages;
@@ -15686,7 +15918,9 @@ var __publicField = (obj, key, value) => {
15686
15918
  exports2.setIsImportingProjectFile = setIsImportingProjectFile;
15687
15919
  exports2.setIsLoading = setIsLoading;
15688
15920
  exports2.setIssueAttachments = setIssueAttachments;
15921
+ exports2.setIssueComment = setIssueComment;
15689
15922
  exports2.setIssueComments = setIssueComments;
15923
+ exports2.setIssueUpdates = setIssueUpdates;
15690
15924
  exports2.setIssues = setIssues;
15691
15925
  exports2.setLicenses = setLicenses;
15692
15926
  exports2.setLoggedIn = setLoggedIn;