@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.
- package/dist/forms/builder/hooks.d.ts +2 -1
- package/dist/overmap-core.js +316 -82
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +315 -81
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/sdk.d.ts +2 -1
- package/dist/sdk/services/IssueCommentService.d.ts +2 -2
- package/dist/sdk/services/IssueUpdateService.d.ts +4 -0
- package/dist/sdk/services/index.d.ts +1 -0
- package/dist/store/slices/componentStageSlice.d.ts +1 -0
- package/dist/store/slices/issueSlice.d.ts +21 -3
- package/dist/typings/models/attachments.d.ts +3 -1
- package/dist/typings/models/issues.d.ts +35 -1
- package/package.json +5 -5
package/dist/overmap-core.js
CHANGED
|
@@ -8,7 +8,7 @@ var _a;
|
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import React__default, { useState, useEffect, useRef, memo, useMemo, useCallback, createContext, createElement, useContext, forwardRef, Children, isValidElement, cloneElement, Fragment as Fragment$1, useLayoutEffect, useReducer, lazy, Suspense } from "react";
|
|
10
10
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
11
|
-
import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, useViewportSize, Overlay, ButtonGroup, Spinner, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, Button, ButtonList, divButtonProps,
|
|
11
|
+
import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, useViewportSize, Overlay, ButtonGroup, Spinner, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, Button, ButtonList, divButtonProps, OvermapDropdownMenu, Input, useAlertDialog } from "@overmap-ai/blocks";
|
|
12
12
|
import { DepGraph } from "dependency-graph";
|
|
13
13
|
import { offline as offline$1 } from "@redux-offline/redux-offline";
|
|
14
14
|
import offlineConfig from "@redux-offline/redux-offline/lib/defaults";
|
|
@@ -1807,6 +1807,11 @@ const componentStageSlice = createSlice({
|
|
|
1807
1807
|
}
|
|
1808
1808
|
});
|
|
1809
1809
|
const selectStageMapping = (state) => state.componentStageReducer.stages;
|
|
1810
|
+
const selectStage = restructureCreateSelectorWithArgs(
|
|
1811
|
+
createSelector([selectStageMapping, (_state, stageId) => stageId], (stageMapping, stageId) => {
|
|
1812
|
+
return stageMapping[stageId];
|
|
1813
|
+
})
|
|
1814
|
+
);
|
|
1810
1815
|
const selectStages = createSelector(
|
|
1811
1816
|
[selectStageMapping],
|
|
1812
1817
|
(stageMapping) => {
|
|
@@ -2047,6 +2052,7 @@ const initialState$g = {
|
|
|
2047
2052
|
issues: {},
|
|
2048
2053
|
attachments: {},
|
|
2049
2054
|
comments: {},
|
|
2055
|
+
updates: {},
|
|
2050
2056
|
visibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],
|
|
2051
2057
|
visibleUserIds: null,
|
|
2052
2058
|
recentIssueIds: [],
|
|
@@ -2068,6 +2074,16 @@ const issueSlice = createSlice({
|
|
|
2068
2074
|
});
|
|
2069
2075
|
},
|
|
2070
2076
|
setIssueAttachments: setAttachments,
|
|
2077
|
+
setIssueUpdates: (state, action) => {
|
|
2078
|
+
if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
|
|
2079
|
+
throw new Error("Tried to use setIssues reducer with duplicate ID's");
|
|
2080
|
+
}
|
|
2081
|
+
const newUpdates = {};
|
|
2082
|
+
for (const update of action.payload) {
|
|
2083
|
+
newUpdates[update.offline_id] = update;
|
|
2084
|
+
}
|
|
2085
|
+
state.updates = newUpdates;
|
|
2086
|
+
},
|
|
2071
2087
|
setActiveIssueId: (state, action) => {
|
|
2072
2088
|
state.activeIssueId = action.payload;
|
|
2073
2089
|
},
|
|
@@ -2079,6 +2095,17 @@ const issueSlice = createSlice({
|
|
|
2079
2095
|
},
|
|
2080
2096
|
addIssueAttachment: addAttachment,
|
|
2081
2097
|
addIssueAttachments: addAttachments,
|
|
2098
|
+
addIssueUpdate: (state, action) => {
|
|
2099
|
+
if (action.payload.offline_id in state.updates) {
|
|
2100
|
+
throw new Error(`Tried to add duplicate issue update with offline_id: ${action.payload.offline_id}`);
|
|
2101
|
+
}
|
|
2102
|
+
state.updates[action.payload.offline_id] = action.payload;
|
|
2103
|
+
},
|
|
2104
|
+
addIssueUpdates: (state, action) => {
|
|
2105
|
+
for (const update of action.payload) {
|
|
2106
|
+
state.updates[update.offline_id] = update;
|
|
2107
|
+
}
|
|
2108
|
+
},
|
|
2082
2109
|
updateIssue: (state, action) => {
|
|
2083
2110
|
if (action.payload.offline_id in state.issues) {
|
|
2084
2111
|
state.issues[action.payload.offline_id] = {
|
|
@@ -2098,6 +2125,18 @@ const issueSlice = createSlice({
|
|
|
2098
2125
|
}
|
|
2099
2126
|
},
|
|
2100
2127
|
removeIssueAttachment: removeAttachment,
|
|
2128
|
+
removeIssueUpdate: (state, action) => {
|
|
2129
|
+
if (action.payload in state.updates) {
|
|
2130
|
+
delete state.updates[action.payload];
|
|
2131
|
+
} else {
|
|
2132
|
+
throw new Error(`Failed to remove issue update because offline_id doesn't exist: ${action.payload}`);
|
|
2133
|
+
}
|
|
2134
|
+
},
|
|
2135
|
+
removeIssueUpdates: (state, action) => {
|
|
2136
|
+
for (const updateId of action.payload) {
|
|
2137
|
+
delete state.updates[updateId];
|
|
2138
|
+
}
|
|
2139
|
+
},
|
|
2101
2140
|
removeAttachmentsOfIssue: (state, action) => {
|
|
2102
2141
|
const attachments = Object.values(state.attachments).filter((a) => a.issue === action.payload);
|
|
2103
2142
|
for (const attachment of attachments) {
|
|
@@ -2110,20 +2149,55 @@ const issueSlice = createSlice({
|
|
|
2110
2149
|
setVisibleUserIds: (state, action) => {
|
|
2111
2150
|
state.visibleUserIds = [...new Set(action.payload)];
|
|
2112
2151
|
},
|
|
2113
|
-
|
|
2152
|
+
// Comments
|
|
2153
|
+
addIssueComment: (state, action) => {
|
|
2154
|
+
if (action.payload.offline_id in state.comments) {
|
|
2155
|
+
throw new Error(
|
|
2156
|
+
`Tried to add issue comment with offline_id: ${action.payload.offline_id} that already exists`
|
|
2157
|
+
);
|
|
2158
|
+
}
|
|
2159
|
+
state.comments[action.payload.offline_id] = action.payload;
|
|
2160
|
+
},
|
|
2161
|
+
addIssueComments: (state, action) => {
|
|
2162
|
+
for (const comment of action.payload) {
|
|
2163
|
+
if (comment.offline_id in state.comments) {
|
|
2164
|
+
throw new Error(
|
|
2165
|
+
`Tried to add issue comment with offline_id: ${comment.offline_id} that already exists`
|
|
2166
|
+
);
|
|
2167
|
+
}
|
|
2168
|
+
}
|
|
2114
2169
|
for (const comment of action.payload) {
|
|
2115
2170
|
state.comments[comment.offline_id] = comment;
|
|
2116
2171
|
}
|
|
2117
2172
|
},
|
|
2173
|
+
setIssueComment: (state, action) => {
|
|
2174
|
+
state.comments[action.payload.offline_id] = action.payload;
|
|
2175
|
+
},
|
|
2176
|
+
setIssueComments: (state, action) => {
|
|
2177
|
+
const newComments = {};
|
|
2178
|
+
for (const comment of action.payload) {
|
|
2179
|
+
newComments[comment.offline_id] = comment;
|
|
2180
|
+
}
|
|
2181
|
+
state.comments = newComments;
|
|
2182
|
+
},
|
|
2118
2183
|
addOrReplaceIssueComment: (state, action) => {
|
|
2119
2184
|
state.comments[action.payload.offline_id] = action.payload;
|
|
2120
2185
|
},
|
|
2121
2186
|
removeIssueComment: (state, action) => {
|
|
2122
|
-
if (action.payload in state.comments) {
|
|
2123
|
-
delete state.comments[action.payload];
|
|
2124
|
-
} else {
|
|
2187
|
+
if (!(action.payload in state.comments)) {
|
|
2125
2188
|
throw new Error(`Failed to remove issue comment because ID doesn't exist: ${action.payload}`);
|
|
2126
2189
|
}
|
|
2190
|
+
delete state.comments[action.payload];
|
|
2191
|
+
},
|
|
2192
|
+
removeIssueComments: (state, action) => {
|
|
2193
|
+
for (const commentId of action.payload) {
|
|
2194
|
+
if (!(commentId in state.comments)) {
|
|
2195
|
+
throw new Error(`Failed to remove issue comment because ID doesn't exist: ${commentId}`);
|
|
2196
|
+
}
|
|
2197
|
+
}
|
|
2198
|
+
for (const commentId of action.payload) {
|
|
2199
|
+
delete state.comments[commentId];
|
|
2200
|
+
}
|
|
2127
2201
|
},
|
|
2128
2202
|
cleanRecentIssues: (state) => {
|
|
2129
2203
|
state.recentIssueIds = state.recentIssueIds.filter((recentIssue) => state.issues[recentIssue.offlineId]);
|
|
@@ -2154,23 +2228,33 @@ const {
|
|
|
2154
2228
|
addIssueAttachment,
|
|
2155
2229
|
addIssueAttachments,
|
|
2156
2230
|
addIssue,
|
|
2231
|
+
addIssueUpdate,
|
|
2232
|
+
addIssueUpdates,
|
|
2157
2233
|
addOrReplaceIssueComment,
|
|
2158
2234
|
addToRecentIssues,
|
|
2159
2235
|
cleanRecentIssues,
|
|
2160
2236
|
removeIssueAttachment,
|
|
2161
2237
|
removeAttachmentsOfIssue,
|
|
2162
2238
|
removeIssue,
|
|
2163
|
-
|
|
2239
|
+
removeIssueUpdate,
|
|
2240
|
+
removeIssueUpdates,
|
|
2164
2241
|
removeRecentIssue,
|
|
2165
2242
|
resetRecentIssues,
|
|
2166
2243
|
setActiveIssueId,
|
|
2167
2244
|
setIssueAttachments,
|
|
2168
|
-
|
|
2245
|
+
setIssueUpdates,
|
|
2169
2246
|
setIssues,
|
|
2170
2247
|
setVisibleStatuses,
|
|
2171
2248
|
setVisibleUserIds,
|
|
2172
2249
|
updateIssueAttachment,
|
|
2173
|
-
updateIssue
|
|
2250
|
+
updateIssue,
|
|
2251
|
+
// Commments
|
|
2252
|
+
addIssueComment,
|
|
2253
|
+
addIssueComments,
|
|
2254
|
+
setIssueComment,
|
|
2255
|
+
setIssueComments,
|
|
2256
|
+
removeIssueComment,
|
|
2257
|
+
removeIssueComments
|
|
2174
2258
|
} = issueSlice.actions;
|
|
2175
2259
|
const selectIssueMapping = (state) => state.issueReducer.issues;
|
|
2176
2260
|
const selectRecentIssueIds = (state) => state.issueReducer.recentIssueIds;
|
|
@@ -2241,6 +2325,12 @@ const selectCommentsOfIssue = restructureCreateSelectorWithArgs(
|
|
|
2241
2325
|
return Object.values(commentMapping).filter((comment) => comment.issue === issueId);
|
|
2242
2326
|
})
|
|
2243
2327
|
);
|
|
2328
|
+
const selectIssueUpdateMapping = (state) => state.issueReducer.updates;
|
|
2329
|
+
const selectIssueUpdatesOfIssue = restructureCreateSelectorWithArgs(
|
|
2330
|
+
createSelector([selectIssueUpdateMapping, (_state, issueId) => issueId], (updates, issueId) => {
|
|
2331
|
+
return Object.values(updates).filter((update) => update.issue === issueId);
|
|
2332
|
+
})
|
|
2333
|
+
);
|
|
2244
2334
|
const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(
|
|
2245
2335
|
createSelector(
|
|
2246
2336
|
[selectIssueAttachments, (_state, issueId) => issueId],
|
|
@@ -2449,6 +2539,16 @@ var OrganizationAccessLevel = /* @__PURE__ */ ((OrganizationAccessLevel2) => {
|
|
|
2449
2539
|
OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
|
|
2450
2540
|
return OrganizationAccessLevel2;
|
|
2451
2541
|
})(OrganizationAccessLevel || {});
|
|
2542
|
+
var IssueUpdateChange = /* @__PURE__ */ ((IssueUpdateChange2) => {
|
|
2543
|
+
IssueUpdateChange2["STATUS"] = "status";
|
|
2544
|
+
IssueUpdateChange2["PRIORITY"] = "priority";
|
|
2545
|
+
IssueUpdateChange2["CATEGORY"] = "category";
|
|
2546
|
+
IssueUpdateChange2["DESCRIPTION"] = "description";
|
|
2547
|
+
IssueUpdateChange2["TITLE"] = "title";
|
|
2548
|
+
IssueUpdateChange2["ASSIGNED_TO"] = "assigned_to";
|
|
2549
|
+
IssueUpdateChange2["DUE_DATE"] = "due_date";
|
|
2550
|
+
return IssueUpdateChange2;
|
|
2551
|
+
})(IssueUpdateChange || {});
|
|
2452
2552
|
var ProjectType = /* @__PURE__ */ ((ProjectType2) => {
|
|
2453
2553
|
ProjectType2[ProjectType2["PERSONAL"] = 0] = "PERSONAL";
|
|
2454
2554
|
ProjectType2[ProjectType2["ORGANIZATION"] = 2] = "ORGANIZATION";
|
|
@@ -4437,7 +4537,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4437
4537
|
}
|
|
4438
4538
|
// Attachments aren't models, so we use the OptimisticGenericResult type instead
|
|
4439
4539
|
async addIssueAttachment(attachmentPayload) {
|
|
4440
|
-
const {
|
|
4540
|
+
const { issue, file_sha1, offline_id } = attachmentPayload;
|
|
4441
4541
|
if (!attachmentPayload.file.objectURL) {
|
|
4442
4542
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4443
4543
|
}
|
|
@@ -4445,7 +4545,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4445
4545
|
...attachmentPayload,
|
|
4446
4546
|
file: attachmentPayload.file.objectURL,
|
|
4447
4547
|
file_name: attachmentPayload.file.name,
|
|
4448
|
-
file_type: attachmentPayload.file.type
|
|
4548
|
+
file_type: attachmentPayload.file.type,
|
|
4549
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4550
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4449
4551
|
};
|
|
4450
4552
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4451
4553
|
this.client.store.dispatch(addIssueAttachment(offlineAttachment));
|
|
@@ -4457,10 +4559,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4457
4559
|
blocks: [offline_id, issue],
|
|
4458
4560
|
blockers: [file_sha1],
|
|
4459
4561
|
payload: {
|
|
4460
|
-
|
|
4461
|
-
issue,
|
|
4462
|
-
description: description2 ?? "",
|
|
4463
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4562
|
+
...offlineAttachment,
|
|
4464
4563
|
...fileProps
|
|
4465
4564
|
}
|
|
4466
4565
|
});
|
|
@@ -4471,7 +4570,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4471
4570
|
return [offlineAttachment, promise];
|
|
4472
4571
|
}
|
|
4473
4572
|
async addComponentAttachment(attachmentPayload) {
|
|
4474
|
-
const {
|
|
4573
|
+
const { component, file_sha1, offline_id } = attachmentPayload;
|
|
4475
4574
|
if (!attachmentPayload.file.objectURL) {
|
|
4476
4575
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4477
4576
|
}
|
|
@@ -4479,7 +4578,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4479
4578
|
...attachmentPayload,
|
|
4480
4579
|
file: attachmentPayload.file.objectURL,
|
|
4481
4580
|
file_name: attachmentPayload.file.name,
|
|
4482
|
-
file_type: attachmentPayload.file.type
|
|
4581
|
+
file_type: attachmentPayload.file.type,
|
|
4582
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4583
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4483
4584
|
};
|
|
4484
4585
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4485
4586
|
this.client.store.dispatch(addComponentAttachment(offlineAttachment));
|
|
@@ -4491,10 +4592,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4491
4592
|
blocks: [offline_id, component],
|
|
4492
4593
|
blockers: [file_sha1],
|
|
4493
4594
|
payload: {
|
|
4494
|
-
|
|
4495
|
-
component,
|
|
4496
|
-
description: description2 ?? "",
|
|
4497
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4595
|
+
...offlineAttachment,
|
|
4498
4596
|
...fileProps
|
|
4499
4597
|
}
|
|
4500
4598
|
});
|
|
@@ -4505,7 +4603,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4505
4603
|
return [offlineAttachment, promise];
|
|
4506
4604
|
}
|
|
4507
4605
|
async addComponentTypeAttachment(attachmentPayload) {
|
|
4508
|
-
const {
|
|
4606
|
+
const { component_type, file_sha1, offline_id } = attachmentPayload;
|
|
4509
4607
|
if (!attachmentPayload.file.objectURL) {
|
|
4510
4608
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4511
4609
|
}
|
|
@@ -4513,7 +4611,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4513
4611
|
...attachmentPayload,
|
|
4514
4612
|
file: attachmentPayload.file.objectURL,
|
|
4515
4613
|
file_name: attachmentPayload.file.name,
|
|
4516
|
-
file_type: attachmentPayload.file.type
|
|
4614
|
+
file_type: attachmentPayload.file.type,
|
|
4615
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4616
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4517
4617
|
};
|
|
4518
4618
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4519
4619
|
this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
|
|
@@ -4525,10 +4625,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4525
4625
|
blocks: [offline_id, component_type],
|
|
4526
4626
|
blockers: [file_sha1],
|
|
4527
4627
|
payload: {
|
|
4528
|
-
|
|
4529
|
-
component_type,
|
|
4530
|
-
description: description2 ?? "",
|
|
4531
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4628
|
+
...offlineAttachment,
|
|
4532
4629
|
...fileProps
|
|
4533
4630
|
}
|
|
4534
4631
|
});
|
|
@@ -4547,7 +4644,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4547
4644
|
...attachmentPayload,
|
|
4548
4645
|
file: attachmentPayload.file.objectURL,
|
|
4549
4646
|
file_name: attachmentPayload.file.name,
|
|
4550
|
-
file_type: attachmentPayload.file.type
|
|
4647
|
+
file_type: attachmentPayload.file.type,
|
|
4648
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4649
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4551
4650
|
};
|
|
4552
4651
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4553
4652
|
this.client.store.dispatch(addProjectAttachment(offlineAttachment));
|
|
@@ -4587,7 +4686,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4587
4686
|
file_name: file2.name,
|
|
4588
4687
|
file_type: file2.type,
|
|
4589
4688
|
issue: issueId,
|
|
4590
|
-
file_sha1: hash
|
|
4689
|
+
file_sha1: hash,
|
|
4690
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4691
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4591
4692
|
});
|
|
4592
4693
|
return this.addIssueAttachment(attachment);
|
|
4593
4694
|
};
|
|
@@ -4606,7 +4707,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4606
4707
|
file_name: file2.name,
|
|
4607
4708
|
file_type: file2.type,
|
|
4608
4709
|
component: componentId,
|
|
4609
|
-
file_sha1: hash
|
|
4710
|
+
file_sha1: hash,
|
|
4711
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4712
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4610
4713
|
});
|
|
4611
4714
|
return this.addComponentAttachment(attachment);
|
|
4612
4715
|
};
|
|
@@ -4625,7 +4728,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4625
4728
|
file_name: file2.name,
|
|
4626
4729
|
file_type: file2.type,
|
|
4627
4730
|
component_type: componentTypeId,
|
|
4628
|
-
file_sha1: hash
|
|
4731
|
+
file_sha1: hash,
|
|
4732
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4733
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4629
4734
|
});
|
|
4630
4735
|
return this.addComponentTypeAttachment(attachment);
|
|
4631
4736
|
};
|
|
@@ -4644,7 +4749,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4644
4749
|
file_name: file2.name,
|
|
4645
4750
|
file_type: file2.type,
|
|
4646
4751
|
project: projectId,
|
|
4647
|
-
file_sha1: hash
|
|
4752
|
+
file_sha1: hash,
|
|
4753
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4754
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4648
4755
|
});
|
|
4649
4756
|
return this.addProjectAttachment(attachment);
|
|
4650
4757
|
};
|
|
@@ -5721,49 +5828,35 @@ class ComponentTypeService extends BaseApiService {
|
|
|
5721
5828
|
}
|
|
5722
5829
|
}
|
|
5723
5830
|
class IssueCommentService extends BaseApiService {
|
|
5831
|
+
// Omit author and submitted_at since these will always be set internally
|
|
5724
5832
|
add(comment) {
|
|
5725
|
-
const offlinePayload = offline(comment);
|
|
5726
|
-
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5727
5833
|
const { store } = this.client;
|
|
5728
|
-
const offlineComment = {
|
|
5729
|
-
...
|
|
5834
|
+
const offlineComment = offline({
|
|
5835
|
+
...comment,
|
|
5730
5836
|
author: store.getState().userReducer.currentUser.id,
|
|
5731
|
-
|
|
5732
|
-
};
|
|
5733
|
-
store.dispatch(
|
|
5837
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
5838
|
+
});
|
|
5839
|
+
store.dispatch(addIssueComment(offlineComment));
|
|
5734
5840
|
const promise = this.enqueueRequest({
|
|
5735
5841
|
description: `${truncate(comment.content, 80)}`,
|
|
5736
5842
|
method: HttpMethod.POST,
|
|
5737
5843
|
url: `/issues/${comment.issue}/comment/`,
|
|
5738
|
-
payload:
|
|
5844
|
+
payload: offlineComment,
|
|
5739
5845
|
blockers: [comment.issue],
|
|
5740
|
-
blocks: [
|
|
5846
|
+
blocks: [offlineComment.offline_id]
|
|
5847
|
+
});
|
|
5848
|
+
promise.catch(() => {
|
|
5849
|
+
store.dispatch(removeIssueComment(offlineComment.offline_id));
|
|
5741
5850
|
});
|
|
5742
5851
|
return [offlineComment, promise];
|
|
5743
5852
|
}
|
|
5744
|
-
|
|
5853
|
+
update(comment) {
|
|
5745
5854
|
const { store } = this.client;
|
|
5746
|
-
const
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
// TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
|
|
5750
|
-
url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
|
|
5751
|
-
blockers: [],
|
|
5752
|
-
blocks: []
|
|
5753
|
-
});
|
|
5754
|
-
let filteredResult = result.filter(onlyUniqueOfflineIds);
|
|
5755
|
-
filteredResult = filteredResult.map((comment) => {
|
|
5756
|
-
return { ...comment };
|
|
5757
|
-
});
|
|
5758
|
-
if (result.length !== filteredResult.length) {
|
|
5759
|
-
console.error(
|
|
5760
|
-
`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
|
|
5761
|
-
);
|
|
5855
|
+
const commentToUpdate = store.getState().issueReducer.comments[comment.offline_id];
|
|
5856
|
+
if (!commentToUpdate) {
|
|
5857
|
+
throw new Error(`Comment with offline_id ${comment.offline_id} not found in store`);
|
|
5762
5858
|
}
|
|
5763
|
-
store.dispatch(
|
|
5764
|
-
}
|
|
5765
|
-
update(comment) {
|
|
5766
|
-
this.client.store.dispatch(addOrReplaceIssueComment(comment));
|
|
5859
|
+
store.dispatch(setIssueComment(comment));
|
|
5767
5860
|
const promise = this.enqueueRequest({
|
|
5768
5861
|
description: `Edit comment: ${truncate(comment.content, 80)}`,
|
|
5769
5862
|
method: HttpMethod.PATCH,
|
|
@@ -5772,17 +5865,62 @@ class IssueCommentService extends BaseApiService {
|
|
|
5772
5865
|
blockers: [comment.issue],
|
|
5773
5866
|
blocks: [comment.offline_id]
|
|
5774
5867
|
});
|
|
5868
|
+
promise.catch(() => {
|
|
5869
|
+
store.dispatch(setIssueComment(commentToUpdate));
|
|
5870
|
+
});
|
|
5775
5871
|
return [comment, promise];
|
|
5776
5872
|
}
|
|
5777
5873
|
remove(offline_id) {
|
|
5874
|
+
const commentToRemove = this.client.store.getState().issueReducer.comments[offline_id];
|
|
5875
|
+
if (!commentToRemove) {
|
|
5876
|
+
throw new Error(`Comment with offline_id ${offline_id} not found in store`);
|
|
5877
|
+
}
|
|
5778
5878
|
this.client.store.dispatch(removeIssueComment(offline_id));
|
|
5779
|
-
|
|
5879
|
+
const promise = this.enqueueRequest({
|
|
5780
5880
|
description: "Delete comment",
|
|
5781
5881
|
method: HttpMethod.DELETE,
|
|
5782
5882
|
url: `/issues/comments/${offline_id}/`,
|
|
5783
5883
|
blockers: [offline_id],
|
|
5784
5884
|
blocks: []
|
|
5785
5885
|
});
|
|
5886
|
+
promise.catch(() => {
|
|
5887
|
+
this.client.store.dispatch(addIssueComment(commentToRemove));
|
|
5888
|
+
});
|
|
5889
|
+
return promise;
|
|
5890
|
+
}
|
|
5891
|
+
async refreshStore() {
|
|
5892
|
+
const { store } = this.client;
|
|
5893
|
+
const result = await this.enqueueRequest({
|
|
5894
|
+
description: "Get comments",
|
|
5895
|
+
method: HttpMethod.GET,
|
|
5896
|
+
// TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
|
|
5897
|
+
url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
|
|
5898
|
+
blockers: [],
|
|
5899
|
+
blocks: []
|
|
5900
|
+
});
|
|
5901
|
+
store.dispatch(setIssueComments(result));
|
|
5902
|
+
}
|
|
5903
|
+
}
|
|
5904
|
+
class IssueUpdateService extends BaseApiService {
|
|
5905
|
+
async refreshStore() {
|
|
5906
|
+
const { store } = this.client;
|
|
5907
|
+
const result = await this.enqueueRequest({
|
|
5908
|
+
description: "Get issue updates",
|
|
5909
|
+
method: HttpMethod.GET,
|
|
5910
|
+
url: `/projects/${store.getState().projectReducer.activeProjectId}/issues/updates/`,
|
|
5911
|
+
blockers: [],
|
|
5912
|
+
blocks: []
|
|
5913
|
+
});
|
|
5914
|
+
let filteredResult = result.filter(onlyUniqueOfflineIds);
|
|
5915
|
+
filteredResult = filteredResult.map((comment) => {
|
|
5916
|
+
return { ...comment };
|
|
5917
|
+
});
|
|
5918
|
+
if (result.length !== filteredResult.length) {
|
|
5919
|
+
console.error(
|
|
5920
|
+
`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
|
|
5921
|
+
);
|
|
5922
|
+
}
|
|
5923
|
+
store.dispatch(setIssueUpdates(filteredResult));
|
|
5786
5924
|
}
|
|
5787
5925
|
}
|
|
5788
5926
|
class IssueService extends BaseApiService {
|
|
@@ -5863,7 +6001,83 @@ class IssueService extends BaseApiService {
|
|
|
5863
6001
|
return [offlineIssues, promise];
|
|
5864
6002
|
}
|
|
5865
6003
|
update(issue) {
|
|
6004
|
+
const state = this.client.store.getState();
|
|
6005
|
+
const issueToBeUpdated = state.issueReducer.issues[issue.offline_id];
|
|
6006
|
+
if (!issueToBeUpdated) {
|
|
6007
|
+
throw new Error(
|
|
6008
|
+
`Attempting to update an issue with offline_id ${issue.offline_id} that doesn't exist in the store`
|
|
6009
|
+
);
|
|
6010
|
+
}
|
|
5866
6011
|
this.client.store.dispatch(updateIssue(issue));
|
|
6012
|
+
const changes = {};
|
|
6013
|
+
for (const issueUpdateChange of [
|
|
6014
|
+
IssueUpdateChange.TITLE,
|
|
6015
|
+
IssueUpdateChange.DESCRIPTION,
|
|
6016
|
+
IssueUpdateChange.STATUS,
|
|
6017
|
+
IssueUpdateChange.CATEGORY,
|
|
6018
|
+
IssueUpdateChange.PRIORITY,
|
|
6019
|
+
IssueUpdateChange.ASSIGNED_TO,
|
|
6020
|
+
IssueUpdateChange.DUE_DATE
|
|
6021
|
+
]) {
|
|
6022
|
+
if (issueUpdateChange in issue && issue[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {
|
|
6023
|
+
switch (issueUpdateChange) {
|
|
6024
|
+
case "category": {
|
|
6025
|
+
let categoryOrNull = null;
|
|
6026
|
+
const categoryIdOrNull = issue[issueUpdateChange];
|
|
6027
|
+
if (categoryIdOrNull) {
|
|
6028
|
+
categoryOrNull = state.categoryReducer.categories[categoryIdOrNull] ?? null;
|
|
6029
|
+
if (!categoryOrNull)
|
|
6030
|
+
throw new Error(
|
|
6031
|
+
`Trying to update issue category to ${categoryIdOrNull} which does not exist in store`
|
|
6032
|
+
);
|
|
6033
|
+
}
|
|
6034
|
+
changes[issueUpdateChange] = categoryOrNull ? {
|
|
6035
|
+
name: categoryOrNull.name,
|
|
6036
|
+
color: categoryOrNull.color,
|
|
6037
|
+
offline_id: categoryOrNull.offline_id
|
|
6038
|
+
} : null;
|
|
6039
|
+
break;
|
|
6040
|
+
}
|
|
6041
|
+
case "assigned_to": {
|
|
6042
|
+
let userOrNull = null;
|
|
6043
|
+
const userIdOrNull = issue[issueUpdateChange];
|
|
6044
|
+
if (userIdOrNull) {
|
|
6045
|
+
userOrNull = state.userReducer.users[userIdOrNull] ?? null;
|
|
6046
|
+
if (!userOrNull)
|
|
6047
|
+
throw new Error(
|
|
6048
|
+
`Trying to update issue assigned_to to ${userIdOrNull} which does not exist in store`
|
|
6049
|
+
);
|
|
6050
|
+
}
|
|
6051
|
+
changes[issueUpdateChange] = userOrNull ? {
|
|
6052
|
+
full_name: userOrNull.username,
|
|
6053
|
+
id: userOrNull.id
|
|
6054
|
+
} : null;
|
|
6055
|
+
break;
|
|
6056
|
+
}
|
|
6057
|
+
case "description":
|
|
6058
|
+
changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
|
|
6059
|
+
break;
|
|
6060
|
+
case "title":
|
|
6061
|
+
changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
|
|
6062
|
+
break;
|
|
6063
|
+
case "priority":
|
|
6064
|
+
changes[issueUpdateChange] = issue[issueUpdateChange];
|
|
6065
|
+
break;
|
|
6066
|
+
case "status":
|
|
6067
|
+
changes[issueUpdateChange] = issue[issueUpdateChange];
|
|
6068
|
+
break;
|
|
6069
|
+
case "due_date":
|
|
6070
|
+
changes[issueUpdateChange] = issue[issueUpdateChange] ? issue[issueUpdateChange] : null;
|
|
6071
|
+
}
|
|
6072
|
+
}
|
|
6073
|
+
}
|
|
6074
|
+
const offlineIssueUpdate = offline({
|
|
6075
|
+
created_by: state.userReducer.currentUser.id,
|
|
6076
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6077
|
+
issue: issueToBeUpdated.offline_id,
|
|
6078
|
+
changes
|
|
6079
|
+
});
|
|
6080
|
+
this.client.store.dispatch(addIssueUpdate(offlineIssueUpdate));
|
|
5867
6081
|
const promise = this.enqueueRequest({
|
|
5868
6082
|
description: "Edit issue",
|
|
5869
6083
|
method: HttpMethod.PATCH,
|
|
@@ -5872,23 +6086,30 @@ class IssueService extends BaseApiService {
|
|
|
5872
6086
|
blockers: [issue.offline_id],
|
|
5873
6087
|
blocks: [issue.offline_id]
|
|
5874
6088
|
});
|
|
6089
|
+
promise.catch(() => {
|
|
6090
|
+
this.client.store.dispatch(updateIssue(issueToBeUpdated));
|
|
6091
|
+
this.client.store.dispatch(removeIssueUpdate(offlineIssueUpdate.offline_id));
|
|
6092
|
+
});
|
|
5875
6093
|
const fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id];
|
|
5876
6094
|
return [fullIssue, promise];
|
|
5877
6095
|
}
|
|
5878
6096
|
async remove(id) {
|
|
5879
6097
|
const { store } = this.client;
|
|
5880
6098
|
const state = store.getState();
|
|
6099
|
+
const dispatch = store.dispatch;
|
|
5881
6100
|
const backup = state.issueReducer.issues[id];
|
|
5882
6101
|
if (!backup) {
|
|
5883
6102
|
throw new Error(`No issue with id ${id} found in the store`);
|
|
5884
6103
|
}
|
|
5885
6104
|
const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue === id);
|
|
5886
6105
|
const attachmentsOfIssue = selectAttachmentsOfIssue(id)(state);
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
6106
|
+
const updatesOfIssue = selectIssueUpdatesOfIssue(id)(state);
|
|
6107
|
+
dispatch(removeIssue(id));
|
|
6108
|
+
dispatch(addActiveProjectIssuesCount(-1));
|
|
6109
|
+
if (attachmentsOfIssue.length > 0)
|
|
6110
|
+
dispatch(removeAttachmentsOfIssue(id));
|
|
6111
|
+
if (updatesOfIssue.length > 0)
|
|
6112
|
+
dispatch(removeIssueUpdates(updatesOfIssue.map(({ offline_id }) => offline_id)));
|
|
5892
6113
|
try {
|
|
5893
6114
|
return await this.enqueueRequest({
|
|
5894
6115
|
description: "Delete issue",
|
|
@@ -5898,9 +6119,10 @@ class IssueService extends BaseApiService {
|
|
|
5898
6119
|
blocks: []
|
|
5899
6120
|
});
|
|
5900
6121
|
} catch (e) {
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
6122
|
+
dispatch(addIssue(backup));
|
|
6123
|
+
dispatch(addIssueAttachments(attachments));
|
|
6124
|
+
dispatch(addIssueUpdates(updatesOfIssue));
|
|
6125
|
+
dispatch(addActiveProjectIssuesCount(1));
|
|
5904
6126
|
throw e;
|
|
5905
6127
|
}
|
|
5906
6128
|
}
|
|
@@ -6082,6 +6304,7 @@ class MainService extends BaseApiService {
|
|
|
6082
6304
|
store.dispatch(setProjectAttachments(project_attachments));
|
|
6083
6305
|
});
|
|
6084
6306
|
void this.client.documents.refreshStore();
|
|
6307
|
+
void this.client.issueUpdates.refreshStore();
|
|
6085
6308
|
}
|
|
6086
6309
|
store.dispatch(setIsFetchingInitialData(false));
|
|
6087
6310
|
if (overwrite) {
|
|
@@ -7549,6 +7772,7 @@ class OvermapSDK {
|
|
|
7549
7772
|
__publicField(this, "organizationAccess", new OrganizationAccessService(this));
|
|
7550
7773
|
__publicField(this, "issues", new IssueService(this));
|
|
7551
7774
|
__publicField(this, "issueComments", new IssueCommentService(this));
|
|
7775
|
+
__publicField(this, "issueUpdates", new IssueUpdateService(this));
|
|
7552
7776
|
__publicField(this, "workspaces", new WorkspaceService(this));
|
|
7553
7777
|
__publicField(this, "main", new MainService(this));
|
|
7554
7778
|
__publicField(this, "components", new ComponentService(this));
|
|
@@ -14206,17 +14430,15 @@ const FieldActions = memo((props) => {
|
|
|
14206
14430
|
Action.key
|
|
14207
14431
|
)) }),
|
|
14208
14432
|
/* @__PURE__ */ jsx(Box, { display: forMobile(true, "block"), children: /* @__PURE__ */ jsx(
|
|
14209
|
-
|
|
14433
|
+
OvermapDropdownMenu,
|
|
14210
14434
|
{
|
|
14211
14435
|
trigger: /* @__PURE__ */ jsx(IconButton, { variant: "ghost", "aria-label": "Actions menu", children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiMore2Line" }) }),
|
|
14212
14436
|
items: actions.map((Action) => {
|
|
14213
14437
|
var _a2;
|
|
14214
14438
|
return {
|
|
14215
|
-
|
|
14216
|
-
|
|
14217
|
-
|
|
14218
|
-
] }, Action.key),
|
|
14219
|
-
onSelect: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
|
|
14439
|
+
leftSlot: /* @__PURE__ */ jsx(Action.Icon, {}),
|
|
14440
|
+
children: Action.text,
|
|
14441
|
+
onClick: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
|
|
14220
14442
|
};
|
|
14221
14443
|
})
|
|
14222
14444
|
}
|
|
@@ -14274,10 +14496,8 @@ const useFieldTypeItems = (onSelect = () => null) => {
|
|
|
14274
14496
|
const field = FieldTypeToClsMapping[identifier];
|
|
14275
14497
|
const Icon = field.Icon;
|
|
14276
14498
|
return {
|
|
14277
|
-
|
|
14278
|
-
|
|
14279
|
-
/* @__PURE__ */ jsx(Text$1, { children: field.fieldTypeName })
|
|
14280
|
-
] }, identifier),
|
|
14499
|
+
children: field.fieldTypeName,
|
|
14500
|
+
leftSlot: /* @__PURE__ */ jsx(Icon, {}),
|
|
14281
14501
|
value: identifier,
|
|
14282
14502
|
onSelect: () => {
|
|
14283
14503
|
onSelect(identifier);
|
|
@@ -14481,7 +14701,7 @@ const FieldBuilder = memo((props) => {
|
|
|
14481
14701
|
}
|
|
14482
14702
|
),
|
|
14483
14703
|
/* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "3", children: [
|
|
14484
|
-
/* @__PURE__ */ jsx(Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.
|
|
14704
|
+
/* @__PURE__ */ jsx(Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.children }),
|
|
14485
14705
|
showPopoverInputs && /* @__PURE__ */ jsx(FieldSettingsPopover, { popoverInputs, hasError: popoverHasErrors })
|
|
14486
14706
|
] }),
|
|
14487
14707
|
resolvedImage && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -14842,7 +15062,7 @@ const FieldSectionWithActions = memo((props) => {
|
|
|
14842
15062
|
)),
|
|
14843
15063
|
droppableProvided.placeholder,
|
|
14844
15064
|
/* @__PURE__ */ jsx(
|
|
14845
|
-
|
|
15065
|
+
OvermapDropdownMenu,
|
|
14846
15066
|
{
|
|
14847
15067
|
trigger: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", children: [
|
|
14848
15068
|
/* @__PURE__ */ jsx(RiIcon, { icon: "RiAddLine" }),
|
|
@@ -15278,6 +15498,8 @@ export {
|
|
|
15278
15498
|
IssuePriority,
|
|
15279
15499
|
IssueService,
|
|
15280
15500
|
IssueStatus,
|
|
15501
|
+
IssueUpdateChange,
|
|
15502
|
+
IssueUpdateService,
|
|
15281
15503
|
LicenseLevel,
|
|
15282
15504
|
LicenseService,
|
|
15283
15505
|
LicenseStatus,
|
|
@@ -15341,6 +15563,10 @@ export {
|
|
|
15341
15563
|
addIssue,
|
|
15342
15564
|
addIssueAttachment,
|
|
15343
15565
|
addIssueAttachments,
|
|
15566
|
+
addIssueComment,
|
|
15567
|
+
addIssueComments,
|
|
15568
|
+
addIssueUpdate,
|
|
15569
|
+
addIssueUpdates,
|
|
15344
15570
|
addLicenses,
|
|
15345
15571
|
addOrReplaceCategories,
|
|
15346
15572
|
addOrReplaceIssueComment,
|
|
@@ -15500,6 +15726,9 @@ export {
|
|
|
15500
15726
|
removeIssue,
|
|
15501
15727
|
removeIssueAttachment,
|
|
15502
15728
|
removeIssueComment,
|
|
15729
|
+
removeIssueComments,
|
|
15730
|
+
removeIssueUpdate,
|
|
15731
|
+
removeIssueUpdates,
|
|
15503
15732
|
removeOrganizationAccess,
|
|
15504
15733
|
removeProjectAccess,
|
|
15505
15734
|
removeProjectAccessesOfProject,
|
|
@@ -15601,6 +15830,8 @@ export {
|
|
|
15601
15830
|
selectIssueAttachmentMapping,
|
|
15602
15831
|
selectIssueAttachments,
|
|
15603
15832
|
selectIssueMapping,
|
|
15833
|
+
selectIssueUpdateMapping,
|
|
15834
|
+
selectIssueUpdatesOfIssue,
|
|
15604
15835
|
selectIssues,
|
|
15605
15836
|
selectLatestFormRevision,
|
|
15606
15837
|
selectLatestRetryTime,
|
|
@@ -15652,6 +15883,7 @@ export {
|
|
|
15652
15883
|
selectSortedOrganizationUsers,
|
|
15653
15884
|
selectSortedProjectUsers,
|
|
15654
15885
|
selectSortedProjects,
|
|
15886
|
+
selectStage,
|
|
15655
15887
|
selectStageFormIdsFromStageIds,
|
|
15656
15888
|
selectStageMapping,
|
|
15657
15889
|
selectStages,
|
|
@@ -15696,7 +15928,9 @@ export {
|
|
|
15696
15928
|
setIsImportingProjectFile,
|
|
15697
15929
|
setIsLoading,
|
|
15698
15930
|
setIssueAttachments,
|
|
15931
|
+
setIssueComment,
|
|
15699
15932
|
setIssueComments,
|
|
15933
|
+
setIssueUpdates,
|
|
15700
15934
|
setIssues,
|
|
15701
15935
|
setLicenses,
|
|
15702
15936
|
setLoggedIn,
|