@overmap-ai/core 1.0.43-projects-licensing.3 → 1.0.44-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 +650 -574
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +650 -574
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/sdk.d.ts +1 -2
- package/dist/sdk/services/AttachmentService.d.ts +30 -8
- package/dist/sdk/services/MainService.d.ts +1 -2
- package/dist/sdk/services/ProjectService.d.ts +3 -2
- package/dist/sdk/services/index.d.ts +0 -1
- package/dist/store/slices/categorySlice.d.ts +0 -1
- package/dist/store/slices/componentSlice.d.ts +30 -2
- package/dist/store/slices/componentTypeSlice.d.ts +30 -2
- package/dist/store/slices/index.d.ts +0 -1
- package/dist/store/slices/issueSlice.d.ts +43 -26
- package/dist/store/slices/organizationSlice.d.ts +1 -5
- package/dist/store/slices/projectFileSlice.d.ts +0 -1
- package/dist/store/slices/projectSlice.d.ts +1 -7
- package/dist/store/slices/settingsSlice.d.ts +1 -7
- package/dist/store/slices/utils.d.ts +12 -0
- package/dist/store/slices/workspaceSlice.d.ts +0 -1
- package/dist/store/store.d.ts +1 -4
- package/dist/typings/models/attachments.d.ts +14 -7
- package/dist/typings/models/base.d.ts +0 -4
- package/dist/typings/models/index.d.ts +0 -1
- package/dist/typings/models/organizations.d.ts +0 -2
- package/dist/typings/models/projects.d.ts +0 -2
- package/package.json +151 -151
- package/dist/sdk/services/LicenseService.d.ts +0 -12
- package/dist/store/slices/licenseSlice.d.ts +0 -25
- package/dist/typings/models/license.d.ts +0 -26
package/dist/overmap-core.js
CHANGED
|
@@ -632,15 +632,15 @@ const wrapMigration = (migrator) => (state) => {
|
|
|
632
632
|
};
|
|
633
633
|
const migrations = [initialVersioning, signOut, signOut, createOutboxState];
|
|
634
634
|
const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
|
|
635
|
-
const initialState$
|
|
635
|
+
const initialState$l = {
|
|
636
636
|
accessToken: "",
|
|
637
637
|
refreshToken: "",
|
|
638
638
|
isLoggedIn: false
|
|
639
639
|
};
|
|
640
640
|
const authSlice = createSlice({
|
|
641
641
|
name: "auth",
|
|
642
|
-
initialState: initialState$
|
|
643
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
642
|
+
initialState: initialState$l,
|
|
643
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
|
|
644
644
|
reducers: {
|
|
645
645
|
setTokens: (state, action) => {
|
|
646
646
|
state.accessToken = action.payload.accessToken;
|
|
@@ -1371,7 +1371,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
|
|
|
1371
1371
|
return getLocalDateString(date);
|
|
1372
1372
|
return relative.format(days, "days");
|
|
1373
1373
|
});
|
|
1374
|
-
const initialState$
|
|
1374
|
+
const initialState$k = {
|
|
1375
1375
|
categories: {},
|
|
1376
1376
|
usedCategoryColors: [],
|
|
1377
1377
|
categoryVisibility: {
|
|
@@ -1381,8 +1381,8 @@ const initialState$l = {
|
|
|
1381
1381
|
};
|
|
1382
1382
|
const categorySlice = createSlice({
|
|
1383
1383
|
name: "categories",
|
|
1384
|
-
initialState: initialState$
|
|
1385
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1384
|
+
initialState: initialState$k,
|
|
1385
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
|
|
1386
1386
|
reducers: {
|
|
1387
1387
|
setCategories: (state, action) => {
|
|
1388
1388
|
if (!Array.isArray(action.payload))
|
|
@@ -1515,13 +1515,49 @@ const selectHiddenCategoryCount = (state) => {
|
|
|
1515
1515
|
return hiddenCategoryCount;
|
|
1516
1516
|
};
|
|
1517
1517
|
const categoryReducer = categorySlice.reducer;
|
|
1518
|
-
|
|
1519
|
-
|
|
1518
|
+
function setAttachments(state, action) {
|
|
1519
|
+
for (const attachment of action.payload) {
|
|
1520
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
1521
|
+
}
|
|
1522
|
+
}
|
|
1523
|
+
function addAttachment(state, action) {
|
|
1524
|
+
if (action.payload.offline_id in state.attachments) {
|
|
1525
|
+
throw new Error(`Attachment ${action.payload.offline_id} already exists.`);
|
|
1526
|
+
}
|
|
1527
|
+
state.attachments[action.payload.offline_id] = action.payload;
|
|
1528
|
+
}
|
|
1529
|
+
function addAttachments(state, action) {
|
|
1530
|
+
for (const attachment of action.payload) {
|
|
1531
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
function updateAttachment(state, action) {
|
|
1535
|
+
if (action.payload.offline_id in state.attachments) {
|
|
1536
|
+
state.attachments[action.payload.offline_id] = action.payload;
|
|
1537
|
+
} else {
|
|
1538
|
+
throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
function removeAttachment(state, action) {
|
|
1542
|
+
if (action.payload in state.attachments) {
|
|
1543
|
+
delete state.attachments[action.payload];
|
|
1544
|
+
} else {
|
|
1545
|
+
throw new Error(`Attachment ${action.payload} does not exist.`);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
function removeAttachments(state, action) {
|
|
1549
|
+
for (const attachmentId of action.payload) {
|
|
1550
|
+
delete state.attachments[attachmentId];
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
const initialState$j = {
|
|
1554
|
+
components: {},
|
|
1555
|
+
attachments: {}
|
|
1520
1556
|
};
|
|
1521
1557
|
const componentSlice = createSlice({
|
|
1522
1558
|
name: "components",
|
|
1523
|
-
initialState: initialState$
|
|
1524
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1559
|
+
initialState: initialState$j,
|
|
1560
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
|
|
1525
1561
|
reducers: {
|
|
1526
1562
|
addComponent: (state, action) => {
|
|
1527
1563
|
state.components[action.payload.offline_id] = action.payload;
|
|
@@ -1535,6 +1571,12 @@ const componentSlice = createSlice({
|
|
|
1535
1571
|
state.components = toOfflineIdRecord(action.payload);
|
|
1536
1572
|
prevComponents = null;
|
|
1537
1573
|
},
|
|
1574
|
+
setComponentAttachments: setAttachments,
|
|
1575
|
+
addComponentAttachment: addAttachment,
|
|
1576
|
+
addComponentAttachments: addAttachments,
|
|
1577
|
+
updateComponentAttachment: updateAttachment,
|
|
1578
|
+
removeComponentAttachment: removeAttachment,
|
|
1579
|
+
removeComponentAttachments: removeAttachments,
|
|
1538
1580
|
updateComponent: (state, action) => {
|
|
1539
1581
|
if (action.payload.offline_id in state.components) {
|
|
1540
1582
|
state.components[action.payload.offline_id] = action.payload;
|
|
@@ -1624,22 +1666,41 @@ const selectComponentTypesFromIds = (componentTypeIds) => (state) => {
|
|
|
1624
1666
|
return acc;
|
|
1625
1667
|
}, []);
|
|
1626
1668
|
};
|
|
1669
|
+
const selectComponentAttachmentMapping = (state) => state.componentReducer.attachments;
|
|
1670
|
+
const selectAllComponentAttachments = createSelector(
|
|
1671
|
+
[selectComponentAttachmentMapping],
|
|
1672
|
+
(mapping) => Object.values(mapping)
|
|
1673
|
+
);
|
|
1674
|
+
const selectAttachmentsOfComponent = restructureCreateSelectorWithArgs(
|
|
1675
|
+
createSelector(
|
|
1676
|
+
[selectAllComponentAttachments, (_state, componentId) => componentId],
|
|
1677
|
+
(attachments, componentId) => {
|
|
1678
|
+
return attachments.filter(({ component_id }) => componentId === component_id);
|
|
1679
|
+
}
|
|
1680
|
+
)
|
|
1681
|
+
);
|
|
1627
1682
|
const {
|
|
1628
1683
|
addComponent,
|
|
1629
1684
|
updateComponent,
|
|
1630
1685
|
removeComponent,
|
|
1631
1686
|
addComponentsInBatches,
|
|
1632
1687
|
setComponents,
|
|
1688
|
+
setComponentAttachments,
|
|
1689
|
+
addComponentAttachment,
|
|
1690
|
+
addComponentAttachments,
|
|
1691
|
+
updateComponentAttachment,
|
|
1692
|
+
removeComponentAttachment,
|
|
1693
|
+
removeComponentAttachments,
|
|
1633
1694
|
removeAllComponentsOfType
|
|
1634
1695
|
} = componentSlice.actions;
|
|
1635
1696
|
const componentReducer = componentSlice.reducer;
|
|
1636
|
-
const initialState$
|
|
1697
|
+
const initialState$i = {
|
|
1637
1698
|
completionsByComponentId: {}
|
|
1638
1699
|
};
|
|
1639
1700
|
const componentStageCompletionSlice = createSlice({
|
|
1640
1701
|
name: "componentStageCompletions",
|
|
1641
|
-
initialState: initialState$
|
|
1642
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1702
|
+
initialState: initialState$i,
|
|
1703
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
|
|
1643
1704
|
reducers: {
|
|
1644
1705
|
addStageCompletion: (state, action) => {
|
|
1645
1706
|
let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
|
|
@@ -1690,13 +1751,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
|
|
|
1690
1751
|
return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
|
|
1691
1752
|
};
|
|
1692
1753
|
const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
|
|
1693
|
-
const initialState$
|
|
1754
|
+
const initialState$h = {
|
|
1694
1755
|
stages: {}
|
|
1695
1756
|
};
|
|
1696
1757
|
const componentStageSlice = createSlice({
|
|
1697
1758
|
name: "componentStages",
|
|
1698
|
-
initialState: initialState$
|
|
1699
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1759
|
+
initialState: initialState$h,
|
|
1760
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
|
|
1700
1761
|
reducers: {
|
|
1701
1762
|
addStages: (state, action) => {
|
|
1702
1763
|
Object.assign(state.stages, toOfflineIdRecord(action.payload));
|
|
@@ -1787,14 +1848,15 @@ const selectStageFormIdsFromStageIds = restructureCreateSelectorWithArgs(
|
|
|
1787
1848
|
);
|
|
1788
1849
|
const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
|
|
1789
1850
|
const componentStageReducer = componentStageSlice.reducer;
|
|
1790
|
-
const initialState$
|
|
1851
|
+
const initialState$g = {
|
|
1791
1852
|
componentTypes: {},
|
|
1792
|
-
hiddenComponentTypeIds: {}
|
|
1853
|
+
hiddenComponentTypeIds: {},
|
|
1854
|
+
attachments: {}
|
|
1793
1855
|
};
|
|
1794
1856
|
const componentTypeSlice = createSlice({
|
|
1795
1857
|
name: "componentTypes",
|
|
1796
|
-
initialState: initialState$
|
|
1797
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1858
|
+
initialState: initialState$g,
|
|
1859
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
|
|
1798
1860
|
reducers: {
|
|
1799
1861
|
addComponentType: (state, action) => {
|
|
1800
1862
|
state.componentTypes[action.payload.offline_id] = action.payload;
|
|
@@ -1802,6 +1864,12 @@ const componentTypeSlice = createSlice({
|
|
|
1802
1864
|
setComponentTypes: (state, action) => {
|
|
1803
1865
|
state.componentTypes = toOfflineIdRecord(action.payload);
|
|
1804
1866
|
},
|
|
1867
|
+
setComponentTypeAttachments: setAttachments,
|
|
1868
|
+
addComponentTypeAttachment: addAttachment,
|
|
1869
|
+
addComponentTypeAttachments: addAttachments,
|
|
1870
|
+
updateComponentTypeAttachment: updateAttachment,
|
|
1871
|
+
removeComponentTypeAttachment: removeAttachment,
|
|
1872
|
+
removeComponentTypeAttachments: removeAttachments,
|
|
1805
1873
|
toggleComponentTypeVisibility: (state, action) => {
|
|
1806
1874
|
state.hiddenComponentTypeIds[action.payload] = !state.hiddenComponentTypeIds[action.payload];
|
|
1807
1875
|
},
|
|
@@ -1851,15 +1919,39 @@ const selectComponentTypesByName = restructureCreateSelectorWithArgs(
|
|
|
1851
1919
|
)
|
|
1852
1920
|
);
|
|
1853
1921
|
const selectHiddenComponentTypeIds = (state) => state.componentTypeReducer.hiddenComponentTypeIds;
|
|
1854
|
-
const
|
|
1922
|
+
const selectComponentTypeAttachmentMapping = (state) => state.componentTypeReducer.attachments;
|
|
1923
|
+
const selectAllComponentTypeAttachments = createSelector(
|
|
1924
|
+
[selectComponentTypeAttachmentMapping],
|
|
1925
|
+
(mapping) => Object.values(mapping)
|
|
1926
|
+
);
|
|
1927
|
+
const selectAttachmentsOfComponentType = restructureCreateSelectorWithArgs(
|
|
1928
|
+
createSelector(
|
|
1929
|
+
[selectAllComponentTypeAttachments, (_state, componentTypeId) => componentTypeId],
|
|
1930
|
+
(attachments, componentTypeId) => {
|
|
1931
|
+
return attachments.filter(({ component_type_id }) => componentTypeId === component_type_id);
|
|
1932
|
+
}
|
|
1933
|
+
)
|
|
1934
|
+
);
|
|
1935
|
+
const {
|
|
1936
|
+
addComponentType,
|
|
1937
|
+
setComponentTypes,
|
|
1938
|
+
setComponentTypeAttachments,
|
|
1939
|
+
addComponentTypeAttachment,
|
|
1940
|
+
addComponentTypeAttachments,
|
|
1941
|
+
updateComponentTypeAttachment,
|
|
1942
|
+
removeComponentTypeAttachment,
|
|
1943
|
+
removeComponentTypeAttachments,
|
|
1944
|
+
toggleComponentTypeVisibility,
|
|
1945
|
+
deleteComponentType
|
|
1946
|
+
} = componentTypeSlice.actions;
|
|
1855
1947
|
const componentTypeReducer = componentTypeSlice.reducer;
|
|
1856
|
-
const initialState$
|
|
1948
|
+
const initialState$f = {
|
|
1857
1949
|
workspaces: {},
|
|
1858
1950
|
activeWorkspaceId: null
|
|
1859
1951
|
};
|
|
1860
1952
|
const workspaceSlice = createSlice({
|
|
1861
1953
|
name: "workspace",
|
|
1862
|
-
initialState: initialState$
|
|
1954
|
+
initialState: initialState$f,
|
|
1863
1955
|
// The `reducers` field lets us define reducers and generate associated actions
|
|
1864
1956
|
reducers: {
|
|
1865
1957
|
setWorkspaces: (state, action) => {
|
|
@@ -1916,20 +2008,21 @@ const selectPermittedWorkspaceIds = createSelector(
|
|
|
1916
2008
|
);
|
|
1917
2009
|
const workspaceReducer = workspaceSlice.reducer;
|
|
1918
2010
|
const maxRecentIssues = 10;
|
|
1919
|
-
const initialState$
|
|
2011
|
+
const initialState$e = {
|
|
1920
2012
|
issues: {},
|
|
1921
2013
|
attachments: {},
|
|
1922
2014
|
comments: {},
|
|
1923
2015
|
visibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],
|
|
2016
|
+
isFetchingInitialData: false,
|
|
1924
2017
|
visibleUserIds: null,
|
|
1925
2018
|
recentIssueIds: [],
|
|
1926
2019
|
activeIssueId: null
|
|
1927
2020
|
};
|
|
1928
2021
|
const issueSlice = createSlice({
|
|
1929
2022
|
name: "issues",
|
|
1930
|
-
initialState: initialState$
|
|
2023
|
+
initialState: initialState$e,
|
|
1931
2024
|
extraReducers: (builder) => builder.addCase("RESET", (state) => {
|
|
1932
|
-
Object.assign(state, initialState$
|
|
2025
|
+
Object.assign(state, initialState$e);
|
|
1933
2026
|
}),
|
|
1934
2027
|
reducers: {
|
|
1935
2028
|
setIssues: (state, action) => {
|
|
@@ -1941,11 +2034,7 @@ const issueSlice = createSlice({
|
|
|
1941
2034
|
});
|
|
1942
2035
|
},
|
|
1943
2036
|
// TODO: Reusable function
|
|
1944
|
-
|
|
1945
|
-
for (const attachment of action.payload) {
|
|
1946
|
-
state.attachments[attachment.offline_id] = attachment;
|
|
1947
|
-
}
|
|
1948
|
-
},
|
|
2037
|
+
setIssueAttachments: setAttachments,
|
|
1949
2038
|
setActiveIssueId: (state, action) => {
|
|
1950
2039
|
state.activeIssueId = action.payload;
|
|
1951
2040
|
},
|
|
@@ -1956,17 +2045,8 @@ const issueSlice = createSlice({
|
|
|
1956
2045
|
state.issues[action.payload.offline_id] = action.payload;
|
|
1957
2046
|
},
|
|
1958
2047
|
// TODO: Reusable function
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
throw new Error(`Attachment ${action.payload.offline_id} already exists.`);
|
|
1962
|
-
}
|
|
1963
|
-
state.attachments[action.payload.offline_id] = action.payload;
|
|
1964
|
-
},
|
|
1965
|
-
addAttachments: (state, action) => {
|
|
1966
|
-
for (const attachment of action.payload) {
|
|
1967
|
-
state.attachments[attachment.offline_id] = attachment;
|
|
1968
|
-
}
|
|
1969
|
-
},
|
|
2048
|
+
addIssueAttachment: addAttachment,
|
|
2049
|
+
addIssueAttachments: addAttachments,
|
|
1970
2050
|
updateIssue: (state, action) => {
|
|
1971
2051
|
if (action.payload.offline_id in state.issues) {
|
|
1972
2052
|
state.issues[action.payload.offline_id] = {
|
|
@@ -1978,13 +2058,7 @@ const issueSlice = createSlice({
|
|
|
1978
2058
|
}
|
|
1979
2059
|
},
|
|
1980
2060
|
// TODO: Reusable function
|
|
1981
|
-
|
|
1982
|
-
if (action.payload.offline_id in state.attachments) {
|
|
1983
|
-
state.attachments[action.payload.offline_id] = action.payload;
|
|
1984
|
-
} else {
|
|
1985
|
-
throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
|
|
1986
|
-
}
|
|
1987
|
-
},
|
|
2061
|
+
updateIssueAttachment: updateAttachment,
|
|
1988
2062
|
removeIssue: (state, action) => {
|
|
1989
2063
|
if (action.payload in state.issues) {
|
|
1990
2064
|
delete state.issues[action.payload];
|
|
@@ -1992,13 +2066,7 @@ const issueSlice = createSlice({
|
|
|
1992
2066
|
throw new Error(`Failed to remove issue because ID doesn't exist: ${action.payload}`);
|
|
1993
2067
|
}
|
|
1994
2068
|
},
|
|
1995
|
-
|
|
1996
|
-
if (action.payload in state.attachments) {
|
|
1997
|
-
delete state.attachments[action.payload];
|
|
1998
|
-
} else {
|
|
1999
|
-
throw new Error(`Attachment ${action.payload} does not exist.`);
|
|
2000
|
-
}
|
|
2001
|
-
},
|
|
2069
|
+
removeIssueAttachment: removeAttachment,
|
|
2002
2070
|
removeAttachmentsOfIssue: (state, action) => {
|
|
2003
2071
|
const attachments = Object.values(state.attachments).filter((a) => a.issue_id === action.payload);
|
|
2004
2072
|
for (const attachment of attachments) {
|
|
@@ -2008,6 +2076,9 @@ const issueSlice = createSlice({
|
|
|
2008
2076
|
setVisibleStatuses: (state, action) => {
|
|
2009
2077
|
state.visibleStatuses = action.payload;
|
|
2010
2078
|
},
|
|
2079
|
+
setIsFetchingInitialData: (state, action) => {
|
|
2080
|
+
state.isFetchingInitialData = action.payload;
|
|
2081
|
+
},
|
|
2011
2082
|
setVisibleUserIds: (state, action) => {
|
|
2012
2083
|
state.visibleUserIds = [...new Set(action.payload)];
|
|
2013
2084
|
},
|
|
@@ -2052,25 +2123,26 @@ const issueSlice = createSlice({
|
|
|
2052
2123
|
}
|
|
2053
2124
|
});
|
|
2054
2125
|
const {
|
|
2055
|
-
|
|
2056
|
-
|
|
2126
|
+
addIssueAttachment,
|
|
2127
|
+
addIssueAttachments,
|
|
2057
2128
|
addIssue,
|
|
2058
2129
|
addOrReplaceIssueComment,
|
|
2059
2130
|
addToRecentIssues,
|
|
2060
2131
|
cleanRecentIssues,
|
|
2061
|
-
|
|
2132
|
+
removeIssueAttachment,
|
|
2062
2133
|
removeAttachmentsOfIssue,
|
|
2063
2134
|
removeIssue,
|
|
2064
2135
|
removeIssueComment,
|
|
2065
2136
|
removeRecentIssue,
|
|
2066
2137
|
resetRecentIssues,
|
|
2067
2138
|
setActiveIssueId,
|
|
2068
|
-
|
|
2139
|
+
setIssueAttachments,
|
|
2140
|
+
setIsFetchingInitialData,
|
|
2069
2141
|
setIssueComments,
|
|
2070
2142
|
setIssues,
|
|
2071
2143
|
setVisibleStatuses,
|
|
2072
2144
|
setVisibleUserIds,
|
|
2073
|
-
|
|
2145
|
+
updateIssueAttachment,
|
|
2074
2146
|
updateIssue
|
|
2075
2147
|
} = issueSlice.actions;
|
|
2076
2148
|
const selectIssueMapping = (state) => state.issueReducer.issues;
|
|
@@ -2130,8 +2202,6 @@ const selectPhotoAttachmentsOfIssue = restructureCreateSelectorWithArgs(
|
|
|
2130
2202
|
createSelector(
|
|
2131
2203
|
[selectIssueAttachmentMapping, (_state, issueId) => issueId],
|
|
2132
2204
|
(attachmentMapping, issueId) => {
|
|
2133
|
-
if (!issueId)
|
|
2134
|
-
return void 0;
|
|
2135
2205
|
return Object.values(attachmentMapping).filter(
|
|
2136
2206
|
(attachment) => attachment.issue_id === issueId && attachment.file_type && attachment.file_type.startsWith("image/")
|
|
2137
2207
|
);
|
|
@@ -2164,6 +2234,7 @@ const selectIssue = restructureCreateSelectorWithArgs(
|
|
|
2164
2234
|
return mapping[id];
|
|
2165
2235
|
})
|
|
2166
2236
|
);
|
|
2237
|
+
const selectIsFetchingInitialData = (state) => state.issueReducer.isFetchingInitialData;
|
|
2167
2238
|
const selectAllAttachments = createSelector([selectIssueAttachmentMapping], (mapping) => Object.values(mapping));
|
|
2168
2239
|
const searchIssues = restructureCreateSelectorWithArgs(
|
|
2169
2240
|
createSelector(
|
|
@@ -2255,15 +2326,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
|
|
|
2255
2326
|
}
|
|
2256
2327
|
);
|
|
2257
2328
|
const issueReducer = issueSlice.reducer;
|
|
2258
|
-
const initialState$
|
|
2329
|
+
const initialState$d = {
|
|
2259
2330
|
s3Urls: {}
|
|
2260
2331
|
};
|
|
2261
2332
|
const msPerHour = 1e3 * 60 * 60;
|
|
2262
2333
|
const msPerWeek = msPerHour * 24 * 7;
|
|
2263
2334
|
const fileSlice = createSlice({
|
|
2264
2335
|
name: "file",
|
|
2265
|
-
initialState: initialState$
|
|
2266
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2336
|
+
initialState: initialState$d,
|
|
2337
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
|
|
2267
2338
|
reducers: {
|
|
2268
2339
|
setUploadUrl: (state, action) => {
|
|
2269
2340
|
const { url, fields, sha1 } = action.payload;
|
|
@@ -2290,7 +2361,7 @@ const selectUploadUrl = (sha1) => (state) => {
|
|
|
2290
2361
|
return url;
|
|
2291
2362
|
};
|
|
2292
2363
|
const fileReducer = fileSlice.reducer;
|
|
2293
|
-
const initialState$
|
|
2364
|
+
const initialState$c = {
|
|
2294
2365
|
// TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
|
|
2295
2366
|
mapStyle: MapStyle.SATELLITE,
|
|
2296
2367
|
showTooltips: false,
|
|
@@ -2298,8 +2369,8 @@ const initialState$d = {
|
|
|
2298
2369
|
};
|
|
2299
2370
|
const mapSlice = createSlice({
|
|
2300
2371
|
name: "map",
|
|
2301
|
-
initialState: initialState$
|
|
2302
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2372
|
+
initialState: initialState$c,
|
|
2373
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
|
|
2303
2374
|
reducers: {
|
|
2304
2375
|
setMapStyle: (state, action) => {
|
|
2305
2376
|
state.mapStyle = action.payload;
|
|
@@ -2341,24 +2412,7 @@ var VerificationCodeType = /* @__PURE__ */ ((VerificationCodeType2) => {
|
|
|
2341
2412
|
VerificationCodeType2[VerificationCodeType2["RESET_PASSWORD"] = 10] = "RESET_PASSWORD";
|
|
2342
2413
|
return VerificationCodeType2;
|
|
2343
2414
|
})(VerificationCodeType || {});
|
|
2344
|
-
|
|
2345
|
-
PaddleCheckoutEvent2["COMPLETED"] = "checkout.completed";
|
|
2346
|
-
PaddleCheckoutEvent2["CLOSED"] = "checkout.closed";
|
|
2347
|
-
return PaddleCheckoutEvent2;
|
|
2348
|
-
})(PaddleCheckoutEvent || {});
|
|
2349
|
-
var LicenseLevel = /* @__PURE__ */ ((LicenseLevel2) => {
|
|
2350
|
-
LicenseLevel2[LicenseLevel2["PRO"] = 0] = "PRO";
|
|
2351
|
-
return LicenseLevel2;
|
|
2352
|
-
})(LicenseLevel || {});
|
|
2353
|
-
var LicenseStatus = /* @__PURE__ */ ((LicenseStatus2) => {
|
|
2354
|
-
LicenseStatus2[LicenseStatus2["ACTIVE"] = 0] = "ACTIVE";
|
|
2355
|
-
LicenseStatus2[LicenseStatus2["PAUSED"] = 2] = "PAUSED";
|
|
2356
|
-
LicenseStatus2[LicenseStatus2["CANCELLED"] = 4] = "CANCELLED";
|
|
2357
|
-
LicenseStatus2[LicenseStatus2["INACTIVE"] = 6] = "INACTIVE";
|
|
2358
|
-
LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
|
|
2359
|
-
return LicenseStatus2;
|
|
2360
|
-
})(LicenseStatus || {});
|
|
2361
|
-
const initialState$c = {
|
|
2415
|
+
const initialState$b = {
|
|
2362
2416
|
users: {},
|
|
2363
2417
|
currentUser: {
|
|
2364
2418
|
id: 0,
|
|
@@ -2369,8 +2423,8 @@ const initialState$c = {
|
|
|
2369
2423
|
};
|
|
2370
2424
|
const userSlice = createSlice({
|
|
2371
2425
|
name: "users",
|
|
2372
|
-
initialState: initialState$
|
|
2373
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2426
|
+
initialState: initialState$b,
|
|
2427
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
|
|
2374
2428
|
reducers: {
|
|
2375
2429
|
setUsers: (state, action) => {
|
|
2376
2430
|
const usersMapping = {};
|
|
@@ -2432,13 +2486,13 @@ const selectUser = (userId) => (state) => {
|
|
|
2432
2486
|
const selectUsersAsMapping = (state) => state.userReducer.users;
|
|
2433
2487
|
const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
|
|
2434
2488
|
const userReducer = userSlice.reducer;
|
|
2435
|
-
const initialState$
|
|
2489
|
+
const initialState$a = {
|
|
2436
2490
|
organizationAccesses: {}
|
|
2437
2491
|
};
|
|
2438
2492
|
const organizationAccessSlice = createSlice({
|
|
2439
2493
|
name: "organizationAccess",
|
|
2440
|
-
initialState: initialState$
|
|
2441
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2494
|
+
initialState: initialState$a,
|
|
2495
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
|
|
2442
2496
|
reducers: {
|
|
2443
2497
|
setOrganizationAccesses: (state, action) => {
|
|
2444
2498
|
if (!Array.isArray(action.payload))
|
|
@@ -2501,64 +2555,151 @@ const selectOrganizationAccessUserMapping = (state) => {
|
|
|
2501
2555
|
return organizationAccesses;
|
|
2502
2556
|
};
|
|
2503
2557
|
const organizationAccessReducer = organizationAccessSlice.reducer;
|
|
2504
|
-
const initialState$
|
|
2505
|
-
|
|
2558
|
+
const initialState$9 = {
|
|
2559
|
+
organizations: {},
|
|
2560
|
+
activeOrganizationId: null
|
|
2506
2561
|
};
|
|
2507
|
-
const
|
|
2508
|
-
name: "
|
|
2509
|
-
initialState: initialState$
|
|
2510
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2562
|
+
const organizationSlice = createSlice({
|
|
2563
|
+
name: "organizations",
|
|
2564
|
+
initialState: initialState$9,
|
|
2565
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
|
|
2511
2566
|
reducers: {
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
|
|
2516
|
-
throw new Error("Tried to use setLicenses reducer with duplicate ID's");
|
|
2517
|
-
}
|
|
2518
|
-
const licenses = {};
|
|
2519
|
-
for (const license of action.payload) {
|
|
2520
|
-
licenses[license.offline_id] = license;
|
|
2567
|
+
setOrganizations: (state, action) => {
|
|
2568
|
+
for (const org of action.payload) {
|
|
2569
|
+
state.organizations[org.id] = org;
|
|
2521
2570
|
}
|
|
2522
|
-
state.licenses = licenses;
|
|
2523
2571
|
},
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2572
|
+
updateActiveOrganization: (state, action) => {
|
|
2573
|
+
if (!state.activeOrganizationId) {
|
|
2574
|
+
throw new Error("Cannot update name of active organization. Active organization ID does not exist");
|
|
2527
2575
|
}
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
if (!(action.payload.offline_id in state.licenses)) {
|
|
2531
|
-
throw new Error("Tried to update license that does not exist.");
|
|
2576
|
+
if (state.activeOrganizationId !== action.payload.id) {
|
|
2577
|
+
throw new Error("Tried updating active organization with different organization");
|
|
2532
2578
|
}
|
|
2533
|
-
state.
|
|
2579
|
+
state.organizations[state.activeOrganizationId] = action.payload;
|
|
2580
|
+
},
|
|
2581
|
+
setActiveOrganizationId: (state, action) => {
|
|
2582
|
+
state.activeOrganizationId = action.payload;
|
|
2534
2583
|
}
|
|
2535
2584
|
}
|
|
2536
2585
|
});
|
|
2537
|
-
const {
|
|
2538
|
-
const
|
|
2539
|
-
return state.
|
|
2586
|
+
const { setOrganizations, setActiveOrganizationId, updateActiveOrganization } = organizationSlice.actions;
|
|
2587
|
+
const selectActiveOrganizationId = (state) => {
|
|
2588
|
+
return state.organizationReducer.activeOrganizationId;
|
|
2589
|
+
};
|
|
2590
|
+
const selectOrganizations = (state) => {
|
|
2591
|
+
return Object.values(state.organizationReducer.organizations);
|
|
2540
2592
|
};
|
|
2541
|
-
const
|
|
2542
|
-
|
|
2543
|
-
(
|
|
2544
|
-
) ?? null;
|
|
2545
|
-
const selectLicenseForProject = (projectId) => (state) => Object.values(state.licenseReducer.licenses).find((license) => license.project === projectId);
|
|
2546
|
-
const selectActiveStatusLicenses = createSelector(
|
|
2547
|
-
[selectLicenses],
|
|
2548
|
-
(licenses) => Object.values(licenses).filter((license) => license.is_active)
|
|
2593
|
+
const selectOrganizationsWithAccess = createSelector(
|
|
2594
|
+
[selectOrganizations],
|
|
2595
|
+
(organizations) => Object.values(organizations).filter((organization) => organization.has_access)
|
|
2549
2596
|
);
|
|
2550
|
-
const
|
|
2551
|
-
|
|
2552
|
-
|
|
2597
|
+
const selectActiveOrganization = (state) => {
|
|
2598
|
+
const id = selectActiveOrganizationId(state);
|
|
2599
|
+
if (!id) {
|
|
2600
|
+
return null;
|
|
2601
|
+
}
|
|
2602
|
+
const organization = state.organizationReducer.organizations[id];
|
|
2603
|
+
if (!organization) {
|
|
2604
|
+
return null;
|
|
2605
|
+
}
|
|
2606
|
+
return organization;
|
|
2607
|
+
};
|
|
2608
|
+
const selectOrganizationUsersIds = createSelector(
|
|
2609
|
+
[selectOrganizationAccesses],
|
|
2610
|
+
(organizationAccesses) => Object.values(organizationAccesses).map((organizationAccess) => organizationAccess.user)
|
|
2553
2611
|
);
|
|
2554
|
-
const
|
|
2555
|
-
|
|
2612
|
+
const selectOrganizationUsersAsMapping = createSelector(
|
|
2613
|
+
[selectOrganizationUsersIds, selectUsersAsMapping],
|
|
2614
|
+
(organizationUserIds, users) => organizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {})
|
|
2615
|
+
);
|
|
2616
|
+
const selectSortedOrganizationUsers = createSelector(
|
|
2617
|
+
[selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],
|
|
2618
|
+
(currentUser, userMapping, organizationAccessMapping) => {
|
|
2619
|
+
return Object.values(userMapping).sort((userA, userB) => {
|
|
2620
|
+
if (userA.id === currentUser.id) {
|
|
2621
|
+
return -1;
|
|
2622
|
+
} else if (userB.id === currentUser.id) {
|
|
2623
|
+
return 1;
|
|
2624
|
+
}
|
|
2625
|
+
const organizationAccessesA = organizationAccessMapping[userA.id];
|
|
2626
|
+
const organizationAccessesB = organizationAccessMapping[userB.id];
|
|
2627
|
+
if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === (organizationAccessesB == null ? void 0 : organizationAccessesB.access_level)) {
|
|
2628
|
+
return userA.username.localeCompare(userB.username);
|
|
2629
|
+
}
|
|
2630
|
+
if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === OrganizationAccessLevel.ADMIN) {
|
|
2631
|
+
return -1;
|
|
2632
|
+
}
|
|
2633
|
+
return 1;
|
|
2634
|
+
});
|
|
2635
|
+
}
|
|
2636
|
+
);
|
|
2637
|
+
const selectOrganization = (id) => (state) => {
|
|
2638
|
+
return state.organizationReducer.organizations[id];
|
|
2639
|
+
};
|
|
2640
|
+
const organizationReducer = organizationSlice.reducer;
|
|
2641
|
+
const createOfflineAction = (request2, baseUrl) => {
|
|
2642
|
+
const requestWithUuid = request2.uuid ? request2 : { ...request2, uuid: v4() };
|
|
2643
|
+
return {
|
|
2644
|
+
payload: requestWithUuid,
|
|
2645
|
+
type: "",
|
|
2646
|
+
meta: {
|
|
2647
|
+
offline: {
|
|
2648
|
+
effect: {
|
|
2649
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2650
|
+
request: requestWithUuid,
|
|
2651
|
+
BASE_URL: baseUrl
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
}
|
|
2655
|
+
};
|
|
2656
|
+
};
|
|
2657
|
+
const initialState$8 = {
|
|
2658
|
+
deletedRequests: [],
|
|
2659
|
+
latestRetryTime: 0
|
|
2660
|
+
};
|
|
2661
|
+
const outboxSlice = createSlice({
|
|
2662
|
+
name: "outbox",
|
|
2663
|
+
initialState: initialState$8,
|
|
2664
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
|
|
2665
|
+
reducers: {
|
|
2666
|
+
// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
|
|
2667
|
+
// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
|
|
2668
|
+
// Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox
|
|
2669
|
+
enqueueRequest: {
|
|
2670
|
+
reducer: (state, _action) => {
|
|
2671
|
+
return state;
|
|
2672
|
+
},
|
|
2673
|
+
prepare: (payload) => {
|
|
2674
|
+
console.debug("Preparing to enqueue request", payload);
|
|
2675
|
+
const { BASE_URL, ...rest } = payload;
|
|
2676
|
+
return createOfflineAction(rest, BASE_URL);
|
|
2677
|
+
}
|
|
2678
|
+
},
|
|
2679
|
+
markForDeletion(state, action) {
|
|
2680
|
+
state.deletedRequests.push(action.payload);
|
|
2681
|
+
},
|
|
2682
|
+
markAsDeleted(state, action) {
|
|
2683
|
+
const index2 = state.deletedRequests.indexOf(action.payload);
|
|
2684
|
+
if (index2 !== -1)
|
|
2685
|
+
state.deletedRequests.splice(index2, 1);
|
|
2686
|
+
},
|
|
2687
|
+
_setLatestRetryTime: (state, action) => {
|
|
2688
|
+
state.latestRetryTime = action.payload;
|
|
2689
|
+
}
|
|
2690
|
+
}
|
|
2691
|
+
});
|
|
2692
|
+
const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
|
|
2693
|
+
const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
|
|
2694
|
+
const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
|
|
2695
|
+
const outboxReducer = outboxSlice.reducer;
|
|
2696
|
+
const initialState$7 = {
|
|
2556
2697
|
projectAccesses: {}
|
|
2557
2698
|
};
|
|
2558
2699
|
const projectAccessSlice = createSlice({
|
|
2559
2700
|
name: "projectAccess",
|
|
2560
|
-
initialState: initialState$
|
|
2561
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2701
|
+
initialState: initialState$7,
|
|
2702
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
|
|
2562
2703
|
reducers: {
|
|
2563
2704
|
setProjectAccesses: (state, action) => {
|
|
2564
2705
|
if (!Array.isArray(action.payload))
|
|
@@ -2626,7 +2767,7 @@ const selectProjectAccessUserMapping = (state) => {
|
|
|
2626
2767
|
return projectAccesses;
|
|
2627
2768
|
};
|
|
2628
2769
|
const projectAccessReducer = projectAccessSlice.reducer;
|
|
2629
|
-
const initialState$
|
|
2770
|
+
const initialState$6 = {
|
|
2630
2771
|
projects: {},
|
|
2631
2772
|
activeProjectId: null,
|
|
2632
2773
|
recentProjectIds: [],
|
|
@@ -2635,7 +2776,7 @@ const initialState$8 = {
|
|
|
2635
2776
|
};
|
|
2636
2777
|
const projectSlice = createSlice({
|
|
2637
2778
|
name: "projects",
|
|
2638
|
-
initialState: initialState$
|
|
2779
|
+
initialState: initialState$6,
|
|
2639
2780
|
reducers: {
|
|
2640
2781
|
setProjects: (state, action) => {
|
|
2641
2782
|
const projectsMap = {};
|
|
@@ -2681,27 +2822,6 @@ const projectSlice = createSlice({
|
|
|
2681
2822
|
} else {
|
|
2682
2823
|
throw new Error("Accept project invite: user is not in this project");
|
|
2683
2824
|
}
|
|
2684
|
-
},
|
|
2685
|
-
addActiveProjectIssuesCount: (state, action) => {
|
|
2686
|
-
if (!state.activeProjectId || !(state.activeProjectId in state.projects)) {
|
|
2687
|
-
throw new Error("Update issues count: no active project");
|
|
2688
|
-
}
|
|
2689
|
-
if (!state.projects[state.activeProjectId].issues_count) {
|
|
2690
|
-
state.projects[state.activeProjectId].issues_count = action.payload;
|
|
2691
|
-
} else {
|
|
2692
|
-
state.projects[state.activeProjectId].issues_count += action.payload;
|
|
2693
|
-
}
|
|
2694
|
-
},
|
|
2695
|
-
addActiveProjectFormSubmissionsCount: (state, action) => {
|
|
2696
|
-
if (state.activeProjectId && state.activeProjectId in state.projects) {
|
|
2697
|
-
if (!state.projects[state.activeProjectId].form_submissions_count) {
|
|
2698
|
-
state.projects[state.activeProjectId].form_submissions_count = action.payload;
|
|
2699
|
-
} else {
|
|
2700
|
-
state.projects[state.activeProjectId].form_submissions_count += action.payload;
|
|
2701
|
-
}
|
|
2702
|
-
} else {
|
|
2703
|
-
throw new Error("Update form submissions count: no active project");
|
|
2704
|
-
}
|
|
2705
2825
|
}
|
|
2706
2826
|
}
|
|
2707
2827
|
});
|
|
@@ -2712,9 +2832,7 @@ const {
|
|
|
2712
2832
|
setActiveProjectId,
|
|
2713
2833
|
setCreateProjectType,
|
|
2714
2834
|
deleteProject,
|
|
2715
|
-
acceptProjectInvite
|
|
2716
|
-
addActiveProjectIssuesCount,
|
|
2717
|
-
addActiveProjectFormSubmissionsCount
|
|
2835
|
+
acceptProjectInvite
|
|
2718
2836
|
} = projectSlice.actions;
|
|
2719
2837
|
const selectProjects = (state) => state.projectReducer.projects;
|
|
2720
2838
|
const selectActiveProjectId = (state) => state.projectReducer.activeProjectId;
|
|
@@ -2778,171 +2896,6 @@ const selectSortedProjectUsers = createSelector(
|
|
|
2778
2896
|
});
|
|
2779
2897
|
}
|
|
2780
2898
|
);
|
|
2781
|
-
const initialState$7 = {
|
|
2782
|
-
organizations: {},
|
|
2783
|
-
activeOrganizationId: null
|
|
2784
|
-
};
|
|
2785
|
-
const organizationSlice = createSlice({
|
|
2786
|
-
name: "organizations",
|
|
2787
|
-
initialState: initialState$7,
|
|
2788
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
|
|
2789
|
-
reducers: {
|
|
2790
|
-
setOrganizations: (state, action) => {
|
|
2791
|
-
for (const org of action.payload) {
|
|
2792
|
-
state.organizations[org.id] = org;
|
|
2793
|
-
}
|
|
2794
|
-
},
|
|
2795
|
-
updateActiveOrganization: (state, action) => {
|
|
2796
|
-
if (!state.activeOrganizationId) {
|
|
2797
|
-
throw new Error("Cannot update name of active organization. Active organization ID does not exist");
|
|
2798
|
-
}
|
|
2799
|
-
if (state.activeOrganizationId !== action.payload.id) {
|
|
2800
|
-
throw new Error("Tried updating active organization with different organization");
|
|
2801
|
-
}
|
|
2802
|
-
state.organizations[state.activeOrganizationId] = action.payload;
|
|
2803
|
-
},
|
|
2804
|
-
setActiveOrganizationId: (state, action) => {
|
|
2805
|
-
state.activeOrganizationId = action.payload;
|
|
2806
|
-
}
|
|
2807
|
-
}
|
|
2808
|
-
});
|
|
2809
|
-
const { setOrganizations, setActiveOrganizationId, updateActiveOrganization } = organizationSlice.actions;
|
|
2810
|
-
const selectActiveOrganizationId = (state) => {
|
|
2811
|
-
return state.organizationReducer.activeOrganizationId;
|
|
2812
|
-
};
|
|
2813
|
-
const selectOrganizations = (state) => {
|
|
2814
|
-
return Object.values(state.organizationReducer.organizations);
|
|
2815
|
-
};
|
|
2816
|
-
const selectOrganizationsMapping = (state) => {
|
|
2817
|
-
return state.organizationReducer.organizations;
|
|
2818
|
-
};
|
|
2819
|
-
const selectOrganizationsWithAccess = createSelector(
|
|
2820
|
-
[selectOrganizations],
|
|
2821
|
-
(organizations) => Object.values(organizations).filter((organization) => organization.has_access)
|
|
2822
|
-
);
|
|
2823
|
-
const selectActiveOrganization = (state) => {
|
|
2824
|
-
const id = selectActiveOrganizationId(state);
|
|
2825
|
-
if (!id) {
|
|
2826
|
-
return null;
|
|
2827
|
-
}
|
|
2828
|
-
const organization = state.organizationReducer.organizations[id];
|
|
2829
|
-
if (!organization) {
|
|
2830
|
-
return null;
|
|
2831
|
-
}
|
|
2832
|
-
return organization;
|
|
2833
|
-
};
|
|
2834
|
-
const selectOrganizationUsersIds = createSelector(
|
|
2835
|
-
[selectOrganizationAccesses],
|
|
2836
|
-
(organizationAccesses) => Object.values(organizationAccesses).map((organizationAccess) => organizationAccess.user)
|
|
2837
|
-
);
|
|
2838
|
-
const selectActiveOrganizationProjects = createSelector(
|
|
2839
|
-
[selectProjects, selectActiveOrganizationId],
|
|
2840
|
-
(projects, activeOrganizationId) => activeOrganizationId ? Object.values(projects).filter((project) => project.owner_organization === activeOrganizationId) : []
|
|
2841
|
-
);
|
|
2842
|
-
const selectActiveOrganizationLicenses = createSelector(
|
|
2843
|
-
[selectActiveOrganizationId, selectLicenses],
|
|
2844
|
-
(activeOrganizationId, licenses) => !activeOrganizationId ? [] : Object.values(licenses).filter((license) => license.organization_owner === activeOrganizationId)
|
|
2845
|
-
);
|
|
2846
|
-
const selectSortedOrganizationLicenses = createSelector(
|
|
2847
|
-
[selectActiveOrganizationLicenses, selectProjects],
|
|
2848
|
-
(licences, projects) => licences.sort((licenseA, licenseB) => {
|
|
2849
|
-
if (!licenseA.project) {
|
|
2850
|
-
return 1;
|
|
2851
|
-
}
|
|
2852
|
-
if (!licenseB.project) {
|
|
2853
|
-
return -1;
|
|
2854
|
-
}
|
|
2855
|
-
return projects[licenseA.project].name.toLowerCase().localeCompare(
|
|
2856
|
-
projects[licenseB.project].name.toLowerCase(),
|
|
2857
|
-
void 0,
|
|
2858
|
-
{ numeric: true }
|
|
2859
|
-
);
|
|
2860
|
-
})
|
|
2861
|
-
);
|
|
2862
|
-
const selectOrganizationUsersAsMapping = createSelector(
|
|
2863
|
-
[selectOrganizationUsersIds, selectUsersAsMapping],
|
|
2864
|
-
(organizationUserIds, users) => organizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {})
|
|
2865
|
-
);
|
|
2866
|
-
const selectSortedOrganizationUsers = createSelector(
|
|
2867
|
-
[selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],
|
|
2868
|
-
(currentUser, userMapping, organizationAccessMapping) => {
|
|
2869
|
-
return Object.values(userMapping).sort((userA, userB) => {
|
|
2870
|
-
if (userA.id === currentUser.id) {
|
|
2871
|
-
return -1;
|
|
2872
|
-
} else if (userB.id === currentUser.id) {
|
|
2873
|
-
return 1;
|
|
2874
|
-
}
|
|
2875
|
-
const organizationAccessesA = organizationAccessMapping[userA.id];
|
|
2876
|
-
const organizationAccessesB = organizationAccessMapping[userB.id];
|
|
2877
|
-
if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === (organizationAccessesB == null ? void 0 : organizationAccessesB.access_level)) {
|
|
2878
|
-
return userA.username.localeCompare(userB.username);
|
|
2879
|
-
}
|
|
2880
|
-
if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === OrganizationAccessLevel.ADMIN) {
|
|
2881
|
-
return -1;
|
|
2882
|
-
}
|
|
2883
|
-
return 1;
|
|
2884
|
-
});
|
|
2885
|
-
}
|
|
2886
|
-
);
|
|
2887
|
-
const selectOrganization = (id) => (state) => {
|
|
2888
|
-
return state.organizationReducer.organizations[id];
|
|
2889
|
-
};
|
|
2890
|
-
const organizationReducer = organizationSlice.reducer;
|
|
2891
|
-
const createOfflineAction = (request2, baseUrl) => {
|
|
2892
|
-
const requestWithUuid = request2.uuid ? request2 : { ...request2, uuid: v4() };
|
|
2893
|
-
return {
|
|
2894
|
-
payload: requestWithUuid,
|
|
2895
|
-
type: "",
|
|
2896
|
-
meta: {
|
|
2897
|
-
offline: {
|
|
2898
|
-
effect: {
|
|
2899
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2900
|
-
request: requestWithUuid,
|
|
2901
|
-
BASE_URL: baseUrl
|
|
2902
|
-
}
|
|
2903
|
-
}
|
|
2904
|
-
}
|
|
2905
|
-
};
|
|
2906
|
-
};
|
|
2907
|
-
const initialState$6 = {
|
|
2908
|
-
deletedRequests: [],
|
|
2909
|
-
latestRetryTime: 0
|
|
2910
|
-
};
|
|
2911
|
-
const outboxSlice = createSlice({
|
|
2912
|
-
name: "outbox",
|
|
2913
|
-
initialState: initialState$6,
|
|
2914
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
|
|
2915
|
-
reducers: {
|
|
2916
|
-
// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
|
|
2917
|
-
// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
|
|
2918
|
-
// Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox
|
|
2919
|
-
enqueueRequest: {
|
|
2920
|
-
reducer: (state, _action) => {
|
|
2921
|
-
return state;
|
|
2922
|
-
},
|
|
2923
|
-
prepare: (payload) => {
|
|
2924
|
-
console.debug("Preparing to enqueue request", payload);
|
|
2925
|
-
const { BASE_URL, ...rest } = payload;
|
|
2926
|
-
return createOfflineAction(rest, BASE_URL);
|
|
2927
|
-
}
|
|
2928
|
-
},
|
|
2929
|
-
markForDeletion(state, action) {
|
|
2930
|
-
state.deletedRequests.push(action.payload);
|
|
2931
|
-
},
|
|
2932
|
-
markAsDeleted(state, action) {
|
|
2933
|
-
const index2 = state.deletedRequests.indexOf(action.payload);
|
|
2934
|
-
if (index2 !== -1)
|
|
2935
|
-
state.deletedRequests.splice(index2, 1);
|
|
2936
|
-
},
|
|
2937
|
-
_setLatestRetryTime: (state, action) => {
|
|
2938
|
-
state.latestRetryTime = action.payload;
|
|
2939
|
-
}
|
|
2940
|
-
}
|
|
2941
|
-
});
|
|
2942
|
-
const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
|
|
2943
|
-
const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
|
|
2944
|
-
const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
|
|
2945
|
-
const outboxReducer = outboxSlice.reducer;
|
|
2946
2899
|
const initialState$5 = {
|
|
2947
2900
|
projectFiles: {},
|
|
2948
2901
|
activeProjectFileId: null,
|
|
@@ -3079,9 +3032,7 @@ const initialState$3 = {
|
|
|
3079
3032
|
Components: false,
|
|
3080
3033
|
Experimental: false
|
|
3081
3034
|
},
|
|
3082
|
-
appearance: "dark"
|
|
3083
|
-
isFetchingInitialData: false,
|
|
3084
|
-
isLoading: false
|
|
3035
|
+
appearance: "dark"
|
|
3085
3036
|
};
|
|
3086
3037
|
const settingSlice = createSlice({
|
|
3087
3038
|
name: "settings",
|
|
@@ -3105,12 +3056,6 @@ const settingSlice = createSlice({
|
|
|
3105
3056
|
},
|
|
3106
3057
|
setAppearance: (state, action) => {
|
|
3107
3058
|
state.appearance = action.payload;
|
|
3108
|
-
},
|
|
3109
|
-
setIsFetchingInitialData: (state, action) => {
|
|
3110
|
-
state.isFetchingInitialData = action.payload;
|
|
3111
|
-
},
|
|
3112
|
-
setIsLoading: (state, action) => {
|
|
3113
|
-
state.isLoading = action.payload;
|
|
3114
3059
|
}
|
|
3115
3060
|
}
|
|
3116
3061
|
});
|
|
@@ -3119,9 +3064,7 @@ const {
|
|
|
3119
3064
|
setEnablePlacementMode,
|
|
3120
3065
|
setSectionExpanded,
|
|
3121
3066
|
setEnableClustering,
|
|
3122
|
-
setAppearance
|
|
3123
|
-
setIsFetchingInitialData,
|
|
3124
|
-
setIsLoading
|
|
3067
|
+
setAppearance
|
|
3125
3068
|
} = settingSlice.actions;
|
|
3126
3069
|
const selectEnablePlacementMode = (state) => state.settingReducer.placementMode;
|
|
3127
3070
|
const selectEnableDuplicateIssues = (state) => state.settingReducer.useIssueTemplate;
|
|
@@ -3130,8 +3073,6 @@ const selectExpandedSections = (state) => state.settingReducer.expandedSections;
|
|
|
3130
3073
|
const selectEnableClustering = (state) => state.settingReducer.enableClustering;
|
|
3131
3074
|
const selectAppearance = (state) => state.settingReducer.appearance;
|
|
3132
3075
|
const settingReducer = settingSlice.reducer;
|
|
3133
|
-
const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
|
|
3134
|
-
const selectIsLoading = (state) => state.settingReducer.isLoading;
|
|
3135
3076
|
const LATEST_REVISION_CACHE = {};
|
|
3136
3077
|
function considerCachingRevision(revision, formId2, preferPending = false) {
|
|
3137
3078
|
var _a2;
|
|
@@ -3550,8 +3491,7 @@ const overmapReducers = {
|
|
|
3550
3491
|
userFormReducer,
|
|
3551
3492
|
userReducer,
|
|
3552
3493
|
workspaceReducer,
|
|
3553
|
-
emailDomainsReducer
|
|
3554
|
-
licenseReducer
|
|
3494
|
+
emailDomainsReducer
|
|
3555
3495
|
};
|
|
3556
3496
|
const overmapReducer = combineReducers(overmapReducers);
|
|
3557
3497
|
const resetStore = "RESET";
|
|
@@ -4072,22 +4012,86 @@ class BaseApiService {
|
|
|
4072
4012
|
}
|
|
4073
4013
|
return promise;
|
|
4074
4014
|
}
|
|
4075
|
-
}
|
|
4076
|
-
class AttachmentService extends BaseApiService {
|
|
4077
|
-
fetchAll(projectId) {
|
|
4015
|
+
}
|
|
4016
|
+
class AttachmentService extends BaseApiService {
|
|
4017
|
+
fetchAll(projectId) {
|
|
4018
|
+
const promise = this.enqueueRequest({
|
|
4019
|
+
description: "Fetch attachments",
|
|
4020
|
+
method: HttpMethod.GET,
|
|
4021
|
+
url: `/attachments/${projectId}/`,
|
|
4022
|
+
blocks: [],
|
|
4023
|
+
blockers: []
|
|
4024
|
+
});
|
|
4025
|
+
const allAttachments = {
|
|
4026
|
+
issue_attachments: Object.values(this.client.store.getState().issueReducer.attachments),
|
|
4027
|
+
component_attachments: Object.values(this.client.store.getState().componentReducer.attachments),
|
|
4028
|
+
component_type_attachments: Object.values(this.client.store.getState().componentTypeReducer.attachments)
|
|
4029
|
+
};
|
|
4030
|
+
return [allAttachments, promise];
|
|
4031
|
+
}
|
|
4032
|
+
// Attachments aren't models, so we use the OptimisticGenericResult type instead
|
|
4033
|
+
async addIssueAttachment(attachmentPayload) {
|
|
4034
|
+
const { description: description2, issue_id, file_sha1, offline_id } = attachmentPayload;
|
|
4035
|
+
if (!attachmentPayload.file.objectURL) {
|
|
4036
|
+
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4037
|
+
}
|
|
4038
|
+
const offlineAttachment = {
|
|
4039
|
+
...attachmentPayload,
|
|
4040
|
+
file: attachmentPayload.file.objectURL,
|
|
4041
|
+
file_name: attachmentPayload.file.name,
|
|
4042
|
+
file_type: attachmentPayload.file.type
|
|
4043
|
+
};
|
|
4044
|
+
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4045
|
+
this.client.store.dispatch(addIssueAttachment(offlineAttachment));
|
|
4046
|
+
const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
|
|
4047
|
+
const promise = this.enqueueRequest({
|
|
4048
|
+
description: "Create attachment",
|
|
4049
|
+
method: HttpMethod.POST,
|
|
4050
|
+
url: `/issues/${issue_id}/attach/`,
|
|
4051
|
+
blocks: [offline_id, issue_id],
|
|
4052
|
+
blockers: [file_sha1],
|
|
4053
|
+
payload: {
|
|
4054
|
+
offline_id,
|
|
4055
|
+
issue: issue_id,
|
|
4056
|
+
description: description2 ?? "",
|
|
4057
|
+
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4058
|
+
...fileProps
|
|
4059
|
+
}
|
|
4060
|
+
});
|
|
4061
|
+
return [offlineAttachment, promise];
|
|
4062
|
+
}
|
|
4063
|
+
async addComponentAttachment(attachmentPayload) {
|
|
4064
|
+
const { description: description2, component_id, file_sha1, offline_id } = attachmentPayload;
|
|
4065
|
+
if (!attachmentPayload.file.objectURL) {
|
|
4066
|
+
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4067
|
+
}
|
|
4068
|
+
const offlineAttachment = {
|
|
4069
|
+
...attachmentPayload,
|
|
4070
|
+
file: attachmentPayload.file.objectURL,
|
|
4071
|
+
file_name: attachmentPayload.file.name,
|
|
4072
|
+
file_type: attachmentPayload.file.type
|
|
4073
|
+
};
|
|
4074
|
+
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4075
|
+
this.client.store.dispatch(addComponentAttachment(offlineAttachment));
|
|
4076
|
+
const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
|
|
4078
4077
|
const promise = this.enqueueRequest({
|
|
4079
|
-
description: "
|
|
4080
|
-
method: HttpMethod.
|
|
4081
|
-
url: `/
|
|
4082
|
-
blocks: [],
|
|
4083
|
-
blockers: []
|
|
4078
|
+
description: "Create attachment",
|
|
4079
|
+
method: HttpMethod.POST,
|
|
4080
|
+
url: `/components/${component_id}/attach/`,
|
|
4081
|
+
blocks: [offline_id, component_id],
|
|
4082
|
+
blockers: [file_sha1],
|
|
4083
|
+
payload: {
|
|
4084
|
+
offline_id,
|
|
4085
|
+
component: component_id,
|
|
4086
|
+
description: description2 ?? "",
|
|
4087
|
+
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4088
|
+
...fileProps
|
|
4089
|
+
}
|
|
4084
4090
|
});
|
|
4085
|
-
|
|
4086
|
-
return [allAttachments, promise];
|
|
4091
|
+
return [offlineAttachment, promise];
|
|
4087
4092
|
}
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
const { description: description2, issue_id, file_sha1, offline_id } = attachmentPayload;
|
|
4093
|
+
async addComponentTypeAttachment(attachmentPayload) {
|
|
4094
|
+
const { description: description2, component_type_id, file_sha1, offline_id } = attachmentPayload;
|
|
4091
4095
|
if (!attachmentPayload.file.objectURL) {
|
|
4092
4096
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4093
4097
|
}
|
|
@@ -4098,17 +4102,17 @@ class AttachmentService extends BaseApiService {
|
|
|
4098
4102
|
file_type: attachmentPayload.file.type
|
|
4099
4103
|
};
|
|
4100
4104
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4101
|
-
this.client.store.dispatch(
|
|
4105
|
+
this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
|
|
4102
4106
|
const [fileProps] = await this.client.files.uploadFileToS3(file_sha1);
|
|
4103
4107
|
const promise = this.enqueueRequest({
|
|
4104
4108
|
description: "Create attachment",
|
|
4105
4109
|
method: HttpMethod.POST,
|
|
4106
|
-
url: `/
|
|
4107
|
-
blocks: [offline_id,
|
|
4110
|
+
url: `/component_types/${component_type_id}/attach/`,
|
|
4111
|
+
blocks: [offline_id, component_type_id],
|
|
4108
4112
|
blockers: [file_sha1],
|
|
4109
4113
|
payload: {
|
|
4110
4114
|
offline_id,
|
|
4111
|
-
|
|
4115
|
+
component_type: component_type_id,
|
|
4112
4116
|
description: description2 ?? "",
|
|
4113
4117
|
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4114
4118
|
...fileProps
|
|
@@ -4116,27 +4120,67 @@ class AttachmentService extends BaseApiService {
|
|
|
4116
4120
|
});
|
|
4117
4121
|
return [offlineAttachment, promise];
|
|
4118
4122
|
}
|
|
4119
|
-
|
|
4120
|
-
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4123
|
+
/** the outer Promise is needed to await the hashing of each file, which is required before offline use. If wanting to
|
|
4124
|
+
* attach promise handlers to the request to add the attachment in the backend, apply it on the promise returned from the
|
|
4125
|
+
* OptimisticModelResult. */
|
|
4126
|
+
attachFilesToIssue(filesToSubmit, issueId) {
|
|
4127
|
+
return filesToSubmit.map((file) => {
|
|
4128
|
+
if (!(file instanceof File)) {
|
|
4129
|
+
throw new Error("Expected a File instance.");
|
|
4130
|
+
}
|
|
4131
|
+
const photoAttachmentPromise = async (file2) => {
|
|
4132
|
+
const hash = await hashFile(file2);
|
|
4133
|
+
const attachment = offline({
|
|
4134
|
+
file: file2,
|
|
4135
|
+
file_name: file2.name,
|
|
4136
|
+
file_type: file2.type,
|
|
4137
|
+
issue_id: issueId,
|
|
4138
|
+
file_sha1: hash
|
|
4139
|
+
});
|
|
4140
|
+
return this.addIssueAttachment(attachment);
|
|
4141
|
+
};
|
|
4142
|
+
return photoAttachmentPromise(file);
|
|
4143
|
+
});
|
|
4144
|
+
}
|
|
4145
|
+
attachFilesToComponent(filesToSubmit, componentId) {
|
|
4146
|
+
return filesToSubmit.map((file) => {
|
|
4147
|
+
if (!(file instanceof File)) {
|
|
4148
|
+
throw new Error("Expected a File instance.");
|
|
4149
|
+
}
|
|
4150
|
+
const photoAttachmentPromise = async (file2) => {
|
|
4151
|
+
const hash = await hashFile(file2);
|
|
4152
|
+
const attachment = offline({
|
|
4153
|
+
file: file2,
|
|
4154
|
+
file_name: file2.name,
|
|
4155
|
+
file_type: file2.type,
|
|
4156
|
+
component_id: componentId,
|
|
4157
|
+
file_sha1: hash
|
|
4158
|
+
});
|
|
4159
|
+
return this.addComponentAttachment(attachment);
|
|
4160
|
+
};
|
|
4161
|
+
return photoAttachmentPromise(file);
|
|
4162
|
+
});
|
|
4163
|
+
}
|
|
4164
|
+
attachFilesToComponentType(filesToSubmit, componentTypeId) {
|
|
4165
|
+
return filesToSubmit.map((file) => {
|
|
4166
|
+
if (!(file instanceof File)) {
|
|
4167
|
+
throw new Error("Expected a File instance.");
|
|
4168
|
+
}
|
|
4169
|
+
const photoAttachmentPromise = async (file2) => {
|
|
4170
|
+
const hash = await hashFile(file2);
|
|
4171
|
+
const attachment = offline({
|
|
4172
|
+
file: file2,
|
|
4173
|
+
file_name: file2.name,
|
|
4174
|
+
file_type: file2.type,
|
|
4175
|
+
component_type_id: componentTypeId,
|
|
4176
|
+
file_sha1: hash
|
|
4177
|
+
});
|
|
4178
|
+
return this.addComponentTypeAttachment(attachment);
|
|
4179
|
+
};
|
|
4180
|
+
return photoAttachmentPromise(file);
|
|
4181
|
+
});
|
|
4138
4182
|
}
|
|
4139
|
-
async
|
|
4183
|
+
async replaceIssueAttachmentFile(attachmentId, newFile) {
|
|
4140
4184
|
const { store } = this.client;
|
|
4141
4185
|
const attachment = store.getState().issueReducer.attachments[attachmentId];
|
|
4142
4186
|
if (!attachment)
|
|
@@ -4151,16 +4195,136 @@ class AttachmentService extends BaseApiService {
|
|
|
4151
4195
|
if (!newFile.objectURL) {
|
|
4152
4196
|
throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
|
|
4153
4197
|
}
|
|
4154
|
-
store.dispatch(
|
|
4198
|
+
store.dispatch(
|
|
4199
|
+
updateIssueAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) })
|
|
4200
|
+
);
|
|
4201
|
+
await this.client.files.addCache(newFile, newSha1);
|
|
4202
|
+
const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
|
|
4203
|
+
store.dispatch(updateIssueAttachment(attachment));
|
|
4204
|
+
throw e;
|
|
4205
|
+
});
|
|
4206
|
+
const promise2 = this.enqueueRequest({
|
|
4207
|
+
description: "Edit attachment",
|
|
4208
|
+
method: HttpMethod.PATCH,
|
|
4209
|
+
url: `/attachments/issues/${attachment.offline_id}/`,
|
|
4210
|
+
isResponseBlob: false,
|
|
4211
|
+
payload: fileProps,
|
|
4212
|
+
blockers: [attachmentId, newSha1],
|
|
4213
|
+
blocks: [attachmentId, newSha1]
|
|
4214
|
+
});
|
|
4215
|
+
try {
|
|
4216
|
+
const result = await promise2;
|
|
4217
|
+
void this.client.files.removeCache(attachment.file_sha1);
|
|
4218
|
+
return result;
|
|
4219
|
+
} catch (e) {
|
|
4220
|
+
if (oldFile) {
|
|
4221
|
+
store.dispatch(
|
|
4222
|
+
updateIssueAttachment({
|
|
4223
|
+
...attachment,
|
|
4224
|
+
file_sha1: attachment.file_sha1,
|
|
4225
|
+
file: URL.createObjectURL(oldFile)
|
|
4226
|
+
})
|
|
4227
|
+
);
|
|
4228
|
+
}
|
|
4229
|
+
throw e;
|
|
4230
|
+
}
|
|
4231
|
+
};
|
|
4232
|
+
const offlineAttachment = {
|
|
4233
|
+
...attachment,
|
|
4234
|
+
file_sha1: newSha1,
|
|
4235
|
+
file: URL.createObjectURL(newFile)
|
|
4236
|
+
};
|
|
4237
|
+
const promise = performRequest2();
|
|
4238
|
+
return [offlineAttachment, promise];
|
|
4239
|
+
}
|
|
4240
|
+
async replaceComponentAttachmentFile(attachmentId, newFile) {
|
|
4241
|
+
const { store } = this.client;
|
|
4242
|
+
const attachment = store.getState().componentReducer.attachments[attachmentId];
|
|
4243
|
+
if (!attachment)
|
|
4244
|
+
throw new Error(`Attachment ${attachmentId} not found`);
|
|
4245
|
+
let oldFile = void 0;
|
|
4246
|
+
const newSha1 = await hashFile(newFile);
|
|
4247
|
+
const performRequest2 = async () => {
|
|
4248
|
+
oldFile = await this.client.files.fetchCache(attachment.file_sha1);
|
|
4249
|
+
if (!oldFile) {
|
|
4250
|
+
console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
|
|
4251
|
+
}
|
|
4252
|
+
if (!newFile.objectURL) {
|
|
4253
|
+
throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
|
|
4254
|
+
}
|
|
4255
|
+
store.dispatch(
|
|
4256
|
+
updateComponentAttachment({ ...attachment, file_sha1: newSha1, file: URL.createObjectURL(newFile) })
|
|
4257
|
+
);
|
|
4258
|
+
await this.client.files.addCache(newFile, newSha1);
|
|
4259
|
+
const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
|
|
4260
|
+
store.dispatch(updateComponentAttachment(attachment));
|
|
4261
|
+
throw e;
|
|
4262
|
+
});
|
|
4263
|
+
const promise2 = this.enqueueRequest({
|
|
4264
|
+
description: "Edit attachment",
|
|
4265
|
+
method: HttpMethod.PATCH,
|
|
4266
|
+
url: `/attachments/components/${attachment.offline_id}/`,
|
|
4267
|
+
isResponseBlob: false,
|
|
4268
|
+
payload: fileProps,
|
|
4269
|
+
blockers: [attachmentId, newSha1],
|
|
4270
|
+
blocks: [attachmentId, newSha1]
|
|
4271
|
+
});
|
|
4272
|
+
try {
|
|
4273
|
+
const result = await promise2;
|
|
4274
|
+
void this.client.files.removeCache(attachment.file_sha1);
|
|
4275
|
+
return result;
|
|
4276
|
+
} catch (e) {
|
|
4277
|
+
if (oldFile) {
|
|
4278
|
+
store.dispatch(
|
|
4279
|
+
updateComponentAttachment({
|
|
4280
|
+
...attachment,
|
|
4281
|
+
file_sha1: attachment.file_sha1,
|
|
4282
|
+
file: URL.createObjectURL(oldFile)
|
|
4283
|
+
})
|
|
4284
|
+
);
|
|
4285
|
+
}
|
|
4286
|
+
throw e;
|
|
4287
|
+
}
|
|
4288
|
+
};
|
|
4289
|
+
const offlineAttachment = {
|
|
4290
|
+
...attachment,
|
|
4291
|
+
file_sha1: newSha1,
|
|
4292
|
+
file: URL.createObjectURL(newFile)
|
|
4293
|
+
};
|
|
4294
|
+
const promise = performRequest2();
|
|
4295
|
+
return [offlineAttachment, promise];
|
|
4296
|
+
}
|
|
4297
|
+
async replaceComponentTypeAttachmentFile(attachmentId, newFile) {
|
|
4298
|
+
const { store } = this.client;
|
|
4299
|
+
const attachment = store.getState().componentTypeReducer.attachments[attachmentId];
|
|
4300
|
+
if (!attachment)
|
|
4301
|
+
throw new Error(`Attachment ${attachmentId} not found`);
|
|
4302
|
+
let oldFile = void 0;
|
|
4303
|
+
const newSha1 = await hashFile(newFile);
|
|
4304
|
+
const performRequest2 = async () => {
|
|
4305
|
+
oldFile = await this.client.files.fetchCache(attachment.file_sha1);
|
|
4306
|
+
if (!oldFile) {
|
|
4307
|
+
console.error(`Failed to fetch old file from cache for sha1 ${attachment.file_sha1}.`);
|
|
4308
|
+
}
|
|
4309
|
+
if (!newFile.objectURL) {
|
|
4310
|
+
throw new Error(`newFile["objectURL"] is unexpectedly ${newFile.objectURL}`);
|
|
4311
|
+
}
|
|
4312
|
+
store.dispatch(
|
|
4313
|
+
updateComponentTypeAttachment({
|
|
4314
|
+
...attachment,
|
|
4315
|
+
file_sha1: newSha1,
|
|
4316
|
+
file: URL.createObjectURL(newFile)
|
|
4317
|
+
})
|
|
4318
|
+
);
|
|
4155
4319
|
await this.client.files.addCache(newFile, newSha1);
|
|
4156
4320
|
const [fileProps] = await this.client.files.uploadFileToS3(newSha1).catch((e) => {
|
|
4157
|
-
store.dispatch(
|
|
4321
|
+
store.dispatch(updateComponentTypeAttachment(attachment));
|
|
4158
4322
|
throw e;
|
|
4159
4323
|
});
|
|
4160
4324
|
const promise2 = this.enqueueRequest({
|
|
4161
4325
|
description: "Edit attachment",
|
|
4162
4326
|
method: HttpMethod.PATCH,
|
|
4163
|
-
url: `/attachments/${attachment.offline_id}/`,
|
|
4327
|
+
url: `/attachments/component_types/${attachment.offline_id}/`,
|
|
4164
4328
|
isResponseBlob: false,
|
|
4165
4329
|
payload: fileProps,
|
|
4166
4330
|
blockers: [attachmentId, newSha1],
|
|
@@ -4173,7 +4337,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4173
4337
|
} catch (e) {
|
|
4174
4338
|
if (oldFile) {
|
|
4175
4339
|
store.dispatch(
|
|
4176
|
-
|
|
4340
|
+
updateComponentTypeAttachment({
|
|
4177
4341
|
...attachment,
|
|
4178
4342
|
file_sha1: attachment.file_sha1,
|
|
4179
4343
|
file: URL.createObjectURL(oldFile)
|
|
@@ -4193,23 +4357,54 @@ class AttachmentService extends BaseApiService {
|
|
|
4193
4357
|
}
|
|
4194
4358
|
/**
|
|
4195
4359
|
* Deletes an attachment and associated data in the cloud, in the Redux store and the cache.
|
|
4196
|
-
* @param
|
|
4360
|
+
* @param issueAttachmentId
|
|
4197
4361
|
*/
|
|
4198
|
-
|
|
4362
|
+
deleteIssueAttachment(issueAttachmentId) {
|
|
4199
4363
|
const { store } = this.client;
|
|
4200
|
-
const
|
|
4201
|
-
const attachment = storeStateIssueReducer.attachments[attachmentId];
|
|
4364
|
+
const attachment = selectIssueAttachmentMapping(store.getState())[issueAttachmentId];
|
|
4202
4365
|
if (!attachment) {
|
|
4203
|
-
throw new Error(`Attachment ${
|
|
4366
|
+
throw new Error(`Attachment ${issueAttachmentId} not found`);
|
|
4367
|
+
}
|
|
4368
|
+
store.dispatch(removeIssueAttachment(issueAttachmentId));
|
|
4369
|
+
void this.client.files.removeCache(attachment.file_sha1);
|
|
4370
|
+
return this.enqueueRequest({
|
|
4371
|
+
description: "Delete attachment",
|
|
4372
|
+
method: HttpMethod.DELETE,
|
|
4373
|
+
url: `/attachments/issues/${issueAttachmentId}/`,
|
|
4374
|
+
blockers: [issueAttachmentId],
|
|
4375
|
+
blocks: [issueAttachmentId]
|
|
4376
|
+
});
|
|
4377
|
+
}
|
|
4378
|
+
deleteComponentAttachment(componentAttachmentId) {
|
|
4379
|
+
const { store } = this.client;
|
|
4380
|
+
const attachment = selectComponentAttachmentMapping(store.getState())[componentAttachmentId];
|
|
4381
|
+
if (!attachment) {
|
|
4382
|
+
throw new Error(`Attachment ${componentAttachmentId} not found`);
|
|
4383
|
+
}
|
|
4384
|
+
store.dispatch(removeIssueAttachment(componentAttachmentId));
|
|
4385
|
+
void this.client.files.removeCache(attachment.file_sha1);
|
|
4386
|
+
return this.enqueueRequest({
|
|
4387
|
+
description: "Delete attachment",
|
|
4388
|
+
method: HttpMethod.DELETE,
|
|
4389
|
+
url: `/attachments/components/${componentAttachmentId}/`,
|
|
4390
|
+
blockers: [componentAttachmentId],
|
|
4391
|
+
blocks: [componentAttachmentId]
|
|
4392
|
+
});
|
|
4393
|
+
}
|
|
4394
|
+
deleteComponentTypeAttachment(componentTypeAttachmentId) {
|
|
4395
|
+
const { store } = this.client;
|
|
4396
|
+
const attachment = selectComponentTypeAttachmentMapping(store.getState())[componentTypeAttachmentId];
|
|
4397
|
+
if (!attachment) {
|
|
4398
|
+
throw new Error(`Attachment ${componentTypeAttachmentId} not found`);
|
|
4204
4399
|
}
|
|
4205
|
-
store.dispatch(
|
|
4400
|
+
store.dispatch(removeIssueAttachment(componentTypeAttachmentId));
|
|
4206
4401
|
void this.client.files.removeCache(attachment.file_sha1);
|
|
4207
4402
|
return this.enqueueRequest({
|
|
4208
4403
|
description: "Delete attachment",
|
|
4209
4404
|
method: HttpMethod.DELETE,
|
|
4210
|
-
url: `/attachments/${
|
|
4211
|
-
blockers: [
|
|
4212
|
-
blocks: [
|
|
4405
|
+
url: `/attachments/component_types/${componentTypeAttachmentId}/`,
|
|
4406
|
+
blockers: [componentTypeAttachmentId],
|
|
4407
|
+
blocks: [componentTypeAttachmentId]
|
|
4213
4408
|
});
|
|
4214
4409
|
}
|
|
4215
4410
|
}
|
|
@@ -4601,13 +4796,26 @@ class ComponentService extends BaseApiService {
|
|
|
4601
4796
|
return [component, promise];
|
|
4602
4797
|
}
|
|
4603
4798
|
async remove(id) {
|
|
4604
|
-
this.client
|
|
4799
|
+
const { store } = this.client;
|
|
4800
|
+
const backupComponent = selectComponent(id)(store.getState());
|
|
4801
|
+
if (!backupComponent)
|
|
4802
|
+
throw new Error(`No component with id ${id} found in the store`);
|
|
4803
|
+
const attachmentsOfComponent = selectAttachmentsOfComponent(id)(store.getState());
|
|
4804
|
+
store.dispatch(removeComponent(id));
|
|
4805
|
+
if (attachmentsOfComponent.length > 0) {
|
|
4806
|
+
const attachmentsOfComponentIds = attachmentsOfComponent.map(({ offline_id }) => offline_id);
|
|
4807
|
+
store.dispatch(removeComponentAttachments(attachmentsOfComponentIds));
|
|
4808
|
+
}
|
|
4605
4809
|
return this.enqueueRequest({
|
|
4606
4810
|
description: "Delete issue",
|
|
4607
4811
|
method: HttpMethod.DELETE,
|
|
4608
4812
|
url: `/components/${id}/`,
|
|
4609
4813
|
blockers: [id],
|
|
4610
4814
|
blocks: []
|
|
4815
|
+
}).catch((err) => {
|
|
4816
|
+
store.dispatch(addComponent(backupComponent));
|
|
4817
|
+
store.dispatch(addComponentAttachments(attachmentsOfComponent));
|
|
4818
|
+
throw err;
|
|
4611
4819
|
});
|
|
4612
4820
|
}
|
|
4613
4821
|
async deleteAllByComponentType(componentTypeId) {
|
|
@@ -4918,13 +5126,19 @@ class ComponentTypeService extends BaseApiService {
|
|
|
4918
5126
|
if (!componentType) {
|
|
4919
5127
|
throw new Error("Expected componentType to exist");
|
|
4920
5128
|
}
|
|
4921
|
-
const
|
|
4922
|
-
|
|
4923
|
-
removeStages(
|
|
4924
|
-
componentTypeStages.map((componentTypeStage) => componentTypeStage.offline_id)
|
|
4925
|
-
)
|
|
4926
|
-
);
|
|
5129
|
+
const stagesOfComponentType = selectStagesFromComponentType(componentTypeId)(state) ?? [];
|
|
5130
|
+
const attachmentsOfComponentType = selectAttachmentsOfComponentType(componentTypeId)(state);
|
|
4927
5131
|
store.dispatch(deleteComponentType(componentTypeId));
|
|
5132
|
+
if (stagesOfComponentType.length > 0) {
|
|
5133
|
+
const stagesOfComponentTypeIds = stagesOfComponentType.map(
|
|
5134
|
+
(componentTypeStage) => componentTypeStage.offline_id
|
|
5135
|
+
);
|
|
5136
|
+
store.dispatch(removeStages(stagesOfComponentTypeIds));
|
|
5137
|
+
}
|
|
5138
|
+
if (attachmentsOfComponentType.length > 0) {
|
|
5139
|
+
const attachmentsOfComponentTypeIds = attachmentsOfComponentType.map(({ offline_id }) => offline_id);
|
|
5140
|
+
store.dispatch(removeComponentTypeAttachments(attachmentsOfComponentTypeIds));
|
|
5141
|
+
}
|
|
4928
5142
|
return this.enqueueRequest({
|
|
4929
5143
|
description: "Delete ComponentType",
|
|
4930
5144
|
method: HttpMethod.DELETE,
|
|
@@ -4933,7 +5147,8 @@ class ComponentTypeService extends BaseApiService {
|
|
|
4933
5147
|
blocks: []
|
|
4934
5148
|
}).catch((e) => {
|
|
4935
5149
|
store.dispatch(addComponentType(componentType));
|
|
4936
|
-
store.dispatch(addStages(
|
|
5150
|
+
store.dispatch(addStages(stagesOfComponentType));
|
|
5151
|
+
store.dispatch(addComponentTypeAttachments(attachmentsOfComponentType));
|
|
4937
5152
|
throw e;
|
|
4938
5153
|
});
|
|
4939
5154
|
}
|
|
@@ -5038,7 +5253,6 @@ class IssueService extends BaseApiService {
|
|
|
5038
5253
|
});
|
|
5039
5254
|
store.dispatch(addIssue(issuePayload));
|
|
5040
5255
|
store.dispatch(addToRecentIssues(issuePayload.offline_id));
|
|
5041
|
-
store.dispatch(addActiveProjectIssuesCount(1));
|
|
5042
5256
|
const promise = this.enqueueRequest({
|
|
5043
5257
|
description: "Create issue",
|
|
5044
5258
|
method: HttpMethod.POST,
|
|
@@ -5048,7 +5262,6 @@ class IssueService extends BaseApiService {
|
|
|
5048
5262
|
},
|
|
5049
5263
|
payload: issuePayload,
|
|
5050
5264
|
blockers: [
|
|
5051
|
-
"add-issue",
|
|
5052
5265
|
...issuePayload.index_workspace ? [issuePayload.index_workspace] : [],
|
|
5053
5266
|
...issuePayload.visible_in_workspaces
|
|
5054
5267
|
],
|
|
@@ -5066,7 +5279,6 @@ class IssueService extends BaseApiService {
|
|
|
5066
5279
|
});
|
|
5067
5280
|
}
|
|
5068
5281
|
store.dispatch(removeIssue(issuePayload.offline_id));
|
|
5069
|
-
store.dispatch(addActiveProjectIssuesCount(-1));
|
|
5070
5282
|
throw error2;
|
|
5071
5283
|
});
|
|
5072
5284
|
return [issuePayload, promise];
|
|
@@ -5105,18 +5317,16 @@ class IssueService extends BaseApiService {
|
|
|
5105
5317
|
return [fullIssue, promise];
|
|
5106
5318
|
}
|
|
5107
5319
|
async remove(id) {
|
|
5108
|
-
const
|
|
5109
|
-
const state = store.getState();
|
|
5320
|
+
const state = this.client.store.getState();
|
|
5110
5321
|
const backup = state.issueReducer.issues[id];
|
|
5111
5322
|
if (!backup) {
|
|
5112
5323
|
throw new Error(`No issue with id ${id} found in the store`);
|
|
5113
5324
|
}
|
|
5114
5325
|
const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue_id === id);
|
|
5115
5326
|
const attachmentsOfIssue = selectPhotoAttachmentsOfIssue(id)(state);
|
|
5116
|
-
store.dispatch(removeIssue(id));
|
|
5117
|
-
store.dispatch(addActiveProjectIssuesCount(-1));
|
|
5327
|
+
this.client.store.dispatch(removeIssue(id));
|
|
5118
5328
|
if (attachmentsOfIssue) {
|
|
5119
|
-
store.dispatch(removeAttachmentsOfIssue(id));
|
|
5329
|
+
this.client.store.dispatch(removeAttachmentsOfIssue(id));
|
|
5120
5330
|
}
|
|
5121
5331
|
try {
|
|
5122
5332
|
return await this.enqueueRequest({
|
|
@@ -5127,9 +5337,8 @@ class IssueService extends BaseApiService {
|
|
|
5127
5337
|
blocks: []
|
|
5128
5338
|
});
|
|
5129
5339
|
} catch (e) {
|
|
5130
|
-
store.dispatch(addIssue(backup));
|
|
5131
|
-
store.dispatch(
|
|
5132
|
-
store.dispatch(addActiveProjectIssuesCount(1));
|
|
5340
|
+
this.client.store.dispatch(addIssue(backup));
|
|
5341
|
+
this.client.store.dispatch(addIssueAttachments(attachments));
|
|
5133
5342
|
throw e;
|
|
5134
5343
|
}
|
|
5135
5344
|
}
|
|
@@ -5205,9 +5414,7 @@ class MainService extends BaseApiService {
|
|
|
5205
5414
|
owner_organization: projectData.organization_owner,
|
|
5206
5415
|
owner_user: projectData.user_owner,
|
|
5207
5416
|
bounds: projectData.bounds,
|
|
5208
|
-
invited: projectData.invited || false
|
|
5209
|
-
issues_count: projectData.issues_count,
|
|
5210
|
-
form_submissions_count: projectData.form_submissions_count
|
|
5417
|
+
invited: projectData.invited || false
|
|
5211
5418
|
});
|
|
5212
5419
|
if (currentProjectId === projectData.id && !projectData.invited) {
|
|
5213
5420
|
isProjectIdValid = true;
|
|
@@ -5225,7 +5432,6 @@ class MainService extends BaseApiService {
|
|
|
5225
5432
|
}
|
|
5226
5433
|
store.dispatch(setCurrentUser(data.user));
|
|
5227
5434
|
store.dispatch(addUsers(data.project_owners));
|
|
5228
|
-
store.dispatch(setLicenses(data.licenses));
|
|
5229
5435
|
const organizationsData = data.organizations;
|
|
5230
5436
|
store.dispatch(setOrganizations(organizationsData));
|
|
5231
5437
|
const validProjects = projects.filter((project) => !project.invited);
|
|
@@ -5304,7 +5510,10 @@ class MainService extends BaseApiService {
|
|
|
5304
5510
|
if (currentProjectId) {
|
|
5305
5511
|
const [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId);
|
|
5306
5512
|
void promise.then((result) => {
|
|
5307
|
-
|
|
5513
|
+
const { issue_attachments, component_type_attachments, component_attachments } = result;
|
|
5514
|
+
store.dispatch(setIssueAttachments(issue_attachments));
|
|
5515
|
+
store.dispatch(setComponentAttachments(component_attachments));
|
|
5516
|
+
store.dispatch(setComponentTypeAttachments(component_type_attachments));
|
|
5308
5517
|
});
|
|
5309
5518
|
}
|
|
5310
5519
|
store.dispatch(setIsFetchingInitialData(false));
|
|
@@ -5339,7 +5548,7 @@ class ProjectAccessService extends BaseApiService {
|
|
|
5339
5548
|
method: HttpMethod.PATCH,
|
|
5340
5549
|
url: `/access/${projectAccess.offline_id}/`,
|
|
5341
5550
|
payload: projectAccess,
|
|
5342
|
-
blockers: [projectAccess.offline_id
|
|
5551
|
+
blockers: [projectAccess.offline_id],
|
|
5343
5552
|
blocks: [projectAccess.offline_id]
|
|
5344
5553
|
});
|
|
5345
5554
|
}
|
|
@@ -5548,11 +5757,6 @@ class ProjectService extends BaseApiService {
|
|
|
5548
5757
|
store.dispatch(removeProjectAccessesOfProject(project.id));
|
|
5549
5758
|
store.dispatch({ type: "rehydrated/setRehydrated", payload: false });
|
|
5550
5759
|
store.dispatch(deleteProject(project));
|
|
5551
|
-
const licenseSelector = selectLicenseForProject(project.id);
|
|
5552
|
-
const license = licenseSelector(state);
|
|
5553
|
-
if (license) {
|
|
5554
|
-
store.dispatch(updateLicense({ ...license, project: null }));
|
|
5555
|
-
}
|
|
5556
5760
|
try {
|
|
5557
5761
|
await this.enqueueRequest({
|
|
5558
5762
|
description: "Delete project",
|
|
@@ -5568,9 +5772,6 @@ class ProjectService extends BaseApiService {
|
|
|
5568
5772
|
store.dispatch(addOrReplaceProjectFiles(filesToDelete));
|
|
5569
5773
|
store.dispatch(setActiveProjectId(activeProjectId));
|
|
5570
5774
|
store.dispatch({ type: "rehydrated/setRehydrated", payload: true });
|
|
5571
|
-
if (license) {
|
|
5572
|
-
store.dispatch(updateLicense({ ...license, project: project.id }));
|
|
5573
|
-
}
|
|
5574
5775
|
throw e;
|
|
5575
5776
|
}
|
|
5576
5777
|
}
|
|
@@ -5945,7 +6146,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
5945
6146
|
method: HttpMethod.POST,
|
|
5946
6147
|
url: `/forms/revisions/${payload.form_revision}/respond/`,
|
|
5947
6148
|
payload: { ...payloadWithoutFiles, project: activeProjectId },
|
|
5948
|
-
blockers: [payload.issue, payload.component, payload.component_stage
|
|
6149
|
+
blockers: [payload.issue, payload.component, payload.component_stage].filter(
|
|
5949
6150
|
(x) => x !== void 0
|
|
5950
6151
|
),
|
|
5951
6152
|
blocks: [payload.offline_id]
|
|
@@ -5964,12 +6165,10 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
5964
6165
|
};
|
|
5965
6166
|
store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
|
|
5966
6167
|
void promise.then((result) => {
|
|
5967
|
-
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
5968
6168
|
store.dispatch(updateOrCreateUserFormSubmission(result));
|
|
5969
6169
|
return result;
|
|
5970
6170
|
}).catch(() => {
|
|
5971
6171
|
store.dispatch(deleteUserFormSubmission(payload.offline_id));
|
|
5972
|
-
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
5973
6172
|
});
|
|
5974
6173
|
const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
5975
6174
|
return [fullOfflineResult, settledPromise];
|
|
@@ -6003,7 +6202,6 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6003
6202
|
const state = store.getState();
|
|
6004
6203
|
const submission = state.userFormReducer.submissions[submissionId];
|
|
6005
6204
|
store.dispatch(deleteUserFormSubmission(submissionId));
|
|
6006
|
-
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
6007
6205
|
try {
|
|
6008
6206
|
return await this.enqueueRequest({
|
|
6009
6207
|
description: "Delete user form submissions",
|
|
@@ -6014,7 +6212,6 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6014
6212
|
});
|
|
6015
6213
|
} catch (e) {
|
|
6016
6214
|
if (submission) {
|
|
6017
|
-
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
6018
6215
|
store.dispatch(updateOrCreateUserFormSubmission(submission));
|
|
6019
6216
|
}
|
|
6020
6217
|
throw e;
|
|
@@ -6051,7 +6248,7 @@ class WorkspaceService extends BaseApiService {
|
|
|
6051
6248
|
method: HttpMethod.POST,
|
|
6052
6249
|
url: `/projects/${store.getState().projectReducer.activeProjectId}/workspaces/`,
|
|
6053
6250
|
payload: offlineWorkspace,
|
|
6054
|
-
blockers: [
|
|
6251
|
+
blockers: [],
|
|
6055
6252
|
blocks: [offlineWorkspace.offline_id]
|
|
6056
6253
|
});
|
|
6057
6254
|
void promise.then((result) => {
|
|
@@ -6472,121 +6669,6 @@ class OrganizationService extends BaseApiService {
|
|
|
6472
6669
|
});
|
|
6473
6670
|
}
|
|
6474
6671
|
}
|
|
6475
|
-
class LicenseService extends BaseApiService {
|
|
6476
|
-
async fetchLicensesForOrganization(organizationId, showLoading = false) {
|
|
6477
|
-
if (showLoading) {
|
|
6478
|
-
this.client.store.dispatch(setIsFetchingInitialData(true));
|
|
6479
|
-
}
|
|
6480
|
-
const result = await this.enqueueRequest({
|
|
6481
|
-
description: "Get licenses",
|
|
6482
|
-
method: HttpMethod.GET,
|
|
6483
|
-
url: `/organizations/${organizationId}/licenses/`,
|
|
6484
|
-
isAuthNeeded: true,
|
|
6485
|
-
blockers: [organizationId.toString()],
|
|
6486
|
-
blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
|
|
6487
|
-
});
|
|
6488
|
-
if (showLoading) {
|
|
6489
|
-
this.client.store.dispatch(setIsFetchingInitialData(false));
|
|
6490
|
-
}
|
|
6491
|
-
return result;
|
|
6492
|
-
}
|
|
6493
|
-
async getLicense(license) {
|
|
6494
|
-
const result = await this.enqueueRequest({
|
|
6495
|
-
description: "Get license",
|
|
6496
|
-
method: HttpMethod.GET,
|
|
6497
|
-
url: `/billing/${license.offline_id}/`,
|
|
6498
|
-
isAuthNeeded: true,
|
|
6499
|
-
blockers: [
|
|
6500
|
-
license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
|
|
6501
|
-
],
|
|
6502
|
-
blocks: []
|
|
6503
|
-
});
|
|
6504
|
-
this.client.store.dispatch(updateLicense(result));
|
|
6505
|
-
return result;
|
|
6506
|
-
}
|
|
6507
|
-
async pauseLicense(license) {
|
|
6508
|
-
const result = await this.enqueueRequest({
|
|
6509
|
-
description: "Pause license",
|
|
6510
|
-
method: HttpMethod.DELETE,
|
|
6511
|
-
url: `/billing/${license.offline_id}/suspend/`,
|
|
6512
|
-
isAuthNeeded: true,
|
|
6513
|
-
blockers: [
|
|
6514
|
-
license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
|
|
6515
|
-
],
|
|
6516
|
-
blocks: []
|
|
6517
|
-
});
|
|
6518
|
-
this.client.store.dispatch(updateLicense(result));
|
|
6519
|
-
return result;
|
|
6520
|
-
}
|
|
6521
|
-
async resumeLicense(license) {
|
|
6522
|
-
const result = await this.enqueueRequest({
|
|
6523
|
-
description: "Resume license",
|
|
6524
|
-
method: HttpMethod.PATCH,
|
|
6525
|
-
url: `/billing/${license.offline_id}/suspend/`,
|
|
6526
|
-
isAuthNeeded: true,
|
|
6527
|
-
blockers: [
|
|
6528
|
-
license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
|
|
6529
|
-
],
|
|
6530
|
-
blocks: []
|
|
6531
|
-
});
|
|
6532
|
-
this.client.store.dispatch(updateLicense(result));
|
|
6533
|
-
return result;
|
|
6534
|
-
}
|
|
6535
|
-
async cancelLicense(license) {
|
|
6536
|
-
const result = await this.enqueueRequest({
|
|
6537
|
-
description: "Cancel license",
|
|
6538
|
-
method: HttpMethod.DELETE,
|
|
6539
|
-
url: `/billing/${license.offline_id}/`,
|
|
6540
|
-
isAuthNeeded: true,
|
|
6541
|
-
blockers: [
|
|
6542
|
-
license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
|
|
6543
|
-
],
|
|
6544
|
-
blocks: []
|
|
6545
|
-
});
|
|
6546
|
-
this.client.store.dispatch(updateLicense(result));
|
|
6547
|
-
return result;
|
|
6548
|
-
}
|
|
6549
|
-
async attachLicenseToProject(license, project) {
|
|
6550
|
-
const result = await this.enqueueRequest({
|
|
6551
|
-
description: "Attach license",
|
|
6552
|
-
method: HttpMethod.PATCH,
|
|
6553
|
-
url: `/billing/${license.offline_id}/project/`,
|
|
6554
|
-
isAuthNeeded: true,
|
|
6555
|
-
payload: { project: project.id },
|
|
6556
|
-
blockers: [
|
|
6557
|
-
license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : "",
|
|
6558
|
-
project.id ? project.id.toString() : ""
|
|
6559
|
-
],
|
|
6560
|
-
blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
|
|
6561
|
-
});
|
|
6562
|
-
this.client.store.dispatch(updateLicense(result));
|
|
6563
|
-
return result;
|
|
6564
|
-
}
|
|
6565
|
-
async detachLicenseFromProject(license) {
|
|
6566
|
-
const result = await this.enqueueRequest({
|
|
6567
|
-
description: "Detach license",
|
|
6568
|
-
method: HttpMethod.DELETE,
|
|
6569
|
-
url: `/billing/${license.offline_id}/project/`,
|
|
6570
|
-
isAuthNeeded: true,
|
|
6571
|
-
blockers: [
|
|
6572
|
-
license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
|
|
6573
|
-
],
|
|
6574
|
-
blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
|
|
6575
|
-
});
|
|
6576
|
-
this.client.store.dispatch(updateLicense(result));
|
|
6577
|
-
return result;
|
|
6578
|
-
}
|
|
6579
|
-
async getLatestTransaction(license) {
|
|
6580
|
-
return await this.enqueueRequest({
|
|
6581
|
-
description: "Get latest transaction",
|
|
6582
|
-
method: HttpMethod.GET,
|
|
6583
|
-
url: `/billing/${license.offline_id}/transaction/`,
|
|
6584
|
-
isAuthNeeded: true,
|
|
6585
|
-
blockers: [license.offline_id],
|
|
6586
|
-
blocks: [license.offline_id]
|
|
6587
|
-
});
|
|
6588
|
-
}
|
|
6589
|
-
}
|
|
6590
6672
|
class OvermapSDK {
|
|
6591
6673
|
constructor(apiUrl, store) {
|
|
6592
6674
|
__publicField(this, "API_URL");
|
|
@@ -6612,7 +6694,6 @@ class OvermapSDK {
|
|
|
6612
6694
|
__publicField(this, "projectFiles", new ProjectFileService(this));
|
|
6613
6695
|
__publicField(this, "emailVerification", new EmailVerificationService(this));
|
|
6614
6696
|
__publicField(this, "emailDomains", new EmailDomainsService(this));
|
|
6615
|
-
__publicField(this, "licenses", new LicenseService(this));
|
|
6616
6697
|
this.API_URL = apiUrl;
|
|
6617
6698
|
this.store = store;
|
|
6618
6699
|
}
|
|
@@ -14626,9 +14707,6 @@ export {
|
|
|
14626
14707
|
IssuePriority,
|
|
14627
14708
|
IssueService,
|
|
14628
14709
|
IssueStatus,
|
|
14629
|
-
LicenseLevel,
|
|
14630
|
-
LicenseService,
|
|
14631
|
-
LicenseStatus,
|
|
14632
14710
|
MainService,
|
|
14633
14711
|
MapStyle,
|
|
14634
14712
|
MultiSelectField,
|
|
@@ -14646,7 +14724,6 @@ export {
|
|
|
14646
14724
|
OvermapProvider,
|
|
14647
14725
|
OvermapSDK,
|
|
14648
14726
|
PDFViewer,
|
|
14649
|
-
PaddleCheckoutEvent,
|
|
14650
14727
|
PatchField,
|
|
14651
14728
|
PatchFormProvider,
|
|
14652
14729
|
ProjectAccessLevel,
|
|
@@ -14673,18 +14750,19 @@ export {
|
|
|
14673
14750
|
YELLOW,
|
|
14674
14751
|
_setLatestRetryTime,
|
|
14675
14752
|
acceptProjectInvite,
|
|
14676
|
-
addActiveProjectFormSubmissionsCount,
|
|
14677
|
-
addActiveProjectIssuesCount,
|
|
14678
|
-
addAttachment,
|
|
14679
|
-
addAttachments,
|
|
14680
14753
|
addCategory,
|
|
14681
14754
|
addComponent,
|
|
14755
|
+
addComponentAttachment,
|
|
14756
|
+
addComponentAttachments,
|
|
14682
14757
|
addComponentType,
|
|
14758
|
+
addComponentTypeAttachment,
|
|
14759
|
+
addComponentTypeAttachments,
|
|
14683
14760
|
addComponentsInBatches,
|
|
14684
14761
|
addEmailDomain,
|
|
14685
14762
|
addFavouriteProjectId,
|
|
14686
14763
|
addIssue,
|
|
14687
|
-
|
|
14764
|
+
addIssueAttachment,
|
|
14765
|
+
addIssueAttachments,
|
|
14688
14766
|
addOrReplaceCategories,
|
|
14689
14767
|
addOrReplaceIssueComment,
|
|
14690
14768
|
addOrReplaceProjectFile,
|
|
@@ -14784,8 +14862,6 @@ export {
|
|
|
14784
14862
|
issueReducer,
|
|
14785
14863
|
issueSlice,
|
|
14786
14864
|
issueToSearchResult,
|
|
14787
|
-
licenseReducer,
|
|
14788
|
-
licenseSlice,
|
|
14789
14865
|
linkStageToForm,
|
|
14790
14866
|
literalToCoordinates,
|
|
14791
14867
|
logOnlyOnce,
|
|
@@ -14824,14 +14900,18 @@ export {
|
|
|
14824
14900
|
rehydratedReducer,
|
|
14825
14901
|
rehydratedSlice,
|
|
14826
14902
|
removeAllComponentsOfType,
|
|
14827
|
-
removeAttachment,
|
|
14828
14903
|
removeAttachmentsOfIssue,
|
|
14829
14904
|
removeCategory,
|
|
14830
14905
|
removeColor,
|
|
14831
14906
|
removeComponent,
|
|
14907
|
+
removeComponentAttachment,
|
|
14908
|
+
removeComponentAttachments,
|
|
14909
|
+
removeComponentTypeAttachment,
|
|
14910
|
+
removeComponentTypeAttachments,
|
|
14832
14911
|
removeEmailDomain,
|
|
14833
14912
|
removeFavouriteProjectId,
|
|
14834
14913
|
removeIssue,
|
|
14914
|
+
removeIssueAttachment,
|
|
14835
14915
|
removeIssueComment,
|
|
14836
14916
|
removeOrganizationAccess,
|
|
14837
14917
|
removeProjectAccess,
|
|
@@ -14853,21 +14933,21 @@ export {
|
|
|
14853
14933
|
searchIssues,
|
|
14854
14934
|
selectAccessToken,
|
|
14855
14935
|
selectActiveIssueId,
|
|
14856
|
-
selectActiveLicense,
|
|
14857
14936
|
selectActiveOrganization,
|
|
14858
14937
|
selectActiveOrganizationAccess,
|
|
14859
14938
|
selectActiveOrganizationId,
|
|
14860
|
-
selectActiveOrganizationLicenses,
|
|
14861
|
-
selectActiveOrganizationProjects,
|
|
14862
14939
|
selectActiveProject,
|
|
14863
14940
|
selectActiveProjectAccess,
|
|
14864
14941
|
selectActiveProjectFileId,
|
|
14865
14942
|
selectActiveProjectId,
|
|
14866
|
-
selectActiveStatusLicenses,
|
|
14867
14943
|
selectActiveWorkspace,
|
|
14868
14944
|
selectActiveWorkspaceId,
|
|
14869
14945
|
selectAllAttachments,
|
|
14946
|
+
selectAllComponentAttachments,
|
|
14947
|
+
selectAllComponentTypeAttachments,
|
|
14870
14948
|
selectAppearance,
|
|
14949
|
+
selectAttachmentsOfComponent,
|
|
14950
|
+
selectAttachmentsOfComponentType,
|
|
14871
14951
|
selectCategories,
|
|
14872
14952
|
selectCategoriesOfWorkspace,
|
|
14873
14953
|
selectCategory,
|
|
@@ -14879,7 +14959,9 @@ export {
|
|
|
14879
14959
|
selectCompletedStageIdsForComponent,
|
|
14880
14960
|
selectCompletedStages,
|
|
14881
14961
|
selectComponent,
|
|
14962
|
+
selectComponentAttachmentMapping,
|
|
14882
14963
|
selectComponentType,
|
|
14964
|
+
selectComponentTypeAttachmentMapping,
|
|
14883
14965
|
selectComponentTypeForm,
|
|
14884
14966
|
selectComponentTypeFromComponent,
|
|
14885
14967
|
selectComponentTypeFromComponents,
|
|
@@ -14909,7 +14991,6 @@ export {
|
|
|
14909
14991
|
selectHiddenComponentTypeIds,
|
|
14910
14992
|
selectIsFetchingInitialData,
|
|
14911
14993
|
selectIsImportingProjectFile,
|
|
14912
|
-
selectIsLoading,
|
|
14913
14994
|
selectIsLoggedIn,
|
|
14914
14995
|
selectIssue,
|
|
14915
14996
|
selectIssueAttachmentMapping,
|
|
@@ -14920,10 +15001,6 @@ export {
|
|
|
14920
15001
|
selectLatestRetryTime,
|
|
14921
15002
|
selectLatestRevisionByFormId,
|
|
14922
15003
|
selectLatestRevisionsFromComponentTypeIds,
|
|
14923
|
-
selectLicense,
|
|
14924
|
-
selectLicenseForProject,
|
|
14925
|
-
selectLicenses,
|
|
14926
|
-
selectLicensesForProjectsMapping,
|
|
14927
15004
|
selectMainWorkspace,
|
|
14928
15005
|
selectMapStyle,
|
|
14929
15006
|
selectNumberOfComponentTypesMatchingCaseInsensitiveName,
|
|
@@ -14938,7 +15015,6 @@ export {
|
|
|
14938
15015
|
selectOrganizationUsersAsMapping,
|
|
14939
15016
|
selectOrganizationUsersIds,
|
|
14940
15017
|
selectOrganizations,
|
|
14941
|
-
selectOrganizationsMapping,
|
|
14942
15018
|
selectOrganizationsWithAccess,
|
|
14943
15019
|
selectPermittedWorkspaceIds,
|
|
14944
15020
|
selectPhotoAttachmentsOfIssue,
|
|
@@ -14960,7 +15036,6 @@ export {
|
|
|
14960
15036
|
selectRevisionsForForm,
|
|
14961
15037
|
selectShowTooltips,
|
|
14962
15038
|
selectSortedEmailDomains,
|
|
14963
|
-
selectSortedOrganizationLicenses,
|
|
14964
15039
|
selectSortedOrganizationUsers,
|
|
14965
15040
|
selectSortedProjectUsers,
|
|
14966
15041
|
selectSortedProjects,
|
|
@@ -14991,9 +15066,10 @@ export {
|
|
|
14991
15066
|
setActiveProjectId,
|
|
14992
15067
|
setActiveWorkspaceId,
|
|
14993
15068
|
setAppearance,
|
|
14994
|
-
setAttachments,
|
|
14995
15069
|
setCategories,
|
|
14996
15070
|
setCenterMapToProject,
|
|
15071
|
+
setComponentAttachments,
|
|
15072
|
+
setComponentTypeAttachments,
|
|
14997
15073
|
setComponentTypes,
|
|
14998
15074
|
setComponents,
|
|
14999
15075
|
setCreateProjectType,
|
|
@@ -15004,10 +15080,9 @@ export {
|
|
|
15004
15080
|
setEnablePlacementMode,
|
|
15005
15081
|
setIsFetchingInitialData,
|
|
15006
15082
|
setIsImportingProjectFile,
|
|
15007
|
-
|
|
15083
|
+
setIssueAttachments,
|
|
15008
15084
|
setIssueComments,
|
|
15009
15085
|
setIssues,
|
|
15010
|
-
setLicenses,
|
|
15011
15086
|
setLoggedIn,
|
|
15012
15087
|
setMapStyle,
|
|
15013
15088
|
setOrganizationAccesses,
|
|
@@ -15044,10 +15119,11 @@ export {
|
|
|
15044
15119
|
unhideCategory,
|
|
15045
15120
|
unlinkStageToForm,
|
|
15046
15121
|
updateActiveOrganization,
|
|
15047
|
-
updateAttachment,
|
|
15048
15122
|
updateComponent,
|
|
15123
|
+
updateComponentAttachment,
|
|
15124
|
+
updateComponentTypeAttachment,
|
|
15049
15125
|
updateIssue,
|
|
15050
|
-
|
|
15126
|
+
updateIssueAttachment,
|
|
15051
15127
|
updateOrCreateProject,
|
|
15052
15128
|
updateOrCreateUserFormSubmission,
|
|
15053
15129
|
updateOrganizationAccess,
|