@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.
- package/README.md +4 -4
- package/dist/overmap-core.js +567 -122
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +567 -122
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/services/AttachmentService.d.ts +30 -8
- package/dist/store/slices/componentSlice.d.ts +34 -2
- package/dist/store/slices/componentTypeSlice.d.ts +34 -2
- package/dist/store/slices/issueSlice.d.ts +26 -6
- package/dist/store/slices/utils.d.ts +12 -0
- package/dist/typings/models/attachments.d.ts +14 -7
- package/package.json +151 -151
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
1950
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
2046
|
-
|
|
2148
|
+
addIssueAttachment,
|
|
2149
|
+
addIssueAttachments,
|
|
2047
2150
|
addIssue,
|
|
2048
2151
|
addOrReplaceIssueComment,
|
|
2049
2152
|
addToRecentIssues,
|
|
2050
2153
|
cleanRecentIssues,
|
|
2051
|
-
|
|
2154
|
+
removeIssueAttachment,
|
|
2052
2155
|
removeAttachmentsOfIssue,
|
|
2053
2156
|
removeIssue,
|
|
2054
2157
|
removeIssueComment,
|
|
2055
2158
|
removeRecentIssue,
|
|
2056
2159
|
resetRecentIssues,
|
|
2057
2160
|
setActiveIssueId,
|
|
2058
|
-
|
|
2161
|
+
setIssueAttachments,
|
|
2059
2162
|
setIssueComments,
|
|
2060
2163
|
setIssues,
|
|
2061
2164
|
setVisibleStatuses,
|
|
2062
2165
|
setVisibleUserIds,
|
|
2063
|
-
|
|
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.
|
|
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.
|
|
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 =
|
|
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
|
|
4080
|
-
const { description: description2,
|
|
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(
|
|
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: `/
|
|
4097
|
-
blocks: [offline_id,
|
|
4260
|
+
url: `/components/${component}/attach/`,
|
|
4261
|
+
blocks: [offline_id, component],
|
|
4098
4262
|
blockers: [file_sha1],
|
|
4099
4263
|
payload: {
|
|
4100
4264
|
offline_id,
|
|
4101
|
-
|
|
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
|
|
4110
|
-
|
|
4111
|
-
|
|
4112
|
-
|
|
4113
|
-
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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
|
-
|
|
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
|
|
4548
|
+
* @param issueAttachmentId
|
|
4187
4549
|
*/
|
|
4188
|
-
|
|
4550
|
+
deleteIssueAttachment(issueAttachmentId) {
|
|
4189
4551
|
const { store } = this.client;
|
|
4190
|
-
const
|
|
4191
|
-
const attachment = storeStateIssueReducer.attachments[attachmentId];
|
|
4552
|
+
const attachment = selectIssueAttachmentMapping(store.getState())[issueAttachmentId];
|
|
4192
4553
|
if (!attachment) {
|
|
4193
|
-
throw new Error(`Attachment ${
|
|
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(
|
|
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/${
|
|
4201
|
-
blockers: [
|
|
4202
|
-
blocks: [
|
|
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
|
|
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
|
|
4912
|
-
|
|
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(
|
|
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.
|
|
5105
|
-
const attachmentsOfIssue =
|
|
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(
|
|
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
|
-
|
|
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 =
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6285
|
-
|
|
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: "
|
|
6692
|
-
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;
|