@overmap-ai/core 1.0.48-add-agent-response-rating.2 → 1.0.48-bulk-form-submission.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/components/ImageCard/ImageCard.d.ts +1 -1
- package/dist/forms/builder/hooks.d.ts +2 -1
- package/dist/forms/renderer/FormSubmissionBrowser/FormSubmissionBrowser.d.ts +5 -5
- package/dist/forms/renderer/FormSubmissionViewer/FormSubmissionViewer.d.ts +3 -3
- package/dist/overmap-core.js +1017 -532
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +1016 -531
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/sdk.d.ts +2 -1
- package/dist/sdk/services/IssueCommentService.d.ts +2 -2
- package/dist/sdk/services/IssueUpdateService.d.ts +4 -0
- package/dist/sdk/services/UserFormSubmissionService.d.ts +9 -2
- package/dist/sdk/services/index.d.ts +1 -0
- package/dist/store/slices/categorySlice.d.ts +3 -1
- package/dist/store/slices/componentSlice.d.ts +1 -0
- package/dist/store/slices/componentStageSlice.d.ts +2 -0
- package/dist/store/slices/documentSlice.d.ts +3 -1
- package/dist/store/slices/formRevisionSlice.d.ts +73 -0
- package/dist/store/slices/formSubmissionSlice.d.ts +46 -0
- package/dist/store/slices/index.d.ts +2 -0
- package/dist/store/slices/issueSlice.d.ts +24 -4
- package/dist/store/slices/projectFileSlice.d.ts +3 -1
- package/dist/store/slices/userFormSlice.d.ts +38 -63
- package/dist/store/slices/workspaceSlice.d.ts +3 -1
- package/dist/store/store.d.ts +10 -4
- package/dist/typings/models/access.d.ts +1 -1
- package/dist/typings/models/attachments.d.ts +3 -1
- package/dist/typings/models/base.d.ts +7 -0
- package/dist/typings/models/forms.d.ts +3 -6
- package/dist/typings/models/issues.d.ts +35 -1
- package/package.json +152 -152
package/dist/overmap-core.js
CHANGED
|
@@ -8,7 +8,7 @@ var _a;
|
|
|
8
8
|
import * as React from "react";
|
|
9
9
|
import React__default, { useState, useEffect, useRef, memo, useMemo, useCallback, createContext, createElement, useContext, forwardRef, Children, isValidElement, cloneElement, Fragment as Fragment$1, useLayoutEffect, useReducer, lazy, Suspense } from "react";
|
|
10
10
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
11
|
-
import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, useViewportSize, Overlay, ButtonGroup, Spinner, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, Button, ButtonList, divButtonProps,
|
|
11
|
+
import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, useViewportSize, Overlay, ButtonGroup, Spinner, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, Button, ButtonList, divButtonProps, OvermapDropdownMenu, Input, useAlertDialog } from "@overmap-ai/blocks";
|
|
12
12
|
import { DepGraph } from "dependency-graph";
|
|
13
13
|
import { offline as offline$1 } from "@redux-offline/redux-offline";
|
|
14
14
|
import offlineConfig from "@redux-offline/redux-offline/lib/defaults";
|
|
@@ -631,15 +631,15 @@ const wrapMigration = (migrator) => (state) => {
|
|
|
631
631
|
};
|
|
632
632
|
const migrations = [initialVersioning, signOut, signOut, createOutboxState];
|
|
633
633
|
const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
|
|
634
|
-
const initialState$
|
|
634
|
+
const initialState$p = {
|
|
635
635
|
accessToken: "",
|
|
636
636
|
refreshToken: "",
|
|
637
637
|
isLoggedIn: false
|
|
638
638
|
};
|
|
639
639
|
const authSlice = createSlice({
|
|
640
640
|
name: "auth",
|
|
641
|
-
initialState: initialState$
|
|
642
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
641
|
+
initialState: initialState$p,
|
|
642
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$p)),
|
|
643
643
|
reducers: {
|
|
644
644
|
setTokens: (state, action) => {
|
|
645
645
|
state.accessToken = action.payload.accessToken;
|
|
@@ -1370,7 +1370,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
|
|
|
1370
1370
|
return getLocalDateString(date);
|
|
1371
1371
|
return relative.format(days, "days");
|
|
1372
1372
|
});
|
|
1373
|
-
const initialState$
|
|
1373
|
+
const initialState$o = {
|
|
1374
1374
|
categories: {},
|
|
1375
1375
|
usedCategoryColors: [],
|
|
1376
1376
|
categoryVisibility: {
|
|
@@ -1380,8 +1380,8 @@ const initialState$m = {
|
|
|
1380
1380
|
};
|
|
1381
1381
|
const categorySlice = createSlice({
|
|
1382
1382
|
name: "categories",
|
|
1383
|
-
initialState: initialState$
|
|
1384
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1383
|
+
initialState: initialState$o,
|
|
1384
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$o)),
|
|
1385
1385
|
reducers: {
|
|
1386
1386
|
setCategories: (state, action) => {
|
|
1387
1387
|
if (!Array.isArray(action.payload))
|
|
@@ -1549,14 +1549,14 @@ function removeAttachments(state, action) {
|
|
|
1549
1549
|
delete state.attachments[attachmentId];
|
|
1550
1550
|
}
|
|
1551
1551
|
}
|
|
1552
|
-
const initialState$
|
|
1552
|
+
const initialState$n = {
|
|
1553
1553
|
components: {},
|
|
1554
1554
|
attachments: {}
|
|
1555
1555
|
};
|
|
1556
1556
|
const componentSlice = createSlice({
|
|
1557
1557
|
name: "components",
|
|
1558
|
-
initialState: initialState$
|
|
1559
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1558
|
+
initialState: initialState$n,
|
|
1559
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
|
|
1560
1560
|
reducers: {
|
|
1561
1561
|
addComponent: (state, action) => {
|
|
1562
1562
|
state.components[action.payload.offline_id] = action.payload;
|
|
@@ -1610,6 +1610,7 @@ const selectComponents = (state) => {
|
|
|
1610
1610
|
}
|
|
1611
1611
|
return prevComponents;
|
|
1612
1612
|
};
|
|
1613
|
+
const selectComponentsMapping = (state) => state.componentReducer.components;
|
|
1613
1614
|
const selectComponentsFromComponentType = (componentTypeId) => (state) => {
|
|
1614
1615
|
if (!componentTypeId)
|
|
1615
1616
|
return [];
|
|
@@ -1640,16 +1641,14 @@ const selectComponentTypeFromComponents = (state) => {
|
|
|
1640
1641
|
}
|
|
1641
1642
|
return ret;
|
|
1642
1643
|
};
|
|
1643
|
-
const selectComponentsByType = (
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
componentsOfType.push(component);
|
|
1644
|
+
const selectComponentsByType = restructureCreateSelectorWithArgs(
|
|
1645
|
+
createSelector(
|
|
1646
|
+
[selectComponents, (_state, componentTypeId) => componentTypeId],
|
|
1647
|
+
(components, componentTypeId) => {
|
|
1648
|
+
return components.filter((component) => component.component_type === componentTypeId);
|
|
1649
1649
|
}
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
};
|
|
1650
|
+
)
|
|
1651
|
+
);
|
|
1653
1652
|
const selectNumberOfComponentsOfComponentType = (componentTypeId) => (state) => {
|
|
1654
1653
|
var _a2;
|
|
1655
1654
|
if (!componentTypeId)
|
|
@@ -1710,13 +1709,13 @@ const {
|
|
|
1710
1709
|
removeAllComponentsOfType
|
|
1711
1710
|
} = componentSlice.actions;
|
|
1712
1711
|
const componentReducer = componentSlice.reducer;
|
|
1713
|
-
const initialState$
|
|
1712
|
+
const initialState$m = {
|
|
1714
1713
|
completionsByComponentId: {}
|
|
1715
1714
|
};
|
|
1716
1715
|
const componentStageCompletionSlice = createSlice({
|
|
1717
1716
|
name: "componentStageCompletions",
|
|
1718
|
-
initialState: initialState$
|
|
1719
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1717
|
+
initialState: initialState$m,
|
|
1718
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
|
|
1720
1719
|
reducers: {
|
|
1721
1720
|
addStageCompletion: (state, action) => {
|
|
1722
1721
|
let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
|
|
@@ -1767,13 +1766,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
|
|
|
1767
1766
|
return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
|
|
1768
1767
|
};
|
|
1769
1768
|
const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
|
|
1770
|
-
const initialState$
|
|
1769
|
+
const initialState$l = {
|
|
1771
1770
|
stages: {}
|
|
1772
1771
|
};
|
|
1773
1772
|
const componentStageSlice = createSlice({
|
|
1774
1773
|
name: "componentStages",
|
|
1775
|
-
initialState: initialState$
|
|
1776
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1774
|
+
initialState: initialState$l,
|
|
1775
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
|
|
1777
1776
|
reducers: {
|
|
1778
1777
|
addStages: (state, action) => {
|
|
1779
1778
|
Object.assign(state.stages, toOfflineIdRecord(action.payload));
|
|
@@ -1807,6 +1806,11 @@ const componentStageSlice = createSlice({
|
|
|
1807
1806
|
}
|
|
1808
1807
|
});
|
|
1809
1808
|
const selectStageMapping = (state) => state.componentStageReducer.stages;
|
|
1809
|
+
const selectStage = restructureCreateSelectorWithArgs(
|
|
1810
|
+
createSelector([selectStageMapping, (_state, stageId) => stageId], (stageMapping, stageId) => {
|
|
1811
|
+
return stageMapping[stageId];
|
|
1812
|
+
})
|
|
1813
|
+
);
|
|
1810
1814
|
const selectStages = createSelector(
|
|
1811
1815
|
[selectStageMapping],
|
|
1812
1816
|
(stageMapping) => {
|
|
@@ -1834,6 +1838,20 @@ const selectStagesFromComponentTypeIds = restructureCreateSelectorWithArgs(
|
|
|
1834
1838
|
}
|
|
1835
1839
|
)
|
|
1836
1840
|
);
|
|
1841
|
+
const selectComponentTypeStagesMapping = restructureCreateSelectorWithArgs(
|
|
1842
|
+
createSelector(
|
|
1843
|
+
[selectStageMapping, (_state, componentTypeId) => componentTypeId],
|
|
1844
|
+
(stagesMapping, componentTypeId) => {
|
|
1845
|
+
const componentTypeStagesMapping = {};
|
|
1846
|
+
for (const [stageId, stage] of Object.entries(stagesMapping)) {
|
|
1847
|
+
if (stage.component_type === componentTypeId) {
|
|
1848
|
+
componentTypeStagesMapping[stageId] = stage;
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
return componentTypeStagesMapping;
|
|
1852
|
+
}
|
|
1853
|
+
)
|
|
1854
|
+
);
|
|
1837
1855
|
const selectStagesFromComponentType = restructureCreateSelectorWithArgs(
|
|
1838
1856
|
createSelector(
|
|
1839
1857
|
[selectStages, (_state, componentTypeId) => componentTypeId],
|
|
@@ -1864,15 +1882,15 @@ const selectStageFormIdsFromStageIds = restructureCreateSelectorWithArgs(
|
|
|
1864
1882
|
);
|
|
1865
1883
|
const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
|
|
1866
1884
|
const componentStageReducer = componentStageSlice.reducer;
|
|
1867
|
-
const initialState$
|
|
1885
|
+
const initialState$k = {
|
|
1868
1886
|
componentTypes: {},
|
|
1869
1887
|
hiddenComponentTypeIds: {},
|
|
1870
1888
|
attachments: {}
|
|
1871
1889
|
};
|
|
1872
1890
|
const componentTypeSlice = createSlice({
|
|
1873
1891
|
name: "componentTypes",
|
|
1874
|
-
initialState: initialState$
|
|
1875
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1892
|
+
initialState: initialState$k,
|
|
1893
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
|
|
1876
1894
|
reducers: {
|
|
1877
1895
|
addComponentType: (state, action) => {
|
|
1878
1896
|
state.componentTypes[action.payload.offline_id] = action.payload;
|
|
@@ -1980,13 +1998,13 @@ const {
|
|
|
1980
1998
|
deleteComponentType
|
|
1981
1999
|
} = componentTypeSlice.actions;
|
|
1982
2000
|
const componentTypeReducer = componentTypeSlice.reducer;
|
|
1983
|
-
const initialState$
|
|
2001
|
+
const initialState$j = {
|
|
1984
2002
|
workspaces: {},
|
|
1985
2003
|
activeWorkspaceId: null
|
|
1986
2004
|
};
|
|
1987
2005
|
const workspaceSlice = createSlice({
|
|
1988
2006
|
name: "workspace",
|
|
1989
|
-
initialState: initialState$
|
|
2007
|
+
initialState: initialState$j,
|
|
1990
2008
|
// The `reducers` field lets us define reducers and generate associated actions
|
|
1991
2009
|
reducers: {
|
|
1992
2010
|
setWorkspaces: (state, action) => {
|
|
@@ -2043,10 +2061,11 @@ const selectPermittedWorkspaceIds = createSelector(
|
|
|
2043
2061
|
);
|
|
2044
2062
|
const workspaceReducer = workspaceSlice.reducer;
|
|
2045
2063
|
const maxRecentIssues = 10;
|
|
2046
|
-
const initialState$
|
|
2064
|
+
const initialState$i = {
|
|
2047
2065
|
issues: {},
|
|
2048
2066
|
attachments: {},
|
|
2049
2067
|
comments: {},
|
|
2068
|
+
updates: {},
|
|
2050
2069
|
visibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],
|
|
2051
2070
|
visibleUserIds: null,
|
|
2052
2071
|
recentIssueIds: [],
|
|
@@ -2054,9 +2073,9 @@ const initialState$g = {
|
|
|
2054
2073
|
};
|
|
2055
2074
|
const issueSlice = createSlice({
|
|
2056
2075
|
name: "issues",
|
|
2057
|
-
initialState: initialState$
|
|
2076
|
+
initialState: initialState$i,
|
|
2058
2077
|
extraReducers: (builder) => builder.addCase("RESET", (state) => {
|
|
2059
|
-
Object.assign(state, initialState$
|
|
2078
|
+
Object.assign(state, initialState$i);
|
|
2060
2079
|
}),
|
|
2061
2080
|
reducers: {
|
|
2062
2081
|
setIssues: (state, action) => {
|
|
@@ -2068,6 +2087,16 @@ const issueSlice = createSlice({
|
|
|
2068
2087
|
});
|
|
2069
2088
|
},
|
|
2070
2089
|
setIssueAttachments: setAttachments,
|
|
2090
|
+
setIssueUpdates: (state, action) => {
|
|
2091
|
+
if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
|
|
2092
|
+
throw new Error("Tried to use setIssues reducer with duplicate ID's");
|
|
2093
|
+
}
|
|
2094
|
+
const newUpdates = {};
|
|
2095
|
+
for (const update of action.payload) {
|
|
2096
|
+
newUpdates[update.offline_id] = update;
|
|
2097
|
+
}
|
|
2098
|
+
state.updates = newUpdates;
|
|
2099
|
+
},
|
|
2071
2100
|
setActiveIssueId: (state, action) => {
|
|
2072
2101
|
state.activeIssueId = action.payload;
|
|
2073
2102
|
},
|
|
@@ -2079,6 +2108,17 @@ const issueSlice = createSlice({
|
|
|
2079
2108
|
},
|
|
2080
2109
|
addIssueAttachment: addAttachment,
|
|
2081
2110
|
addIssueAttachments: addAttachments,
|
|
2111
|
+
addIssueUpdate: (state, action) => {
|
|
2112
|
+
if (action.payload.offline_id in state.updates) {
|
|
2113
|
+
throw new Error(`Tried to add duplicate issue update with offline_id: ${action.payload.offline_id}`);
|
|
2114
|
+
}
|
|
2115
|
+
state.updates[action.payload.offline_id] = action.payload;
|
|
2116
|
+
},
|
|
2117
|
+
addIssueUpdates: (state, action) => {
|
|
2118
|
+
for (const update of action.payload) {
|
|
2119
|
+
state.updates[update.offline_id] = update;
|
|
2120
|
+
}
|
|
2121
|
+
},
|
|
2082
2122
|
updateIssue: (state, action) => {
|
|
2083
2123
|
if (action.payload.offline_id in state.issues) {
|
|
2084
2124
|
state.issues[action.payload.offline_id] = {
|
|
@@ -2098,6 +2138,18 @@ const issueSlice = createSlice({
|
|
|
2098
2138
|
}
|
|
2099
2139
|
},
|
|
2100
2140
|
removeIssueAttachment: removeAttachment,
|
|
2141
|
+
removeIssueUpdate: (state, action) => {
|
|
2142
|
+
if (action.payload in state.updates) {
|
|
2143
|
+
delete state.updates[action.payload];
|
|
2144
|
+
} else {
|
|
2145
|
+
throw new Error(`Failed to remove issue update because offline_id doesn't exist: ${action.payload}`);
|
|
2146
|
+
}
|
|
2147
|
+
},
|
|
2148
|
+
removeIssueUpdates: (state, action) => {
|
|
2149
|
+
for (const updateId of action.payload) {
|
|
2150
|
+
delete state.updates[updateId];
|
|
2151
|
+
}
|
|
2152
|
+
},
|
|
2101
2153
|
removeAttachmentsOfIssue: (state, action) => {
|
|
2102
2154
|
const attachments = Object.values(state.attachments).filter((a) => a.issue === action.payload);
|
|
2103
2155
|
for (const attachment of attachments) {
|
|
@@ -2110,20 +2162,55 @@ const issueSlice = createSlice({
|
|
|
2110
2162
|
setVisibleUserIds: (state, action) => {
|
|
2111
2163
|
state.visibleUserIds = [...new Set(action.payload)];
|
|
2112
2164
|
},
|
|
2113
|
-
|
|
2165
|
+
// Comments
|
|
2166
|
+
addIssueComment: (state, action) => {
|
|
2167
|
+
if (action.payload.offline_id in state.comments) {
|
|
2168
|
+
throw new Error(
|
|
2169
|
+
`Tried to add issue comment with offline_id: ${action.payload.offline_id} that already exists`
|
|
2170
|
+
);
|
|
2171
|
+
}
|
|
2172
|
+
state.comments[action.payload.offline_id] = action.payload;
|
|
2173
|
+
},
|
|
2174
|
+
addIssueComments: (state, action) => {
|
|
2175
|
+
for (const comment of action.payload) {
|
|
2176
|
+
if (comment.offline_id in state.comments) {
|
|
2177
|
+
throw new Error(
|
|
2178
|
+
`Tried to add issue comment with offline_id: ${comment.offline_id} that already exists`
|
|
2179
|
+
);
|
|
2180
|
+
}
|
|
2181
|
+
}
|
|
2114
2182
|
for (const comment of action.payload) {
|
|
2115
2183
|
state.comments[comment.offline_id] = comment;
|
|
2116
2184
|
}
|
|
2117
2185
|
},
|
|
2186
|
+
setIssueComment: (state, action) => {
|
|
2187
|
+
state.comments[action.payload.offline_id] = action.payload;
|
|
2188
|
+
},
|
|
2189
|
+
setIssueComments: (state, action) => {
|
|
2190
|
+
const newComments = {};
|
|
2191
|
+
for (const comment of action.payload) {
|
|
2192
|
+
newComments[comment.offline_id] = comment;
|
|
2193
|
+
}
|
|
2194
|
+
state.comments = newComments;
|
|
2195
|
+
},
|
|
2118
2196
|
addOrReplaceIssueComment: (state, action) => {
|
|
2119
2197
|
state.comments[action.payload.offline_id] = action.payload;
|
|
2120
2198
|
},
|
|
2121
2199
|
removeIssueComment: (state, action) => {
|
|
2122
|
-
if (action.payload in state.comments) {
|
|
2123
|
-
delete state.comments[action.payload];
|
|
2124
|
-
} else {
|
|
2200
|
+
if (!(action.payload in state.comments)) {
|
|
2125
2201
|
throw new Error(`Failed to remove issue comment because ID doesn't exist: ${action.payload}`);
|
|
2126
2202
|
}
|
|
2203
|
+
delete state.comments[action.payload];
|
|
2204
|
+
},
|
|
2205
|
+
removeIssueComments: (state, action) => {
|
|
2206
|
+
for (const commentId of action.payload) {
|
|
2207
|
+
if (!(commentId in state.comments)) {
|
|
2208
|
+
throw new Error(`Failed to remove issue comment because ID doesn't exist: ${commentId}`);
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
for (const commentId of action.payload) {
|
|
2212
|
+
delete state.comments[commentId];
|
|
2213
|
+
}
|
|
2127
2214
|
},
|
|
2128
2215
|
cleanRecentIssues: (state) => {
|
|
2129
2216
|
state.recentIssueIds = state.recentIssueIds.filter((recentIssue) => state.issues[recentIssue.offlineId]);
|
|
@@ -2154,23 +2241,33 @@ const {
|
|
|
2154
2241
|
addIssueAttachment,
|
|
2155
2242
|
addIssueAttachments,
|
|
2156
2243
|
addIssue,
|
|
2244
|
+
addIssueUpdate,
|
|
2245
|
+
addIssueUpdates,
|
|
2157
2246
|
addOrReplaceIssueComment,
|
|
2158
2247
|
addToRecentIssues,
|
|
2159
2248
|
cleanRecentIssues,
|
|
2160
2249
|
removeIssueAttachment,
|
|
2161
2250
|
removeAttachmentsOfIssue,
|
|
2162
2251
|
removeIssue,
|
|
2163
|
-
|
|
2252
|
+
removeIssueUpdate,
|
|
2253
|
+
removeIssueUpdates,
|
|
2164
2254
|
removeRecentIssue,
|
|
2165
2255
|
resetRecentIssues,
|
|
2166
2256
|
setActiveIssueId,
|
|
2167
2257
|
setIssueAttachments,
|
|
2168
|
-
|
|
2258
|
+
setIssueUpdates,
|
|
2169
2259
|
setIssues,
|
|
2170
2260
|
setVisibleStatuses,
|
|
2171
2261
|
setVisibleUserIds,
|
|
2172
2262
|
updateIssueAttachment,
|
|
2173
|
-
updateIssue
|
|
2263
|
+
updateIssue,
|
|
2264
|
+
// Commments
|
|
2265
|
+
addIssueComment,
|
|
2266
|
+
addIssueComments,
|
|
2267
|
+
setIssueComment,
|
|
2268
|
+
setIssueComments,
|
|
2269
|
+
removeIssueComment,
|
|
2270
|
+
removeIssueComments
|
|
2174
2271
|
} = issueSlice.actions;
|
|
2175
2272
|
const selectIssueMapping = (state) => state.issueReducer.issues;
|
|
2176
2273
|
const selectRecentIssueIds = (state) => state.issueReducer.recentIssueIds;
|
|
@@ -2241,6 +2338,12 @@ const selectCommentsOfIssue = restructureCreateSelectorWithArgs(
|
|
|
2241
2338
|
return Object.values(commentMapping).filter((comment) => comment.issue === issueId);
|
|
2242
2339
|
})
|
|
2243
2340
|
);
|
|
2341
|
+
const selectIssueUpdateMapping = (state) => state.issueReducer.updates;
|
|
2342
|
+
const selectIssueUpdatesOfIssue = restructureCreateSelectorWithArgs(
|
|
2343
|
+
createSelector([selectIssueUpdateMapping, (_state, issueId) => issueId], (updates, issueId) => {
|
|
2344
|
+
return Object.values(updates).filter((update) => update.issue === issueId);
|
|
2345
|
+
})
|
|
2346
|
+
);
|
|
2244
2347
|
const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(
|
|
2245
2348
|
createSelector(
|
|
2246
2349
|
[selectIssueAttachments, (_state, issueId) => issueId],
|
|
@@ -2377,15 +2480,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
|
|
|
2377
2480
|
}
|
|
2378
2481
|
);
|
|
2379
2482
|
const issueReducer = issueSlice.reducer;
|
|
2380
|
-
const initialState$
|
|
2483
|
+
const initialState$h = {
|
|
2381
2484
|
s3Urls: {}
|
|
2382
2485
|
};
|
|
2383
2486
|
const msPerHour = 1e3 * 60 * 60;
|
|
2384
2487
|
const msPerWeek = msPerHour * 24 * 7;
|
|
2385
2488
|
const fileSlice = createSlice({
|
|
2386
2489
|
name: "file",
|
|
2387
|
-
initialState: initialState$
|
|
2388
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2490
|
+
initialState: initialState$h,
|
|
2491
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
|
|
2389
2492
|
reducers: {
|
|
2390
2493
|
setUploadUrl: (state, action) => {
|
|
2391
2494
|
const { url, fields, sha1 } = action.payload;
|
|
@@ -2412,7 +2515,7 @@ const selectUploadUrl = (sha1) => (state) => {
|
|
|
2412
2515
|
return url;
|
|
2413
2516
|
};
|
|
2414
2517
|
const fileReducer = fileSlice.reducer;
|
|
2415
|
-
const initialState$
|
|
2518
|
+
const initialState$g = {
|
|
2416
2519
|
// TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
|
|
2417
2520
|
mapStyle: MapStyle.SATELLITE,
|
|
2418
2521
|
showTooltips: false,
|
|
@@ -2420,8 +2523,8 @@ const initialState$e = {
|
|
|
2420
2523
|
};
|
|
2421
2524
|
const mapSlice = createSlice({
|
|
2422
2525
|
name: "map",
|
|
2423
|
-
initialState: initialState$
|
|
2424
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2526
|
+
initialState: initialState$g,
|
|
2527
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
|
|
2425
2528
|
reducers: {
|
|
2426
2529
|
setMapStyle: (state, action) => {
|
|
2427
2530
|
state.mapStyle = action.payload;
|
|
@@ -2449,6 +2552,16 @@ var OrganizationAccessLevel = /* @__PURE__ */ ((OrganizationAccessLevel2) => {
|
|
|
2449
2552
|
OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
|
|
2450
2553
|
return OrganizationAccessLevel2;
|
|
2451
2554
|
})(OrganizationAccessLevel || {});
|
|
2555
|
+
var IssueUpdateChange = /* @__PURE__ */ ((IssueUpdateChange2) => {
|
|
2556
|
+
IssueUpdateChange2["STATUS"] = "status";
|
|
2557
|
+
IssueUpdateChange2["PRIORITY"] = "priority";
|
|
2558
|
+
IssueUpdateChange2["CATEGORY"] = "category";
|
|
2559
|
+
IssueUpdateChange2["DESCRIPTION"] = "description";
|
|
2560
|
+
IssueUpdateChange2["TITLE"] = "title";
|
|
2561
|
+
IssueUpdateChange2["ASSIGNED_TO"] = "assigned_to";
|
|
2562
|
+
IssueUpdateChange2["DUE_DATE"] = "due_date";
|
|
2563
|
+
return IssueUpdateChange2;
|
|
2564
|
+
})(IssueUpdateChange || {});
|
|
2452
2565
|
var ProjectType = /* @__PURE__ */ ((ProjectType2) => {
|
|
2453
2566
|
ProjectType2[ProjectType2["PERSONAL"] = 0] = "PERSONAL";
|
|
2454
2567
|
ProjectType2[ProjectType2["ORGANIZATION"] = 2] = "ORGANIZATION";
|
|
@@ -2480,7 +2593,7 @@ var LicenseStatus = /* @__PURE__ */ ((LicenseStatus2) => {
|
|
|
2480
2593
|
LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
|
|
2481
2594
|
return LicenseStatus2;
|
|
2482
2595
|
})(LicenseStatus || {});
|
|
2483
|
-
const initialState$
|
|
2596
|
+
const initialState$f = {
|
|
2484
2597
|
users: {},
|
|
2485
2598
|
currentUser: {
|
|
2486
2599
|
id: 0,
|
|
@@ -2491,8 +2604,8 @@ const initialState$d = {
|
|
|
2491
2604
|
};
|
|
2492
2605
|
const userSlice = createSlice({
|
|
2493
2606
|
name: "users",
|
|
2494
|
-
initialState: initialState$
|
|
2495
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2607
|
+
initialState: initialState$f,
|
|
2608
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
|
|
2496
2609
|
reducers: {
|
|
2497
2610
|
setUsers: (state, action) => {
|
|
2498
2611
|
const usersMapping = {};
|
|
@@ -2554,13 +2667,13 @@ const selectUser = (userId) => (state) => {
|
|
|
2554
2667
|
const selectUsersAsMapping = (state) => state.userReducer.users;
|
|
2555
2668
|
const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
|
|
2556
2669
|
const userReducer = userSlice.reducer;
|
|
2557
|
-
const initialState$
|
|
2670
|
+
const initialState$e = {
|
|
2558
2671
|
organizationAccesses: {}
|
|
2559
2672
|
};
|
|
2560
2673
|
const organizationAccessSlice = createSlice({
|
|
2561
2674
|
name: "organizationAccess",
|
|
2562
|
-
initialState: initialState$
|
|
2563
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2675
|
+
initialState: initialState$e,
|
|
2676
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
|
|
2564
2677
|
reducers: {
|
|
2565
2678
|
setOrganizationAccesses: (state, action) => {
|
|
2566
2679
|
if (!Array.isArray(action.payload))
|
|
@@ -2623,13 +2736,13 @@ const selectOrganizationAccessUserMapping = (state) => {
|
|
|
2623
2736
|
return organizationAccesses;
|
|
2624
2737
|
};
|
|
2625
2738
|
const organizationAccessReducer = organizationAccessSlice.reducer;
|
|
2626
|
-
const initialState$
|
|
2739
|
+
const initialState$d = {
|
|
2627
2740
|
licenses: {}
|
|
2628
2741
|
};
|
|
2629
2742
|
const licenseSlice = createSlice({
|
|
2630
2743
|
name: "license",
|
|
2631
|
-
initialState: initialState$
|
|
2632
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2744
|
+
initialState: initialState$d,
|
|
2745
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
|
|
2633
2746
|
reducers: {
|
|
2634
2747
|
setLicenses: (state, action) => {
|
|
2635
2748
|
if (!Array.isArray(action.payload))
|
|
@@ -2674,13 +2787,13 @@ const selectLicensesForProjectsMapping = createSelector(
|
|
|
2674
2787
|
(licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
|
|
2675
2788
|
);
|
|
2676
2789
|
const licenseReducer = licenseSlice.reducer;
|
|
2677
|
-
const initialState$
|
|
2790
|
+
const initialState$c = {
|
|
2678
2791
|
projectAccesses: {}
|
|
2679
2792
|
};
|
|
2680
2793
|
const projectAccessSlice = createSlice({
|
|
2681
2794
|
name: "projectAccess",
|
|
2682
|
-
initialState: initialState$
|
|
2683
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2795
|
+
initialState: initialState$c,
|
|
2796
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
|
|
2684
2797
|
reducers: {
|
|
2685
2798
|
setProjectAccesses: (state, action) => {
|
|
2686
2799
|
if (!Array.isArray(action.payload))
|
|
@@ -2748,7 +2861,7 @@ const selectProjectAccessUserMapping = (state) => {
|
|
|
2748
2861
|
return projectAccesses;
|
|
2749
2862
|
};
|
|
2750
2863
|
const projectAccessReducer = projectAccessSlice.reducer;
|
|
2751
|
-
const initialState$
|
|
2864
|
+
const initialState$b = {
|
|
2752
2865
|
projects: {},
|
|
2753
2866
|
activeProjectId: null,
|
|
2754
2867
|
recentProjectIds: [],
|
|
@@ -2758,7 +2871,7 @@ const initialState$9 = {
|
|
|
2758
2871
|
};
|
|
2759
2872
|
const projectSlice = createSlice({
|
|
2760
2873
|
name: "projects",
|
|
2761
|
-
initialState: initialState$
|
|
2874
|
+
initialState: initialState$b,
|
|
2762
2875
|
reducers: {
|
|
2763
2876
|
setProjects: (state, action) => {
|
|
2764
2877
|
const projectsMap = {};
|
|
@@ -2945,14 +3058,14 @@ const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(
|
|
|
2945
3058
|
}
|
|
2946
3059
|
)
|
|
2947
3060
|
);
|
|
2948
|
-
const initialState$
|
|
3061
|
+
const initialState$a = {
|
|
2949
3062
|
organizations: {},
|
|
2950
3063
|
activeOrganizationId: null
|
|
2951
3064
|
};
|
|
2952
3065
|
const organizationSlice = createSlice({
|
|
2953
3066
|
name: "organizations",
|
|
2954
|
-
initialState: initialState$
|
|
2955
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3067
|
+
initialState: initialState$a,
|
|
3068
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
|
|
2956
3069
|
reducers: {
|
|
2957
3070
|
setOrganizations: (state, action) => {
|
|
2958
3071
|
for (const org of action.payload) {
|
|
@@ -3071,14 +3184,14 @@ const createOfflineAction = (request2, baseUrl) => {
|
|
|
3071
3184
|
}
|
|
3072
3185
|
};
|
|
3073
3186
|
};
|
|
3074
|
-
const initialState$
|
|
3187
|
+
const initialState$9 = {
|
|
3075
3188
|
deletedRequests: [],
|
|
3076
3189
|
latestRetryTime: 0
|
|
3077
3190
|
};
|
|
3078
3191
|
const outboxSlice = createSlice({
|
|
3079
3192
|
name: "outbox",
|
|
3080
|
-
initialState: initialState$
|
|
3081
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3193
|
+
initialState: initialState$9,
|
|
3194
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
|
|
3082
3195
|
reducers: {
|
|
3083
3196
|
// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
|
|
3084
3197
|
// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
|
|
@@ -3110,7 +3223,7 @@ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
|
|
|
3110
3223
|
const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
|
|
3111
3224
|
const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
|
|
3112
3225
|
const outboxReducer = outboxSlice.reducer;
|
|
3113
|
-
const initialState$
|
|
3226
|
+
const initialState$8 = {
|
|
3114
3227
|
projectFiles: {},
|
|
3115
3228
|
activeProjectFileId: null,
|
|
3116
3229
|
isImportingProjectFile: false,
|
|
@@ -3118,8 +3231,8 @@ const initialState$6 = {
|
|
|
3118
3231
|
};
|
|
3119
3232
|
const projectFileSlice = createSlice({
|
|
3120
3233
|
name: "projectFiles",
|
|
3121
|
-
initialState: initialState$
|
|
3122
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3234
|
+
initialState: initialState$8,
|
|
3235
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
|
|
3123
3236
|
reducers: {
|
|
3124
3237
|
addOrReplaceProjectFiles: (state, action) => {
|
|
3125
3238
|
for (let fileObj of action.payload) {
|
|
@@ -3220,12 +3333,12 @@ const selectProjectFiles = createSelector(
|
|
|
3220
3333
|
const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
|
|
3221
3334
|
const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
|
|
3222
3335
|
const projectFileReducer = projectFileSlice.reducer;
|
|
3223
|
-
const initialState$
|
|
3336
|
+
const initialState$7 = {
|
|
3224
3337
|
isRehydrated: false
|
|
3225
3338
|
};
|
|
3226
3339
|
const rehydratedSlice = createSlice({
|
|
3227
3340
|
name: "rehydrated",
|
|
3228
|
-
initialState: initialState$
|
|
3341
|
+
initialState: initialState$7,
|
|
3229
3342
|
// The `reducers` field lets us define reducers and generate associated actions
|
|
3230
3343
|
reducers: {
|
|
3231
3344
|
setRehydrated: (state, action) => {
|
|
@@ -3235,7 +3348,7 @@ const rehydratedSlice = createSlice({
|
|
|
3235
3348
|
});
|
|
3236
3349
|
const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
|
|
3237
3350
|
const rehydratedReducer = rehydratedSlice.reducer;
|
|
3238
|
-
const initialState$
|
|
3351
|
+
const initialState$6 = {
|
|
3239
3352
|
useIssueTemplate: false,
|
|
3240
3353
|
placementMode: false,
|
|
3241
3354
|
enableClustering: false,
|
|
@@ -3252,8 +3365,8 @@ const initialState$4 = {
|
|
|
3252
3365
|
};
|
|
3253
3366
|
const settingSlice = createSlice({
|
|
3254
3367
|
name: "settings",
|
|
3255
|
-
initialState: initialState$
|
|
3256
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3368
|
+
initialState: initialState$6,
|
|
3369
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
|
|
3257
3370
|
reducers: {
|
|
3258
3371
|
setEnableDuplicateIssues: (state, action) => {
|
|
3259
3372
|
state.useIssueTemplate = action.payload;
|
|
@@ -3299,146 +3412,248 @@ const selectAppearance = (state) => state.settingReducer.appearance;
|
|
|
3299
3412
|
const settingReducer = settingSlice.reducer;
|
|
3300
3413
|
const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
|
|
3301
3414
|
const selectIsLoading = (state) => state.settingReducer.isLoading;
|
|
3302
|
-
const
|
|
3303
|
-
function
|
|
3415
|
+
const LATEST_FORM_REVISION_CACHE = {};
|
|
3416
|
+
function considerCachingFormRevision(formRevision, formId2, preferPending = false) {
|
|
3304
3417
|
var _a2;
|
|
3305
|
-
if (!
|
|
3418
|
+
if (!formRevision) {
|
|
3306
3419
|
if (!formId2) {
|
|
3307
|
-
throw new Error("If revision is null, formId is required.");
|
|
3420
|
+
throw new Error("If form revision is null, formId is required.");
|
|
3308
3421
|
}
|
|
3309
|
-
const
|
|
3310
|
-
if (
|
|
3422
|
+
const currentLatestFormRevision = getLatestFormRevisionFromCache(formId2);
|
|
3423
|
+
if (currentLatestFormRevision)
|
|
3311
3424
|
return;
|
|
3312
|
-
|
|
3425
|
+
LATEST_FORM_REVISION_CACHE[formId2] = null;
|
|
3313
3426
|
return;
|
|
3314
3427
|
}
|
|
3315
|
-
if (
|
|
3428
|
+
if (formRevision.revision === "Pending") {
|
|
3316
3429
|
if (preferPending) {
|
|
3317
|
-
|
|
3430
|
+
LATEST_FORM_REVISION_CACHE[formRevision.form] = formRevision;
|
|
3318
3431
|
}
|
|
3319
3432
|
return;
|
|
3320
3433
|
}
|
|
3321
|
-
const
|
|
3322
|
-
if (
|
|
3323
|
-
|
|
3434
|
+
const cachedFormRevision = (_a2 = LATEST_FORM_REVISION_CACHE[formRevision.form]) == null ? void 0 : _a2.revision;
|
|
3435
|
+
if (formRevision.revision > (typeof cachedFormRevision === "number" ? cachedFormRevision : -1)) {
|
|
3436
|
+
LATEST_FORM_REVISION_CACHE[formRevision.form] = formRevision;
|
|
3324
3437
|
}
|
|
3325
3438
|
}
|
|
3326
|
-
function
|
|
3327
|
-
return
|
|
3439
|
+
function getLatestFormRevisionFromCache(formId2) {
|
|
3440
|
+
return LATEST_FORM_REVISION_CACHE[formId2];
|
|
3328
3441
|
}
|
|
3329
|
-
const initialState$
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
submissions: {},
|
|
3333
|
-
submissionAttachments: {},
|
|
3334
|
-
revisionAttachments: {}
|
|
3442
|
+
const initialState$5 = {
|
|
3443
|
+
formRevisions: {},
|
|
3444
|
+
attachments: {}
|
|
3335
3445
|
};
|
|
3336
|
-
const
|
|
3337
|
-
name: "
|
|
3338
|
-
initialState: initialState$
|
|
3339
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3446
|
+
const formRevisionsSlice = createSlice({
|
|
3447
|
+
name: "formRevisions",
|
|
3448
|
+
initialState: initialState$5,
|
|
3449
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$5)),
|
|
3340
3450
|
reducers: {
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
action.payload.
|
|
3344
|
-
|
|
3345
|
-
});
|
|
3346
|
-
},
|
|
3347
|
-
addUserForm: (state, action) => {
|
|
3348
|
-
state.userForms[action.payload.offline_id] = action.payload;
|
|
3349
|
-
},
|
|
3350
|
-
addUserForms: (state, action) => {
|
|
3351
|
-
action.payload.forEach((userForm) => {
|
|
3352
|
-
state.userForms[userForm.offline_id] = userForm;
|
|
3353
|
-
});
|
|
3354
|
-
},
|
|
3355
|
-
addUserFormRevisions: (state, action) => {
|
|
3356
|
-
action.payload.forEach((userFormRevision) => {
|
|
3357
|
-
state.revisions[userFormRevision.offline_id] = userFormRevision;
|
|
3358
|
-
considerCachingRevision(userFormRevision);
|
|
3359
|
-
});
|
|
3451
|
+
// revision related actions
|
|
3452
|
+
setFormRevision: (state, action) => {
|
|
3453
|
+
state.formRevisions[action.payload.offline_id] = action.payload;
|
|
3454
|
+
considerCachingFormRevision(action.payload);
|
|
3360
3455
|
},
|
|
3361
|
-
|
|
3362
|
-
state.
|
|
3363
|
-
|
|
3456
|
+
setFormRevisions: (state, action) => {
|
|
3457
|
+
state.formRevisions = {};
|
|
3458
|
+
for (const revision of action.payload) {
|
|
3459
|
+
state.formRevisions[revision.offline_id] = revision;
|
|
3460
|
+
considerCachingFormRevision(revision);
|
|
3461
|
+
}
|
|
3364
3462
|
},
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3463
|
+
addFormRevision: (state, action) => {
|
|
3464
|
+
if (state.formRevisions[action.payload.offline_id] !== void 0) {
|
|
3465
|
+
throw new Error(`Revision with offline_id ${action.payload.offline_id} already exists`);
|
|
3466
|
+
}
|
|
3467
|
+
state.formRevisions[action.payload.offline_id] = action.payload;
|
|
3468
|
+
considerCachingFormRevision(action.payload);
|
|
3368
3469
|
},
|
|
3369
|
-
|
|
3470
|
+
// TODO: @Audiopolis / Magnus - do we want to standardize using PayloadAction?
|
|
3471
|
+
addFormRevisions: (state, action) => {
|
|
3370
3472
|
for (const userFormRevision of action.payload) {
|
|
3371
|
-
|
|
3372
|
-
|
|
3473
|
+
if (state.formRevisions[userFormRevision.offline_id] !== void 0) {
|
|
3474
|
+
throw new Error(`Revision with offline_id ${userFormRevision.offline_id} already exists`);
|
|
3475
|
+
}
|
|
3476
|
+
}
|
|
3477
|
+
for (const userFormRevision of action.payload) {
|
|
3478
|
+
state.formRevisions[userFormRevision.offline_id] = userFormRevision;
|
|
3479
|
+
considerCachingFormRevision(userFormRevision);
|
|
3373
3480
|
}
|
|
3374
3481
|
},
|
|
3375
|
-
|
|
3376
|
-
|
|
3377
|
-
|
|
3378
|
-
|
|
3379
|
-
const submissionId = action.payload.submission;
|
|
3380
|
-
const submissionAttachments = state.submissionAttachments[submissionId];
|
|
3381
|
-
if (submissionAttachments) {
|
|
3382
|
-
submissionAttachments.push(action.payload);
|
|
3383
|
-
} else {
|
|
3384
|
-
state.submissionAttachments[submissionId] = [action.payload];
|
|
3482
|
+
// UserFormRevisions do not get updated
|
|
3483
|
+
deleteFormRevision: (state, action) => {
|
|
3484
|
+
if (state.formRevisions[action.payload] === void 0) {
|
|
3485
|
+
throw new Error(`Revision with offline_id ${action.payload} does not exist`);
|
|
3385
3486
|
}
|
|
3487
|
+
delete state.formRevisions[action.payload];
|
|
3488
|
+
delete LATEST_FORM_REVISION_CACHE[action.payload];
|
|
3386
3489
|
},
|
|
3387
|
-
|
|
3388
|
-
const
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3392
|
-
}
|
|
3393
|
-
|
|
3490
|
+
deleteFormRevisions: (state, action) => {
|
|
3491
|
+
for (const offlineId of action.payload) {
|
|
3492
|
+
if (state.formRevisions[offlineId] === void 0) {
|
|
3493
|
+
throw new Error(`Revision with offline_id ${offlineId} does not exist`);
|
|
3494
|
+
}
|
|
3495
|
+
}
|
|
3496
|
+
for (const offlineId of action.payload) {
|
|
3497
|
+
delete state.formRevisions[offlineId];
|
|
3498
|
+
delete LATEST_FORM_REVISION_CACHE[offlineId];
|
|
3394
3499
|
}
|
|
3395
3500
|
},
|
|
3396
|
-
|
|
3397
|
-
|
|
3501
|
+
// attachment related actions
|
|
3502
|
+
setFormRevisionAttachments: (state, action) => {
|
|
3503
|
+
state.attachments = {};
|
|
3398
3504
|
for (const attachment of action.payload) {
|
|
3399
|
-
|
|
3400
|
-
const submissionAttachments = state.submissionAttachments[submissionId];
|
|
3401
|
-
if (submissionAttachments) {
|
|
3402
|
-
submissionAttachments.push(attachment);
|
|
3403
|
-
} else {
|
|
3404
|
-
state.submissionAttachments[submissionId] = [attachment];
|
|
3405
|
-
}
|
|
3505
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3406
3506
|
}
|
|
3407
3507
|
},
|
|
3408
|
-
|
|
3409
|
-
state.
|
|
3508
|
+
addFormRevisionAttachment: (state, action) => {
|
|
3509
|
+
if (state.attachments[action.payload.offline_id] !== void 0) {
|
|
3510
|
+
throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
|
|
3511
|
+
}
|
|
3512
|
+
state.attachments[action.payload.offline_id] = action.payload;
|
|
3513
|
+
},
|
|
3514
|
+
addFormRevisionAttachments: (state, action) => {
|
|
3410
3515
|
for (const attachment of action.payload) {
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
if (revisionAttachments) {
|
|
3414
|
-
revisionAttachments.push(attachment);
|
|
3415
|
-
} else {
|
|
3416
|
-
state.revisionAttachments[revisionId] = [attachment];
|
|
3516
|
+
if (state.attachments[attachment.offline_id] !== void 0) {
|
|
3517
|
+
throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
|
|
3417
3518
|
}
|
|
3418
3519
|
}
|
|
3520
|
+
for (const attachment of action.payload) {
|
|
3521
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3522
|
+
}
|
|
3419
3523
|
},
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
deleteUserFormSubmissions: (state, action) => {
|
|
3424
|
-
for (const userFormSubmission of action.payload) {
|
|
3425
|
-
delete state.submissions[userFormSubmission.offline_id];
|
|
3524
|
+
deleteFormRevisionAttachment: (state, action) => {
|
|
3525
|
+
if (state.attachments[action.payload] === void 0) {
|
|
3526
|
+
throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
|
|
3426
3527
|
}
|
|
3528
|
+
delete state.attachments[action.payload];
|
|
3427
3529
|
},
|
|
3428
|
-
|
|
3429
|
-
for (const
|
|
3430
|
-
state.
|
|
3530
|
+
deleteFormRevisionAttachments: (state, action) => {
|
|
3531
|
+
for (const offlineId of action.payload) {
|
|
3532
|
+
if (state.attachments[offlineId] === void 0) {
|
|
3533
|
+
throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
|
|
3534
|
+
}
|
|
3535
|
+
}
|
|
3536
|
+
for (const offlineId of action.payload) {
|
|
3537
|
+
delete state.attachments[offlineId];
|
|
3538
|
+
}
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3541
|
+
});
|
|
3542
|
+
const {
|
|
3543
|
+
setFormRevision,
|
|
3544
|
+
setFormRevisions,
|
|
3545
|
+
addFormRevision,
|
|
3546
|
+
addFormRevisions,
|
|
3547
|
+
deleteFormRevision,
|
|
3548
|
+
deleteFormRevisions,
|
|
3549
|
+
setFormRevisionAttachments,
|
|
3550
|
+
addFormRevisionAttachment,
|
|
3551
|
+
addFormRevisionAttachments,
|
|
3552
|
+
deleteFormRevisionAttachment,
|
|
3553
|
+
deleteFormRevisionAttachments
|
|
3554
|
+
} = formRevisionsSlice.actions;
|
|
3555
|
+
const selectFormRevisionMapping = (state) => state.formRevisionReducer.formRevisions;
|
|
3556
|
+
const selectFormRevisions = createSelector(
|
|
3557
|
+
[selectFormRevisionMapping],
|
|
3558
|
+
(formRevisions) => Object.values(formRevisions)
|
|
3559
|
+
);
|
|
3560
|
+
const selectUserFormRevision = (formRevisionId) => (state) => {
|
|
3561
|
+
return state.formRevisionReducer.formRevisions[formRevisionId];
|
|
3562
|
+
};
|
|
3563
|
+
const _selectLatestFormRevision = (formRevisions, formId2) => {
|
|
3564
|
+
let ret = null;
|
|
3565
|
+
for (const candidate of Object.values(formRevisions)) {
|
|
3566
|
+
if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
|
|
3567
|
+
ret = candidate;
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
if (!ret) {
|
|
3571
|
+
throw new Error("No form revision found for form " + formId2);
|
|
3572
|
+
}
|
|
3573
|
+
return ret;
|
|
3574
|
+
};
|
|
3575
|
+
const selectLatestFormRevisionOfForm = restructureCreateSelectorWithArgs(
|
|
3576
|
+
createSelector([selectFormRevisionMapping, (_state, formId2) => formId2], (revisions, formId2) => {
|
|
3577
|
+
if (!formId2) {
|
|
3578
|
+
throw new Error("formId is required");
|
|
3579
|
+
}
|
|
3580
|
+
return _selectLatestFormRevision(revisions, formId2);
|
|
3581
|
+
})
|
|
3582
|
+
);
|
|
3583
|
+
const selectFormRevisionsOfForm = restructureCreateSelectorWithArgs(
|
|
3584
|
+
createSelector([selectFormRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
|
|
3585
|
+
return revisions.filter((revision) => {
|
|
3586
|
+
return revision.form === formId2;
|
|
3587
|
+
});
|
|
3588
|
+
})
|
|
3589
|
+
);
|
|
3590
|
+
const selectLatestFormRevisionsOfComponentTypes = restructureCreateSelectorWithArgs(
|
|
3591
|
+
createSelector(
|
|
3592
|
+
[
|
|
3593
|
+
selectUserFormMapping,
|
|
3594
|
+
selectFormRevisionMapping,
|
|
3595
|
+
(_state, componentTypeIds) => componentTypeIds
|
|
3596
|
+
],
|
|
3597
|
+
(userForms, revisions, componentTypeIds) => {
|
|
3598
|
+
const componentTypeIdsSet = new Set(componentTypeIds);
|
|
3599
|
+
const ret = {};
|
|
3600
|
+
for (const form of Object.values(userForms)) {
|
|
3601
|
+
if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
|
|
3602
|
+
ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
|
|
3603
|
+
}
|
|
3431
3604
|
}
|
|
3605
|
+
return ret;
|
|
3606
|
+
}
|
|
3607
|
+
)
|
|
3608
|
+
);
|
|
3609
|
+
const selectLatestFormRevisionByForm = createSelector([selectFormRevisionMapping], (revisions) => {
|
|
3610
|
+
const latestRevisions = {};
|
|
3611
|
+
for (const revision of Object.values(revisions)) {
|
|
3612
|
+
const formId2 = revision.form;
|
|
3613
|
+
const currentLatestRevision = latestRevisions[formId2];
|
|
3614
|
+
if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
|
|
3615
|
+
latestRevisions[formId2] = revision;
|
|
3616
|
+
}
|
|
3617
|
+
}
|
|
3618
|
+
return latestRevisions;
|
|
3619
|
+
});
|
|
3620
|
+
const selectUserFormRevisionAttachmentsMapping = (state) => {
|
|
3621
|
+
return state.formRevisionReducer.attachments;
|
|
3622
|
+
};
|
|
3623
|
+
const selectAttachmentsOfFormRevision = restructureCreateSelectorWithArgs(
|
|
3624
|
+
createSelector(
|
|
3625
|
+
[selectUserFormRevisionAttachmentsMapping, (_state, revisionId) => revisionId],
|
|
3626
|
+
(attachments, revisionId) => {
|
|
3627
|
+
return Object.values(attachments).filter((attachment) => attachment.revision === revisionId);
|
|
3628
|
+
}
|
|
3629
|
+
)
|
|
3630
|
+
);
|
|
3631
|
+
const formRevisionReducer = formRevisionsSlice.reducer;
|
|
3632
|
+
const initialState$4 = {
|
|
3633
|
+
forms: {}
|
|
3634
|
+
};
|
|
3635
|
+
const userFormSlice = createSlice({
|
|
3636
|
+
name: "userForms",
|
|
3637
|
+
initialState: initialState$4,
|
|
3638
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
|
|
3639
|
+
reducers: {
|
|
3640
|
+
setForms: (state, action) => {
|
|
3641
|
+
state.forms = {};
|
|
3642
|
+
action.payload.forEach((userForm) => {
|
|
3643
|
+
state.forms[userForm.offline_id] = userForm;
|
|
3644
|
+
});
|
|
3645
|
+
},
|
|
3646
|
+
addForm: (state, action) => {
|
|
3647
|
+
state.forms[action.payload.offline_id] = action.payload;
|
|
3432
3648
|
},
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
state.submissions[submission.offline_id] = submission;
|
|
3649
|
+
addForms: (state, action) => {
|
|
3650
|
+
action.payload.forEach((userForm) => {
|
|
3651
|
+
state.forms[userForm.offline_id] = userForm;
|
|
3437
3652
|
});
|
|
3438
3653
|
},
|
|
3439
3654
|
favoriteForm: (state, action) => {
|
|
3440
3655
|
const { formId: formId2 } = action.payload;
|
|
3441
|
-
const form = state.
|
|
3656
|
+
const form = state.forms[formId2];
|
|
3442
3657
|
if (!form) {
|
|
3443
3658
|
throw new Error("No form exists with the id " + formId2);
|
|
3444
3659
|
}
|
|
@@ -3446,48 +3661,23 @@ const userFormSlice = createSlice({
|
|
|
3446
3661
|
},
|
|
3447
3662
|
unfavoriteForm: (state, action) => {
|
|
3448
3663
|
const { formId: formId2 } = action.payload;
|
|
3449
|
-
const form = state.
|
|
3664
|
+
const form = state.forms[formId2];
|
|
3450
3665
|
if (!form) {
|
|
3451
3666
|
throw new Error("No form exists with the id " + formId2);
|
|
3452
3667
|
}
|
|
3453
3668
|
form.favorite = false;
|
|
3454
3669
|
},
|
|
3455
|
-
|
|
3456
|
-
delete state.
|
|
3670
|
+
deleteForm: (state, action) => {
|
|
3671
|
+
delete state.forms[action.payload];
|
|
3457
3672
|
}
|
|
3458
3673
|
}
|
|
3459
3674
|
});
|
|
3460
|
-
const {
|
|
3461
|
-
addUserForm,
|
|
3462
|
-
addUserForms,
|
|
3463
|
-
addUserFormRevisions,
|
|
3464
|
-
updateOrCreateUserFormSubmission,
|
|
3465
|
-
addUserFormSubmissions,
|
|
3466
|
-
deleteUserFormSubmission,
|
|
3467
|
-
deleteUserFormSubmissions,
|
|
3468
|
-
favoriteForm,
|
|
3469
|
-
unfavoriteForm,
|
|
3470
|
-
deleteUserForm,
|
|
3471
|
-
deleteUserFormRevision,
|
|
3472
|
-
deleteUserFormRevisions,
|
|
3473
|
-
setUserFormSubmissions,
|
|
3474
|
-
addUserFormRevision,
|
|
3475
|
-
addUserFormSubmissionAttachment,
|
|
3476
|
-
addUserFormRevisionAttachment,
|
|
3477
|
-
setUserFormSubmissionAttachments,
|
|
3478
|
-
setUserFormRevisionAttachments
|
|
3479
|
-
} = userFormSlice.actions;
|
|
3480
|
-
const selectSubmissionAttachments = (submissionId) => (state) => {
|
|
3481
|
-
return state.userFormReducer.submissionAttachments[submissionId] || [];
|
|
3482
|
-
};
|
|
3483
|
-
const selectRevisionAttachments = (revisionId) => (state) => {
|
|
3484
|
-
return state.userFormReducer.revisionAttachments[revisionId] || [];
|
|
3485
|
-
};
|
|
3675
|
+
const { setForms, addForm, addForms, favoriteForm, unfavoriteForm, deleteForm } = userFormSlice.actions;
|
|
3486
3676
|
const selectFilteredUserForms = restructureCreateSelectorWithArgs(
|
|
3487
3677
|
createSelector(
|
|
3488
3678
|
[
|
|
3489
|
-
(state) => state.userFormReducer.
|
|
3490
|
-
(state) => state.
|
|
3679
|
+
(state) => state.userFormReducer.forms,
|
|
3680
|
+
(state) => state.formRevisionReducer.formRevisions,
|
|
3491
3681
|
(_state, search) => search
|
|
3492
3682
|
],
|
|
3493
3683
|
(userForms, revisions, search) => {
|
|
@@ -3510,71 +3700,188 @@ const selectFilteredUserForms = restructureCreateSelectorWithArgs(
|
|
|
3510
3700
|
regularMatches.push({ ...userForm, latestRevision });
|
|
3511
3701
|
}
|
|
3512
3702
|
}
|
|
3513
|
-
if (favoriteMatches.length >= maxResults) {
|
|
3514
|
-
break;
|
|
3703
|
+
if (favoriteMatches.length >= maxResults) {
|
|
3704
|
+
break;
|
|
3705
|
+
}
|
|
3706
|
+
}
|
|
3707
|
+
const maxRegularMatches = maxResults - favoriteMatches.length;
|
|
3708
|
+
return [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)];
|
|
3709
|
+
},
|
|
3710
|
+
// as the argument is an object, we check the first level of properties for equality
|
|
3711
|
+
{ memoizeOptions: { equalityCheck: shallowEqual$1 } }
|
|
3712
|
+
)
|
|
3713
|
+
);
|
|
3714
|
+
const selectUserForm = (formId2) => (state) => {
|
|
3715
|
+
return state.userFormReducer.forms[formId2];
|
|
3716
|
+
};
|
|
3717
|
+
const selectUserFormMapping = (state) => {
|
|
3718
|
+
return state.userFormReducer.forms;
|
|
3719
|
+
};
|
|
3720
|
+
const selectComponentTypeForm = restructureCreateSelectorWithArgs(
|
|
3721
|
+
createSelector(
|
|
3722
|
+
[selectUserFormMapping, (_state, componentTypeId) => componentTypeId],
|
|
3723
|
+
(userForms, componentTypeId) => {
|
|
3724
|
+
return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
|
|
3725
|
+
}
|
|
3726
|
+
)
|
|
3727
|
+
);
|
|
3728
|
+
const selectNumberOfUserForms = createSelector([selectUserFormMapping], (userForms) => {
|
|
3729
|
+
return Object.keys(userForms).length;
|
|
3730
|
+
});
|
|
3731
|
+
const selectNumberOfGeneralUserForms = createSelector([selectUserFormMapping], (userForms) => {
|
|
3732
|
+
return Object.values(userForms).filter((form) => !form.component_type).length;
|
|
3733
|
+
});
|
|
3734
|
+
const userFormReducer = userFormSlice.reducer;
|
|
3735
|
+
const initialState$3 = {
|
|
3736
|
+
formSubmissions: {},
|
|
3737
|
+
attachments: {}
|
|
3738
|
+
};
|
|
3739
|
+
const formSubmissionSlice = createSlice({
|
|
3740
|
+
name: "formSubmissions",
|
|
3741
|
+
initialState: initialState$3,
|
|
3742
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
|
|
3743
|
+
reducers: {
|
|
3744
|
+
setFormSubmission: (state, action) => {
|
|
3745
|
+
state.formSubmissions[action.payload.offline_id] = action.payload;
|
|
3746
|
+
},
|
|
3747
|
+
setFormSubmissions: (state, action) => {
|
|
3748
|
+
state.formSubmissions = {};
|
|
3749
|
+
for (const submission of action.payload) {
|
|
3750
|
+
state.formSubmissions[submission.offline_id] = submission;
|
|
3751
|
+
}
|
|
3752
|
+
},
|
|
3753
|
+
addFormSubmission: (state, action) => {
|
|
3754
|
+
if (state.formSubmissions[action.payload.offline_id] !== void 0) {
|
|
3755
|
+
throw new Error(`Submission with offline_id ${action.payload.offline_id} already exists`);
|
|
3756
|
+
}
|
|
3757
|
+
state.formSubmissions[action.payload.offline_id] = action.payload;
|
|
3758
|
+
},
|
|
3759
|
+
addFormSubmissions: (state, action) => {
|
|
3760
|
+
for (const submission of action.payload) {
|
|
3761
|
+
if (state.formSubmissions[submission.offline_id] !== void 0) {
|
|
3762
|
+
throw new Error(`Submission with offline_id ${submission.offline_id} already exists`);
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
for (const submission of action.payload) {
|
|
3766
|
+
state.formSubmissions[submission.offline_id] = submission;
|
|
3767
|
+
}
|
|
3768
|
+
},
|
|
3769
|
+
updateFormSubmission: (state, action) => {
|
|
3770
|
+
if (state.formSubmissions[action.payload.offline_id] === void 0) {
|
|
3771
|
+
throw new Error(`Submission with offline_id ${action.payload.offline_id} does not exist`);
|
|
3772
|
+
}
|
|
3773
|
+
state.formSubmissions[action.payload.offline_id] = action.payload;
|
|
3774
|
+
},
|
|
3775
|
+
updateFormSubmissions: (state, action) => {
|
|
3776
|
+
for (const submission of action.payload) {
|
|
3777
|
+
if (state.formSubmissions[submission.offline_id] === void 0) {
|
|
3778
|
+
throw new Error(`Submission with offline_id ${submission.offline_id} does not exist`);
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
for (const submission of action.payload) {
|
|
3782
|
+
state.formSubmissions[submission.offline_id] = submission;
|
|
3783
|
+
}
|
|
3784
|
+
},
|
|
3785
|
+
deleteFormSubmission: (state, action) => {
|
|
3786
|
+
if (state.formSubmissions[action.payload] === void 0) {
|
|
3787
|
+
throw new Error(`Submission with offline_id ${action.payload} does not exist`);
|
|
3788
|
+
}
|
|
3789
|
+
delete state.formSubmissions[action.payload];
|
|
3790
|
+
},
|
|
3791
|
+
deleteFormSubmissions: (state, action) => {
|
|
3792
|
+
for (const offlineId of action.payload) {
|
|
3793
|
+
if (state.formSubmissions[offlineId] === void 0) {
|
|
3794
|
+
throw new Error(`Submission with offline_id ${offlineId} does not exist`);
|
|
3795
|
+
}
|
|
3796
|
+
delete state.formSubmissions[offlineId];
|
|
3797
|
+
}
|
|
3798
|
+
for (const offlineId of action.payload) {
|
|
3799
|
+
delete state.formSubmissions[offlineId];
|
|
3800
|
+
}
|
|
3801
|
+
},
|
|
3802
|
+
// Attachments
|
|
3803
|
+
addFormSubmissionAttachment: (state, action) => {
|
|
3804
|
+
if (state.attachments[action.payload.offline_id] !== void 0) {
|
|
3805
|
+
throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
|
|
3806
|
+
}
|
|
3807
|
+
state.attachments[action.payload.offline_id] = action.payload;
|
|
3808
|
+
},
|
|
3809
|
+
addFormSubmissionAttachments: (state, action) => {
|
|
3810
|
+
for (const attachment of action.payload) {
|
|
3811
|
+
if (state.attachments[attachment.offline_id] !== void 0) {
|
|
3812
|
+
throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
|
|
3515
3813
|
}
|
|
3516
3814
|
}
|
|
3517
|
-
const
|
|
3518
|
-
|
|
3815
|
+
for (const attachment of action.payload) {
|
|
3816
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3817
|
+
}
|
|
3519
3818
|
},
|
|
3520
|
-
//
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
)
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
}
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
|
|
3819
|
+
// We only need a multi set for attachments because they are not updated, only added and deleted
|
|
3820
|
+
setFormSubmissionAttachments: (state, action) => {
|
|
3821
|
+
state.attachments = {};
|
|
3822
|
+
for (const attachment of action.payload) {
|
|
3823
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3824
|
+
}
|
|
3825
|
+
},
|
|
3826
|
+
// The delete actions for UserFormSubmissionAttachments are not used in the app, but are included for completeness
|
|
3827
|
+
// Could be used if editing a submission is ever supported, will be applicable for supporting tip tap content in submissions
|
|
3828
|
+
deleteFormSubmissionAttachment: (state, action) => {
|
|
3829
|
+
if (state.attachments[action.payload] === void 0) {
|
|
3830
|
+
throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
|
|
3831
|
+
}
|
|
3832
|
+
delete state.attachments[action.payload];
|
|
3833
|
+
},
|
|
3834
|
+
deleteFormSubmissionAttachments: (state, action) => {
|
|
3835
|
+
for (const offlineId of action.payload) {
|
|
3836
|
+
if (state.attachments[offlineId] === void 0) {
|
|
3837
|
+
throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
|
|
3838
|
+
}
|
|
3839
|
+
delete state.attachments[offlineId];
|
|
3840
|
+
}
|
|
3532
3841
|
}
|
|
3533
3842
|
}
|
|
3534
|
-
|
|
3535
|
-
|
|
3843
|
+
});
|
|
3844
|
+
const {
|
|
3845
|
+
setFormSubmission,
|
|
3846
|
+
setFormSubmissions,
|
|
3847
|
+
addFormSubmission,
|
|
3848
|
+
addFormSubmissions,
|
|
3849
|
+
updateFormSubmission,
|
|
3850
|
+
updateFormSubmissions,
|
|
3851
|
+
deleteFormSubmission,
|
|
3852
|
+
deleteFormSubmissions,
|
|
3853
|
+
addFormSubmissionAttachment,
|
|
3854
|
+
addFormSubmissionAttachments,
|
|
3855
|
+
setFormSubmissionAttachments,
|
|
3856
|
+
deleteFormSubmissionAttachment,
|
|
3857
|
+
deleteFormSubmissionAttachments
|
|
3858
|
+
} = formSubmissionSlice.actions;
|
|
3859
|
+
const selectFormSubmissionsMapping = (state) => {
|
|
3860
|
+
return state.formSubmissionReducer.formSubmissions;
|
|
3861
|
+
};
|
|
3862
|
+
const selectFormSubmissions = createSelector(
|
|
3863
|
+
[selectFormSubmissionsMapping],
|
|
3864
|
+
(submissions) => {
|
|
3865
|
+
return Object.values(submissions);
|
|
3536
3866
|
}
|
|
3537
|
-
return ret;
|
|
3538
|
-
};
|
|
3539
|
-
const selectLatestFormRevision = restructureCreateSelectorWithArgs(
|
|
3540
|
-
createSelector(
|
|
3541
|
-
[(state) => state.userFormReducer.revisions, (_state, formId2) => formId2],
|
|
3542
|
-
(revisions, formId2) => {
|
|
3543
|
-
if (!formId2) {
|
|
3544
|
-
throw new Error("formId is required");
|
|
3545
|
-
}
|
|
3546
|
-
return _selectLatestFormRevision(revisions, formId2);
|
|
3547
|
-
}
|
|
3548
|
-
)
|
|
3549
3867
|
);
|
|
3550
|
-
const
|
|
3551
|
-
return state.
|
|
3552
|
-
};
|
|
3553
|
-
const
|
|
3554
|
-
const selectSubmissions = createSelector([selectSubmissionMapping], (submissions) => Object.values(submissions));
|
|
3555
|
-
const selectRevisionMapping = (state) => state.userFormReducer.revisions;
|
|
3556
|
-
const selectRevisions = createSelector([selectRevisionMapping], (revisions) => Object.values(revisions));
|
|
3557
|
-
const selectRevisionsForForm = restructureCreateSelectorWithArgs(
|
|
3558
|
-
createSelector([selectRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
|
|
3559
|
-
return revisions.filter((revision) => {
|
|
3560
|
-
return revision.form === formId2;
|
|
3561
|
-
});
|
|
3562
|
-
})
|
|
3563
|
-
);
|
|
3564
|
-
const selectSubmissionsForForm = restructureCreateSelectorWithArgs(
|
|
3868
|
+
const selectFormSubmission = (submissionId) => (state) => {
|
|
3869
|
+
return state.formSubmissionReducer.formSubmissions[submissionId];
|
|
3870
|
+
};
|
|
3871
|
+
const selectFormSubmissionsOfForm = restructureCreateSelectorWithArgs(
|
|
3565
3872
|
createSelector(
|
|
3566
|
-
[
|
|
3873
|
+
[selectFormSubmissions, selectFormRevisionMapping, (_state, formId2) => formId2],
|
|
3567
3874
|
(submissions, revisionMapping, formId2) => {
|
|
3568
|
-
return
|
|
3875
|
+
return submissions.filter((submission) => {
|
|
3569
3876
|
const revision = revisionMapping[submission.form_revision];
|
|
3570
3877
|
return (revision == null ? void 0 : revision.form) === formId2;
|
|
3571
3878
|
});
|
|
3572
3879
|
}
|
|
3573
3880
|
)
|
|
3574
3881
|
);
|
|
3575
|
-
const
|
|
3882
|
+
const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(
|
|
3576
3883
|
createSelector(
|
|
3577
|
-
[
|
|
3884
|
+
[selectFormSubmissions, (_state, issueId) => issueId],
|
|
3578
3885
|
(submissions, issueId) => {
|
|
3579
3886
|
return Object.values(submissions).filter((submission) => {
|
|
3580
3887
|
return submission.issue === issueId;
|
|
@@ -3582,9 +3889,9 @@ const selectSubmissionsForIssue = restructureCreateSelectorWithArgs(
|
|
|
3582
3889
|
}
|
|
3583
3890
|
)
|
|
3584
3891
|
);
|
|
3585
|
-
const
|
|
3892
|
+
const selectFormSubmissionsOfComponent = restructureCreateSelectorWithArgs(
|
|
3586
3893
|
createSelector(
|
|
3587
|
-
[
|
|
3894
|
+
[selectFormSubmissions, (_state, componentId) => componentId],
|
|
3588
3895
|
(submissions, componentId) => {
|
|
3589
3896
|
return submissions.filter((submission) => {
|
|
3590
3897
|
return submission.component === componentId;
|
|
@@ -3592,54 +3899,35 @@ const selectSubmissionsForComponent = restructureCreateSelectorWithArgs(
|
|
|
3592
3899
|
}
|
|
3593
3900
|
)
|
|
3594
3901
|
);
|
|
3595
|
-
const
|
|
3596
|
-
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
|
|
3902
|
+
const selectFormSubmissionsByComponents = createSelector(
|
|
3903
|
+
[selectFormSubmissionsMapping, selectComponentsMapping],
|
|
3904
|
+
(submissions, components) => {
|
|
3905
|
+
var _a2;
|
|
3906
|
+
const componentSubmissionMapping = {};
|
|
3907
|
+
for (const componentId in components) {
|
|
3908
|
+
componentSubmissionMapping[componentId] = [];
|
|
3603
3909
|
}
|
|
3604
|
-
|
|
3910
|
+
for (const submissionId in submissions) {
|
|
3911
|
+
const submission = submissions[submissionId];
|
|
3912
|
+
if (submission.component) {
|
|
3913
|
+
(_a2 = componentSubmissionMapping[submission.component]) == null ? void 0 : _a2.push(submission);
|
|
3914
|
+
}
|
|
3915
|
+
}
|
|
3916
|
+
return componentSubmissionMapping;
|
|
3917
|
+
}
|
|
3605
3918
|
);
|
|
3606
|
-
const
|
|
3919
|
+
const selectFormSubmissionAttachmentsMapping = (state) => {
|
|
3920
|
+
return state.formSubmissionReducer.attachments;
|
|
3921
|
+
};
|
|
3922
|
+
const selectAttachmentsOfFormSubmission = restructureCreateSelectorWithArgs(
|
|
3607
3923
|
createSelector(
|
|
3608
|
-
[
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
(_state, componentTypeIds) => componentTypeIds
|
|
3612
|
-
],
|
|
3613
|
-
(userForms, revisions, componentTypeIds) => {
|
|
3614
|
-
const componentTypeIdsSet = new Set(componentTypeIds);
|
|
3615
|
-
const ret = {};
|
|
3616
|
-
for (const form of Object.values(userForms)) {
|
|
3617
|
-
if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
|
|
3618
|
-
ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
|
|
3619
|
-
}
|
|
3620
|
-
}
|
|
3621
|
-
return ret;
|
|
3924
|
+
[selectFormSubmissionAttachmentsMapping, (_state, submissionId) => submissionId],
|
|
3925
|
+
(attachmentsMapping, submissionId) => {
|
|
3926
|
+
return Object.values(attachmentsMapping).filter((attachment) => attachment.submission === submissionId);
|
|
3622
3927
|
}
|
|
3623
3928
|
)
|
|
3624
3929
|
);
|
|
3625
|
-
const
|
|
3626
|
-
const latestRevisions = {};
|
|
3627
|
-
for (const revision of Object.values(revisions)) {
|
|
3628
|
-
const formId2 = revision.form;
|
|
3629
|
-
const currentLatestRevision = latestRevisions[formId2];
|
|
3630
|
-
if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
|
|
3631
|
-
latestRevisions[formId2] = revision;
|
|
3632
|
-
}
|
|
3633
|
-
}
|
|
3634
|
-
return latestRevisions;
|
|
3635
|
-
});
|
|
3636
|
-
const selectNumberOfUserForms = createSelector([selectUserFormMapping], (userForms) => {
|
|
3637
|
-
return Object.keys(userForms).length;
|
|
3638
|
-
});
|
|
3639
|
-
const selectNumberOfGeneralUserForms = createSelector([selectUserFormMapping], (userForms) => {
|
|
3640
|
-
return Object.values(userForms).filter((form) => !form.component_type).length;
|
|
3641
|
-
});
|
|
3642
|
-
const userFormReducer = userFormSlice.reducer;
|
|
3930
|
+
const formSubmissionReducer = formSubmissionSlice.reducer;
|
|
3643
3931
|
const initialState$2 = {
|
|
3644
3932
|
emailDomains: {}
|
|
3645
3933
|
};
|
|
@@ -3886,6 +4174,8 @@ const overmapReducers = {
|
|
|
3886
4174
|
rehydratedReducer,
|
|
3887
4175
|
settingReducer,
|
|
3888
4176
|
userFormReducer,
|
|
4177
|
+
formRevisionReducer,
|
|
4178
|
+
formSubmissionReducer,
|
|
3889
4179
|
userReducer,
|
|
3890
4180
|
workspaceReducer,
|
|
3891
4181
|
emailDomainsReducer,
|
|
@@ -3938,7 +4228,7 @@ function handleWorkspaceRemoval(draft, action) {
|
|
|
3938
4228
|
throw new Error(`Failed to update index_workspace of issue ${issue.offline_id} to main workspace`);
|
|
3939
4229
|
}
|
|
3940
4230
|
}
|
|
3941
|
-
const indexedForms = Object.values(draft.userFormReducer.
|
|
4231
|
+
const indexedForms = Object.values(draft.userFormReducer.forms).filter(
|
|
3942
4232
|
(form) => form.index_workspace === workspaceId
|
|
3943
4233
|
);
|
|
3944
4234
|
for (const form of indexedForms) {
|
|
@@ -4437,7 +4727,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4437
4727
|
}
|
|
4438
4728
|
// Attachments aren't models, so we use the OptimisticGenericResult type instead
|
|
4439
4729
|
async addIssueAttachment(attachmentPayload) {
|
|
4440
|
-
const {
|
|
4730
|
+
const { issue, file_sha1, offline_id } = attachmentPayload;
|
|
4441
4731
|
if (!attachmentPayload.file.objectURL) {
|
|
4442
4732
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4443
4733
|
}
|
|
@@ -4445,7 +4735,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4445
4735
|
...attachmentPayload,
|
|
4446
4736
|
file: attachmentPayload.file.objectURL,
|
|
4447
4737
|
file_name: attachmentPayload.file.name,
|
|
4448
|
-
file_type: attachmentPayload.file.type
|
|
4738
|
+
file_type: attachmentPayload.file.type,
|
|
4739
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4740
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4449
4741
|
};
|
|
4450
4742
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4451
4743
|
this.client.store.dispatch(addIssueAttachment(offlineAttachment));
|
|
@@ -4457,10 +4749,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4457
4749
|
blocks: [offline_id, issue],
|
|
4458
4750
|
blockers: [file_sha1],
|
|
4459
4751
|
payload: {
|
|
4460
|
-
|
|
4461
|
-
issue,
|
|
4462
|
-
description: description2 ?? "",
|
|
4463
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4752
|
+
...offlineAttachment,
|
|
4464
4753
|
...fileProps
|
|
4465
4754
|
}
|
|
4466
4755
|
});
|
|
@@ -4471,7 +4760,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4471
4760
|
return [offlineAttachment, promise];
|
|
4472
4761
|
}
|
|
4473
4762
|
async addComponentAttachment(attachmentPayload) {
|
|
4474
|
-
const {
|
|
4763
|
+
const { component, file_sha1, offline_id } = attachmentPayload;
|
|
4475
4764
|
if (!attachmentPayload.file.objectURL) {
|
|
4476
4765
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4477
4766
|
}
|
|
@@ -4479,7 +4768,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4479
4768
|
...attachmentPayload,
|
|
4480
4769
|
file: attachmentPayload.file.objectURL,
|
|
4481
4770
|
file_name: attachmentPayload.file.name,
|
|
4482
|
-
file_type: attachmentPayload.file.type
|
|
4771
|
+
file_type: attachmentPayload.file.type,
|
|
4772
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4773
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4483
4774
|
};
|
|
4484
4775
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4485
4776
|
this.client.store.dispatch(addComponentAttachment(offlineAttachment));
|
|
@@ -4491,10 +4782,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4491
4782
|
blocks: [offline_id, component],
|
|
4492
4783
|
blockers: [file_sha1],
|
|
4493
4784
|
payload: {
|
|
4494
|
-
|
|
4495
|
-
component,
|
|
4496
|
-
description: description2 ?? "",
|
|
4497
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4785
|
+
...offlineAttachment,
|
|
4498
4786
|
...fileProps
|
|
4499
4787
|
}
|
|
4500
4788
|
});
|
|
@@ -4505,7 +4793,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4505
4793
|
return [offlineAttachment, promise];
|
|
4506
4794
|
}
|
|
4507
4795
|
async addComponentTypeAttachment(attachmentPayload) {
|
|
4508
|
-
const {
|
|
4796
|
+
const { component_type, file_sha1, offline_id } = attachmentPayload;
|
|
4509
4797
|
if (!attachmentPayload.file.objectURL) {
|
|
4510
4798
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4511
4799
|
}
|
|
@@ -4513,7 +4801,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4513
4801
|
...attachmentPayload,
|
|
4514
4802
|
file: attachmentPayload.file.objectURL,
|
|
4515
4803
|
file_name: attachmentPayload.file.name,
|
|
4516
|
-
file_type: attachmentPayload.file.type
|
|
4804
|
+
file_type: attachmentPayload.file.type,
|
|
4805
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4806
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4517
4807
|
};
|
|
4518
4808
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4519
4809
|
this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
|
|
@@ -4525,10 +4815,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4525
4815
|
blocks: [offline_id, component_type],
|
|
4526
4816
|
blockers: [file_sha1],
|
|
4527
4817
|
payload: {
|
|
4528
|
-
|
|
4529
|
-
component_type,
|
|
4530
|
-
description: description2 ?? "",
|
|
4531
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4818
|
+
...offlineAttachment,
|
|
4532
4819
|
...fileProps
|
|
4533
4820
|
}
|
|
4534
4821
|
});
|
|
@@ -4547,7 +4834,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4547
4834
|
...attachmentPayload,
|
|
4548
4835
|
file: attachmentPayload.file.objectURL,
|
|
4549
4836
|
file_name: attachmentPayload.file.name,
|
|
4550
|
-
file_type: attachmentPayload.file.type
|
|
4837
|
+
file_type: attachmentPayload.file.type,
|
|
4838
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4839
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4551
4840
|
};
|
|
4552
4841
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4553
4842
|
this.client.store.dispatch(addProjectAttachment(offlineAttachment));
|
|
@@ -4587,7 +4876,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4587
4876
|
file_name: file2.name,
|
|
4588
4877
|
file_type: file2.type,
|
|
4589
4878
|
issue: issueId,
|
|
4590
|
-
file_sha1: hash
|
|
4879
|
+
file_sha1: hash,
|
|
4880
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4881
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4591
4882
|
});
|
|
4592
4883
|
return this.addIssueAttachment(attachment);
|
|
4593
4884
|
};
|
|
@@ -4606,7 +4897,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4606
4897
|
file_name: file2.name,
|
|
4607
4898
|
file_type: file2.type,
|
|
4608
4899
|
component: componentId,
|
|
4609
|
-
file_sha1: hash
|
|
4900
|
+
file_sha1: hash,
|
|
4901
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4902
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4610
4903
|
});
|
|
4611
4904
|
return this.addComponentAttachment(attachment);
|
|
4612
4905
|
};
|
|
@@ -4625,7 +4918,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4625
4918
|
file_name: file2.name,
|
|
4626
4919
|
file_type: file2.type,
|
|
4627
4920
|
component_type: componentTypeId,
|
|
4628
|
-
file_sha1: hash
|
|
4921
|
+
file_sha1: hash,
|
|
4922
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4923
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4629
4924
|
});
|
|
4630
4925
|
return this.addComponentTypeAttachment(attachment);
|
|
4631
4926
|
};
|
|
@@ -4644,7 +4939,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4644
4939
|
file_name: file2.name,
|
|
4645
4940
|
file_type: file2.type,
|
|
4646
4941
|
project: projectId,
|
|
4647
|
-
file_sha1: hash
|
|
4942
|
+
file_sha1: hash,
|
|
4943
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4944
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4648
4945
|
});
|
|
4649
4946
|
return this.addProjectAttachment(attachment);
|
|
4650
4947
|
};
|
|
@@ -5721,49 +6018,35 @@ class ComponentTypeService extends BaseApiService {
|
|
|
5721
6018
|
}
|
|
5722
6019
|
}
|
|
5723
6020
|
class IssueCommentService extends BaseApiService {
|
|
6021
|
+
// Omit author and submitted_at since these will always be set internally
|
|
5724
6022
|
add(comment) {
|
|
5725
|
-
const offlinePayload = offline(comment);
|
|
5726
|
-
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5727
6023
|
const { store } = this.client;
|
|
5728
|
-
const offlineComment = {
|
|
5729
|
-
...
|
|
6024
|
+
const offlineComment = offline({
|
|
6025
|
+
...comment,
|
|
5730
6026
|
author: store.getState().userReducer.currentUser.id,
|
|
5731
|
-
|
|
5732
|
-
};
|
|
5733
|
-
store.dispatch(
|
|
6027
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6028
|
+
});
|
|
6029
|
+
store.dispatch(addIssueComment(offlineComment));
|
|
5734
6030
|
const promise = this.enqueueRequest({
|
|
5735
6031
|
description: `${truncate(comment.content, 80)}`,
|
|
5736
6032
|
method: HttpMethod.POST,
|
|
5737
6033
|
url: `/issues/${comment.issue}/comment/`,
|
|
5738
|
-
payload:
|
|
6034
|
+
payload: offlineComment,
|
|
5739
6035
|
blockers: [comment.issue],
|
|
5740
|
-
blocks: [
|
|
6036
|
+
blocks: [offlineComment.offline_id]
|
|
6037
|
+
});
|
|
6038
|
+
promise.catch(() => {
|
|
6039
|
+
store.dispatch(removeIssueComment(offlineComment.offline_id));
|
|
5741
6040
|
});
|
|
5742
6041
|
return [offlineComment, promise];
|
|
5743
6042
|
}
|
|
5744
|
-
|
|
6043
|
+
update(comment) {
|
|
5745
6044
|
const { store } = this.client;
|
|
5746
|
-
const
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
// TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
|
|
5750
|
-
url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
|
|
5751
|
-
blockers: [],
|
|
5752
|
-
blocks: []
|
|
5753
|
-
});
|
|
5754
|
-
let filteredResult = result.filter(onlyUniqueOfflineIds);
|
|
5755
|
-
filteredResult = filteredResult.map((comment) => {
|
|
5756
|
-
return { ...comment };
|
|
5757
|
-
});
|
|
5758
|
-
if (result.length !== filteredResult.length) {
|
|
5759
|
-
console.error(
|
|
5760
|
-
`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
|
|
5761
|
-
);
|
|
6045
|
+
const commentToUpdate = store.getState().issueReducer.comments[comment.offline_id];
|
|
6046
|
+
if (!commentToUpdate) {
|
|
6047
|
+
throw new Error(`Comment with offline_id ${comment.offline_id} not found in store`);
|
|
5762
6048
|
}
|
|
5763
|
-
store.dispatch(
|
|
5764
|
-
}
|
|
5765
|
-
update(comment) {
|
|
5766
|
-
this.client.store.dispatch(addOrReplaceIssueComment(comment));
|
|
6049
|
+
store.dispatch(setIssueComment(comment));
|
|
5767
6050
|
const promise = this.enqueueRequest({
|
|
5768
6051
|
description: `Edit comment: ${truncate(comment.content, 80)}`,
|
|
5769
6052
|
method: HttpMethod.PATCH,
|
|
@@ -5772,17 +6055,62 @@ class IssueCommentService extends BaseApiService {
|
|
|
5772
6055
|
blockers: [comment.issue],
|
|
5773
6056
|
blocks: [comment.offline_id]
|
|
5774
6057
|
});
|
|
6058
|
+
promise.catch(() => {
|
|
6059
|
+
store.dispatch(setIssueComment(commentToUpdate));
|
|
6060
|
+
});
|
|
5775
6061
|
return [comment, promise];
|
|
5776
6062
|
}
|
|
5777
6063
|
remove(offline_id) {
|
|
6064
|
+
const commentToRemove = this.client.store.getState().issueReducer.comments[offline_id];
|
|
6065
|
+
if (!commentToRemove) {
|
|
6066
|
+
throw new Error(`Comment with offline_id ${offline_id} not found in store`);
|
|
6067
|
+
}
|
|
5778
6068
|
this.client.store.dispatch(removeIssueComment(offline_id));
|
|
5779
|
-
|
|
6069
|
+
const promise = this.enqueueRequest({
|
|
5780
6070
|
description: "Delete comment",
|
|
5781
6071
|
method: HttpMethod.DELETE,
|
|
5782
6072
|
url: `/issues/comments/${offline_id}/`,
|
|
5783
6073
|
blockers: [offline_id],
|
|
5784
6074
|
blocks: []
|
|
5785
6075
|
});
|
|
6076
|
+
promise.catch(() => {
|
|
6077
|
+
this.client.store.dispatch(addIssueComment(commentToRemove));
|
|
6078
|
+
});
|
|
6079
|
+
return promise;
|
|
6080
|
+
}
|
|
6081
|
+
async refreshStore() {
|
|
6082
|
+
const { store } = this.client;
|
|
6083
|
+
const result = await this.enqueueRequest({
|
|
6084
|
+
description: "Get comments",
|
|
6085
|
+
method: HttpMethod.GET,
|
|
6086
|
+
// TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
|
|
6087
|
+
url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
|
|
6088
|
+
blockers: [],
|
|
6089
|
+
blocks: []
|
|
6090
|
+
});
|
|
6091
|
+
store.dispatch(setIssueComments(result));
|
|
6092
|
+
}
|
|
6093
|
+
}
|
|
6094
|
+
class IssueUpdateService extends BaseApiService {
|
|
6095
|
+
async refreshStore() {
|
|
6096
|
+
const { store } = this.client;
|
|
6097
|
+
const result = await this.enqueueRequest({
|
|
6098
|
+
description: "Get issue updates",
|
|
6099
|
+
method: HttpMethod.GET,
|
|
6100
|
+
url: `/projects/${store.getState().projectReducer.activeProjectId}/issues/updates/`,
|
|
6101
|
+
blockers: [],
|
|
6102
|
+
blocks: []
|
|
6103
|
+
});
|
|
6104
|
+
let filteredResult = result.filter(onlyUniqueOfflineIds);
|
|
6105
|
+
filteredResult = filteredResult.map((comment) => {
|
|
6106
|
+
return { ...comment };
|
|
6107
|
+
});
|
|
6108
|
+
if (result.length !== filteredResult.length) {
|
|
6109
|
+
console.error(
|
|
6110
|
+
`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
|
|
6111
|
+
);
|
|
6112
|
+
}
|
|
6113
|
+
store.dispatch(setIssueUpdates(filteredResult));
|
|
5786
6114
|
}
|
|
5787
6115
|
}
|
|
5788
6116
|
class IssueService extends BaseApiService {
|
|
@@ -5863,7 +6191,83 @@ class IssueService extends BaseApiService {
|
|
|
5863
6191
|
return [offlineIssues, promise];
|
|
5864
6192
|
}
|
|
5865
6193
|
update(issue) {
|
|
6194
|
+
const state = this.client.store.getState();
|
|
6195
|
+
const issueToBeUpdated = state.issueReducer.issues[issue.offline_id];
|
|
6196
|
+
if (!issueToBeUpdated) {
|
|
6197
|
+
throw new Error(
|
|
6198
|
+
`Attempting to update an issue with offline_id ${issue.offline_id} that doesn't exist in the store`
|
|
6199
|
+
);
|
|
6200
|
+
}
|
|
5866
6201
|
this.client.store.dispatch(updateIssue(issue));
|
|
6202
|
+
const changes = {};
|
|
6203
|
+
for (const issueUpdateChange of [
|
|
6204
|
+
IssueUpdateChange.TITLE,
|
|
6205
|
+
IssueUpdateChange.DESCRIPTION,
|
|
6206
|
+
IssueUpdateChange.STATUS,
|
|
6207
|
+
IssueUpdateChange.CATEGORY,
|
|
6208
|
+
IssueUpdateChange.PRIORITY,
|
|
6209
|
+
IssueUpdateChange.ASSIGNED_TO,
|
|
6210
|
+
IssueUpdateChange.DUE_DATE
|
|
6211
|
+
]) {
|
|
6212
|
+
if (issueUpdateChange in issue && issue[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {
|
|
6213
|
+
switch (issueUpdateChange) {
|
|
6214
|
+
case "category": {
|
|
6215
|
+
let categoryOrNull = null;
|
|
6216
|
+
const categoryIdOrNull = issue[issueUpdateChange];
|
|
6217
|
+
if (categoryIdOrNull) {
|
|
6218
|
+
categoryOrNull = state.categoryReducer.categories[categoryIdOrNull] ?? null;
|
|
6219
|
+
if (!categoryOrNull)
|
|
6220
|
+
throw new Error(
|
|
6221
|
+
`Trying to update issue category to ${categoryIdOrNull} which does not exist in store`
|
|
6222
|
+
);
|
|
6223
|
+
}
|
|
6224
|
+
changes[issueUpdateChange] = categoryOrNull ? {
|
|
6225
|
+
name: categoryOrNull.name,
|
|
6226
|
+
color: categoryOrNull.color,
|
|
6227
|
+
offline_id: categoryOrNull.offline_id
|
|
6228
|
+
} : null;
|
|
6229
|
+
break;
|
|
6230
|
+
}
|
|
6231
|
+
case "assigned_to": {
|
|
6232
|
+
let userOrNull = null;
|
|
6233
|
+
const userIdOrNull = issue[issueUpdateChange];
|
|
6234
|
+
if (userIdOrNull) {
|
|
6235
|
+
userOrNull = state.userReducer.users[userIdOrNull] ?? null;
|
|
6236
|
+
if (!userOrNull)
|
|
6237
|
+
throw new Error(
|
|
6238
|
+
`Trying to update issue assigned_to to ${userIdOrNull} which does not exist in store`
|
|
6239
|
+
);
|
|
6240
|
+
}
|
|
6241
|
+
changes[issueUpdateChange] = userOrNull ? {
|
|
6242
|
+
full_name: userOrNull.username,
|
|
6243
|
+
id: userOrNull.id
|
|
6244
|
+
} : null;
|
|
6245
|
+
break;
|
|
6246
|
+
}
|
|
6247
|
+
case "description":
|
|
6248
|
+
changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
|
|
6249
|
+
break;
|
|
6250
|
+
case "title":
|
|
6251
|
+
changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
|
|
6252
|
+
break;
|
|
6253
|
+
case "priority":
|
|
6254
|
+
changes[issueUpdateChange] = issue[issueUpdateChange];
|
|
6255
|
+
break;
|
|
6256
|
+
case "status":
|
|
6257
|
+
changes[issueUpdateChange] = issue[issueUpdateChange];
|
|
6258
|
+
break;
|
|
6259
|
+
case "due_date":
|
|
6260
|
+
changes[issueUpdateChange] = issue[issueUpdateChange] ? issue[issueUpdateChange] : null;
|
|
6261
|
+
}
|
|
6262
|
+
}
|
|
6263
|
+
}
|
|
6264
|
+
const offlineIssueUpdate = offline({
|
|
6265
|
+
created_by: state.userReducer.currentUser.id,
|
|
6266
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6267
|
+
issue: issueToBeUpdated.offline_id,
|
|
6268
|
+
changes
|
|
6269
|
+
});
|
|
6270
|
+
this.client.store.dispatch(addIssueUpdate(offlineIssueUpdate));
|
|
5867
6271
|
const promise = this.enqueueRequest({
|
|
5868
6272
|
description: "Edit issue",
|
|
5869
6273
|
method: HttpMethod.PATCH,
|
|
@@ -5872,23 +6276,30 @@ class IssueService extends BaseApiService {
|
|
|
5872
6276
|
blockers: [issue.offline_id],
|
|
5873
6277
|
blocks: [issue.offline_id]
|
|
5874
6278
|
});
|
|
6279
|
+
promise.catch(() => {
|
|
6280
|
+
this.client.store.dispatch(updateIssue(issueToBeUpdated));
|
|
6281
|
+
this.client.store.dispatch(removeIssueUpdate(offlineIssueUpdate.offline_id));
|
|
6282
|
+
});
|
|
5875
6283
|
const fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id];
|
|
5876
6284
|
return [fullIssue, promise];
|
|
5877
6285
|
}
|
|
5878
6286
|
async remove(id) {
|
|
5879
6287
|
const { store } = this.client;
|
|
5880
6288
|
const state = store.getState();
|
|
6289
|
+
const dispatch = store.dispatch;
|
|
5881
6290
|
const backup = state.issueReducer.issues[id];
|
|
5882
6291
|
if (!backup) {
|
|
5883
6292
|
throw new Error(`No issue with id ${id} found in the store`);
|
|
5884
6293
|
}
|
|
5885
6294
|
const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue === id);
|
|
5886
6295
|
const attachmentsOfIssue = selectAttachmentsOfIssue(id)(state);
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
6296
|
+
const updatesOfIssue = selectIssueUpdatesOfIssue(id)(state);
|
|
6297
|
+
dispatch(removeIssue(id));
|
|
6298
|
+
dispatch(addActiveProjectIssuesCount(-1));
|
|
6299
|
+
if (attachmentsOfIssue.length > 0)
|
|
6300
|
+
dispatch(removeAttachmentsOfIssue(id));
|
|
6301
|
+
if (updatesOfIssue.length > 0)
|
|
6302
|
+
dispatch(removeIssueUpdates(updatesOfIssue.map(({ offline_id }) => offline_id)));
|
|
5892
6303
|
try {
|
|
5893
6304
|
return await this.enqueueRequest({
|
|
5894
6305
|
description: "Delete issue",
|
|
@@ -5898,9 +6309,10 @@ class IssueService extends BaseApiService {
|
|
|
5898
6309
|
blocks: []
|
|
5899
6310
|
});
|
|
5900
6311
|
} catch (e) {
|
|
5901
|
-
|
|
5902
|
-
|
|
5903
|
-
|
|
6312
|
+
dispatch(addIssue(backup));
|
|
6313
|
+
dispatch(addIssueAttachments(attachments));
|
|
6314
|
+
dispatch(addIssueUpdates(updatesOfIssue));
|
|
6315
|
+
dispatch(addActiveProjectIssuesCount(1));
|
|
5904
6316
|
throw e;
|
|
5905
6317
|
}
|
|
5906
6318
|
}
|
|
@@ -6082,6 +6494,7 @@ class MainService extends BaseApiService {
|
|
|
6082
6494
|
store.dispatch(setProjectAttachments(project_attachments));
|
|
6083
6495
|
});
|
|
6084
6496
|
void this.client.documents.refreshStore();
|
|
6497
|
+
void this.client.issueUpdates.refreshStore();
|
|
6085
6498
|
}
|
|
6086
6499
|
store.dispatch(setIsFetchingInitialData(false));
|
|
6087
6500
|
if (overwrite) {
|
|
@@ -6446,7 +6859,7 @@ class UserFormService extends BaseApiService {
|
|
|
6446
6859
|
...revisionAttachmentPayload,
|
|
6447
6860
|
file: URL.createObjectURL(image)
|
|
6448
6861
|
};
|
|
6449
|
-
store.dispatch(
|
|
6862
|
+
store.dispatch(addFormRevisionAttachment(offlinePayload));
|
|
6450
6863
|
return attach;
|
|
6451
6864
|
});
|
|
6452
6865
|
});
|
|
@@ -6480,8 +6893,8 @@ class UserFormService extends BaseApiService {
|
|
|
6480
6893
|
revision: 0
|
|
6481
6894
|
};
|
|
6482
6895
|
const { store } = this.client;
|
|
6483
|
-
store.dispatch(
|
|
6484
|
-
store.dispatch(
|
|
6896
|
+
store.dispatch(addForm(retForm));
|
|
6897
|
+
store.dispatch(addFormRevision(retRevision));
|
|
6485
6898
|
const formPromise = this.enqueueRequest({
|
|
6486
6899
|
description: "Create form",
|
|
6487
6900
|
method: HttpMethod.POST,
|
|
@@ -6499,8 +6912,8 @@ class UserFormService extends BaseApiService {
|
|
|
6499
6912
|
});
|
|
6500
6913
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevisionPayload.offline_id);
|
|
6501
6914
|
void formPromise.catch((e) => {
|
|
6502
|
-
store.dispatch(
|
|
6503
|
-
store.dispatch(
|
|
6915
|
+
store.dispatch(deleteForm(retForm.offline_id));
|
|
6916
|
+
store.dispatch(deleteFormRevision(retRevision.offline_id));
|
|
6504
6917
|
throw e;
|
|
6505
6918
|
});
|
|
6506
6919
|
const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
|
|
@@ -6542,7 +6955,7 @@ class UserFormService extends BaseApiService {
|
|
|
6542
6955
|
revision: "Pending",
|
|
6543
6956
|
form: formId2
|
|
6544
6957
|
};
|
|
6545
|
-
store.dispatch(
|
|
6958
|
+
store.dispatch(addFormRevision(fullRevision));
|
|
6546
6959
|
const promise = this.enqueueRequest({
|
|
6547
6960
|
description: "Create form revision",
|
|
6548
6961
|
method: HttpMethod.PATCH,
|
|
@@ -6556,9 +6969,9 @@ class UserFormService extends BaseApiService {
|
|
|
6556
6969
|
});
|
|
6557
6970
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
|
|
6558
6971
|
void promise.then((result) => {
|
|
6559
|
-
store.dispatch(
|
|
6972
|
+
store.dispatch(setFormRevision(result));
|
|
6560
6973
|
}).catch(() => {
|
|
6561
|
-
store.dispatch(
|
|
6974
|
+
store.dispatch(deleteFormRevision(fullRevision.offline_id));
|
|
6562
6975
|
});
|
|
6563
6976
|
const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
|
|
6564
6977
|
return [fullRevision, settledPromise];
|
|
@@ -6604,15 +7017,15 @@ class UserFormService extends BaseApiService {
|
|
|
6604
7017
|
if (!userForm) {
|
|
6605
7018
|
throw new Error("Expected userForm to exist");
|
|
6606
7019
|
}
|
|
6607
|
-
const userFormSubmissions =
|
|
7020
|
+
const userFormSubmissions = selectFormSubmissionsOfForm(formId2)(state);
|
|
6608
7021
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6609
|
-
store.dispatch(
|
|
7022
|
+
store.dispatch(deleteFormSubmissions(userFormSubmissions.map(({ offline_id }) => offline_id)));
|
|
6610
7023
|
}
|
|
6611
|
-
const userFormRevisions =
|
|
7024
|
+
const userFormRevisions = selectFormRevisionsOfForm(formId2)(state);
|
|
6612
7025
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6613
|
-
store.dispatch(
|
|
7026
|
+
store.dispatch(deleteFormRevisions(userFormRevisions.map(({ offline_id }) => offline_id)));
|
|
6614
7027
|
}
|
|
6615
|
-
store.dispatch(
|
|
7028
|
+
store.dispatch(deleteForm(formId2));
|
|
6616
7029
|
try {
|
|
6617
7030
|
return await this.enqueueRequest({
|
|
6618
7031
|
description: "Delete form",
|
|
@@ -6622,12 +7035,12 @@ class UserFormService extends BaseApiService {
|
|
|
6622
7035
|
blocks: []
|
|
6623
7036
|
});
|
|
6624
7037
|
} catch (e) {
|
|
6625
|
-
store.dispatch(
|
|
7038
|
+
store.dispatch(addForm(userForm));
|
|
6626
7039
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6627
|
-
store.dispatch(
|
|
7040
|
+
store.dispatch(addFormRevisions(userFormRevisions));
|
|
6628
7041
|
}
|
|
6629
7042
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6630
|
-
store.dispatch(
|
|
7043
|
+
store.dispatch(addFormSubmissions(userFormSubmissions));
|
|
6631
7044
|
}
|
|
6632
7045
|
throw e;
|
|
6633
7046
|
}
|
|
@@ -6641,16 +7054,15 @@ class UserFormService extends BaseApiService {
|
|
|
6641
7054
|
blockers: [],
|
|
6642
7055
|
blocks: []
|
|
6643
7056
|
});
|
|
6644
|
-
store.dispatch(
|
|
6645
|
-
store.dispatch(
|
|
6646
|
-
store.dispatch(
|
|
7057
|
+
store.dispatch(setForms(Object.values(result.forms)));
|
|
7058
|
+
store.dispatch(setFormRevisions(Object.values(result.revisions)));
|
|
7059
|
+
store.dispatch(setFormRevisionAttachments(Object.values(result.attachments)));
|
|
6647
7060
|
}
|
|
6648
7061
|
}
|
|
6649
7062
|
const isArrayOfFiles = (value) => {
|
|
6650
7063
|
return Array.isArray(value) && value[0] instanceof File;
|
|
6651
7064
|
};
|
|
6652
|
-
const separateFilesFromValues = (
|
|
6653
|
-
const { values } = payload;
|
|
7065
|
+
const separateFilesFromValues = (values) => {
|
|
6654
7066
|
const files = {};
|
|
6655
7067
|
const newValues = {};
|
|
6656
7068
|
for (const key in values) {
|
|
@@ -6665,17 +7077,13 @@ const separateFilesFromValues = (payload) => {
|
|
|
6665
7077
|
newValues[key] = value;
|
|
6666
7078
|
}
|
|
6667
7079
|
}
|
|
6668
|
-
|
|
6669
|
-
...payload,
|
|
6670
|
-
values: newValues
|
|
6671
|
-
};
|
|
6672
|
-
return { payloadWithoutFiles, files };
|
|
7080
|
+
return { values: newValues, files };
|
|
6673
7081
|
};
|
|
6674
7082
|
class UserFormSubmissionService extends BaseApiService {
|
|
6675
7083
|
constructor() {
|
|
6676
7084
|
super(...arguments);
|
|
6677
7085
|
// Attach files to submission, after uploading them to S3
|
|
6678
|
-
__publicField(this, "getAttachFilesPromises", (files,
|
|
7086
|
+
__publicField(this, "getAttachFilesPromises", (files, submission) => {
|
|
6679
7087
|
const { store } = this.client;
|
|
6680
7088
|
return Object.entries(files).map(async ([key, fileArray]) => {
|
|
6681
7089
|
const attachResults = [];
|
|
@@ -6685,24 +7093,27 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6685
7093
|
const [fileProps] = await this.client.files.uploadFileToS3(sha1);
|
|
6686
7094
|
const submissionAttachmentPayload = offline({
|
|
6687
7095
|
...fileProps,
|
|
6688
|
-
submission:
|
|
7096
|
+
submission: submission.offline_id,
|
|
6689
7097
|
field_identifier: key
|
|
6690
7098
|
});
|
|
6691
7099
|
const attach = await this.enqueueRequest({
|
|
6692
7100
|
description: "Attach file to form submission",
|
|
6693
7101
|
method: HttpMethod.POST,
|
|
6694
|
-
url: `/forms/submission/${
|
|
7102
|
+
url: `/forms/submission/${submission.offline_id}/attachments/`,
|
|
6695
7103
|
payload: submissionAttachmentPayload,
|
|
6696
|
-
blockers: [
|
|
6697
|
-
|
|
6698
|
-
|
|
7104
|
+
blockers: [
|
|
7105
|
+
submission.component,
|
|
7106
|
+
submission.component_stage,
|
|
7107
|
+
submission.issue,
|
|
7108
|
+
submission.form_revision
|
|
7109
|
+
].filter((x) => x !== void 0),
|
|
6699
7110
|
blocks: [submissionAttachmentPayload.offline_id]
|
|
6700
7111
|
});
|
|
6701
7112
|
const offlinePayload = {
|
|
6702
7113
|
...submissionAttachmentPayload,
|
|
6703
7114
|
file: URL.createObjectURL(file)
|
|
6704
7115
|
};
|
|
6705
|
-
store.dispatch(
|
|
7116
|
+
store.dispatch(addFormSubmissionAttachment(offlinePayload));
|
|
6706
7117
|
attachResults.push(attach);
|
|
6707
7118
|
}
|
|
6708
7119
|
return attachResults;
|
|
@@ -6716,70 +7127,113 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6716
7127
|
if (!activeProjectId) {
|
|
6717
7128
|
throw new Error("Expected an active project");
|
|
6718
7129
|
}
|
|
6719
|
-
const {
|
|
7130
|
+
const { values, files } = separateFilesFromValues(payload.values);
|
|
7131
|
+
const offlineSubmission = {
|
|
7132
|
+
...payload,
|
|
7133
|
+
values,
|
|
7134
|
+
created_by: state.userReducer.currentUser.id,
|
|
7135
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
7136
|
+
};
|
|
6720
7137
|
const promise = this.enqueueRequest({
|
|
6721
7138
|
description: "Respond to form",
|
|
6722
7139
|
method: HttpMethod.POST,
|
|
6723
7140
|
url: `/forms/revisions/${payload.form_revision}/respond/`,
|
|
6724
|
-
payload: { ...
|
|
7141
|
+
payload: { ...offlineSubmission, project: activeProjectId },
|
|
6725
7142
|
blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
|
|
6726
7143
|
(x) => x !== void 0
|
|
6727
7144
|
),
|
|
6728
7145
|
blocks: [payload.offline_id]
|
|
6729
7146
|
});
|
|
6730
|
-
const attachFilesPromises = this.getAttachFilesPromises(files,
|
|
6731
|
-
|
|
6732
|
-
const fullOfflineResult = {
|
|
6733
|
-
...payload,
|
|
6734
|
-
created_by: state.userReducer.currentUser.id,
|
|
6735
|
-
created_at: now,
|
|
6736
|
-
updated_at: now
|
|
6737
|
-
};
|
|
6738
|
-
const offlineResultWithoutFiles = {
|
|
6739
|
-
...fullOfflineResult,
|
|
6740
|
-
...payloadWithoutFiles
|
|
6741
|
-
};
|
|
6742
|
-
store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
|
|
7147
|
+
const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
|
|
7148
|
+
store.dispatch(addFormSubmission(offlineSubmission));
|
|
6743
7149
|
void promise.then((result) => {
|
|
6744
7150
|
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
6745
|
-
store.dispatch(
|
|
7151
|
+
store.dispatch(setFormSubmission(result));
|
|
6746
7152
|
return result;
|
|
6747
7153
|
}).catch(() => {
|
|
6748
|
-
store.dispatch(
|
|
7154
|
+
store.dispatch(deleteFormSubmission(payload.offline_id));
|
|
6749
7155
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
6750
7156
|
});
|
|
6751
7157
|
const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
6752
|
-
return [
|
|
7158
|
+
return [offlineSubmission, settledPromise];
|
|
6753
7159
|
}
|
|
6754
|
-
|
|
7160
|
+
// Note currently the bulkAdd method is specific to form submissions for components
|
|
7161
|
+
// TODO: adapt the support bulk adding to any model type
|
|
7162
|
+
bulkAdd(args) {
|
|
7163
|
+
const { form_revision, values: argsValues, component_offline_ids } = args;
|
|
6755
7164
|
const { store } = this.client;
|
|
6756
|
-
const
|
|
6757
|
-
|
|
6758
|
-
|
|
7165
|
+
const submissions = [];
|
|
7166
|
+
const submissionOfflineIds = [];
|
|
7167
|
+
const offline_ids_to_component_ids = [];
|
|
7168
|
+
let attachFilesPromises = [];
|
|
7169
|
+
const { values, files } = separateFilesFromValues(argsValues);
|
|
7170
|
+
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7171
|
+
const createdBy = store.getState().userReducer.currentUser.id;
|
|
7172
|
+
for (const component_id of component_offline_ids) {
|
|
7173
|
+
const submission = offline({
|
|
7174
|
+
form_revision,
|
|
7175
|
+
values,
|
|
7176
|
+
created_by: createdBy,
|
|
7177
|
+
submitted_at: submittedAt,
|
|
7178
|
+
component: component_id
|
|
7179
|
+
});
|
|
7180
|
+
attachFilesPromises = attachFilesPromises.concat(this.getAttachFilesPromises(files, submission));
|
|
7181
|
+
submissionOfflineIds.push(submission.offline_id);
|
|
7182
|
+
offline_ids_to_component_ids.push([submission.offline_id, component_id]);
|
|
7183
|
+
submissions.push(submission);
|
|
6759
7184
|
}
|
|
7185
|
+
store.dispatch(addFormSubmissions(submissions));
|
|
7186
|
+
const promise = this.enqueueRequest({
|
|
7187
|
+
description: "Bulk add form submissions",
|
|
7188
|
+
method: HttpMethod.POST,
|
|
7189
|
+
url: `/forms/revisions/${form_revision}/bulk-respond/`,
|
|
7190
|
+
payload: {
|
|
7191
|
+
form_data: values,
|
|
7192
|
+
submitted_at: submittedAt,
|
|
7193
|
+
offline_ids_to_component_ids
|
|
7194
|
+
},
|
|
7195
|
+
blockers: component_offline_ids,
|
|
7196
|
+
blocks: submissionOfflineIds
|
|
7197
|
+
});
|
|
7198
|
+
promise.then((createdSubmissions) => {
|
|
7199
|
+
store.dispatch(updateFormSubmissions(createdSubmissions));
|
|
7200
|
+
}).catch(() => {
|
|
7201
|
+
store.dispatch(deleteFormSubmissions(submissionOfflineIds));
|
|
7202
|
+
});
|
|
7203
|
+
return [submissions, promise.then(() => Promise.all(attachFilesPromises).then(() => promise))];
|
|
7204
|
+
}
|
|
7205
|
+
update(submission) {
|
|
7206
|
+
const { store } = this.client;
|
|
7207
|
+
const { values, files } = separateFilesFromValues(submission.values);
|
|
6760
7208
|
const attachFilesPromises = this.getAttachFilesPromises(files, submission);
|
|
6761
|
-
const
|
|
6762
|
-
...
|
|
6763
|
-
|
|
7209
|
+
const offlineSubmission = {
|
|
7210
|
+
...submission,
|
|
7211
|
+
values
|
|
6764
7212
|
};
|
|
6765
|
-
store.
|
|
7213
|
+
const submissionToBeUpdated = store.getState().formSubmissionReducer.formSubmissions[submission.offline_id];
|
|
7214
|
+
store.dispatch(updateFormSubmission(offlineSubmission));
|
|
6766
7215
|
const promise = this.enqueueRequest({
|
|
6767
7216
|
description: "Patch form submission",
|
|
6768
7217
|
method: HttpMethod.PATCH,
|
|
6769
7218
|
url: `/forms/submissions/${submission.offline_id}/`,
|
|
6770
|
-
payload:
|
|
6771
|
-
blockers: [
|
|
7219
|
+
payload: offlineSubmission,
|
|
7220
|
+
blockers: [offlineSubmission.issue, offlineSubmission.component, offlineSubmission.component_stage].filter(
|
|
6772
7221
|
(x) => x !== void 0
|
|
6773
7222
|
),
|
|
6774
|
-
blocks: [
|
|
7223
|
+
blocks: [offlineSubmission.offline_id]
|
|
7224
|
+
});
|
|
7225
|
+
promise.then((createdSubmission) => {
|
|
7226
|
+
store.dispatch(setFormSubmission(createdSubmission));
|
|
7227
|
+
}).catch(() => {
|
|
7228
|
+
store.dispatch(setFormSubmission(submissionToBeUpdated));
|
|
6775
7229
|
});
|
|
6776
|
-
return Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
7230
|
+
return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
|
|
6777
7231
|
}
|
|
6778
7232
|
async delete(submissionId) {
|
|
6779
7233
|
const { store } = this.client;
|
|
6780
7234
|
const state = store.getState();
|
|
6781
|
-
const submission = state.
|
|
6782
|
-
store.dispatch(
|
|
7235
|
+
const submission = state.formSubmissionReducer.formSubmissions[submissionId];
|
|
7236
|
+
store.dispatch(deleteFormSubmission(submissionId));
|
|
6783
7237
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
6784
7238
|
try {
|
|
6785
7239
|
return await this.enqueueRequest({
|
|
@@ -6790,10 +7244,8 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6790
7244
|
blocks: []
|
|
6791
7245
|
});
|
|
6792
7246
|
} catch (e) {
|
|
6793
|
-
|
|
6794
|
-
|
|
6795
|
-
store.dispatch(updateOrCreateUserFormSubmission(submission));
|
|
6796
|
-
}
|
|
7247
|
+
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
7248
|
+
store.dispatch(addFormSubmission(submission));
|
|
6797
7249
|
throw e;
|
|
6798
7250
|
}
|
|
6799
7251
|
}
|
|
@@ -6807,7 +7259,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6807
7259
|
blockers: [],
|
|
6808
7260
|
blocks: []
|
|
6809
7261
|
});
|
|
6810
|
-
store.dispatch(
|
|
7262
|
+
store.dispatch(setFormSubmissions(submissions));
|
|
6811
7263
|
const attachments = await this.enqueueRequest({
|
|
6812
7264
|
description: "Fetch form attachments",
|
|
6813
7265
|
method: HttpMethod.GET,
|
|
@@ -6815,7 +7267,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6815
7267
|
blockers: [],
|
|
6816
7268
|
blocks: []
|
|
6817
7269
|
});
|
|
6818
|
-
store.dispatch(
|
|
7270
|
+
store.dispatch(setFormSubmissionAttachments(attachments));
|
|
6819
7271
|
}
|
|
6820
7272
|
}
|
|
6821
7273
|
class WorkspaceService extends BaseApiService {
|
|
@@ -7549,6 +8001,7 @@ class OvermapSDK {
|
|
|
7549
8001
|
__publicField(this, "organizationAccess", new OrganizationAccessService(this));
|
|
7550
8002
|
__publicField(this, "issues", new IssueService(this));
|
|
7551
8003
|
__publicField(this, "issueComments", new IssueCommentService(this));
|
|
8004
|
+
__publicField(this, "issueUpdates", new IssueUpdateService(this));
|
|
7552
8005
|
__publicField(this, "workspaces", new WorkspaceService(this));
|
|
7553
8006
|
__publicField(this, "main", new MainService(this));
|
|
7554
8007
|
__publicField(this, "components", new ComponentService(this));
|
|
@@ -13022,52 +13475,54 @@ const styles$4 = {
|
|
|
13022
13475
|
Footer,
|
|
13023
13476
|
Loading
|
|
13024
13477
|
};
|
|
13025
|
-
const ImageCard = memo(
|
|
13026
|
-
|
|
13027
|
-
|
|
13028
|
-
|
|
13029
|
-
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
13033
|
-
|
|
13034
|
-
|
|
13035
|
-
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13040
|
-
|
|
13041
|
-
|
|
13042
|
-
|
|
13043
|
-
|
|
13044
|
-
|
|
13045
|
-
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
|
|
13060
|
-
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
|
|
13068
|
-
|
|
13069
|
-
}
|
|
13070
|
-
|
|
13478
|
+
const ImageCard = memo(
|
|
13479
|
+
forwardRef((props, forwardedRef) => {
|
|
13480
|
+
const { file, alt, error: error2, size, rightSlot, className, truncateLength, ...rest } = props;
|
|
13481
|
+
const fileCardRef = useRef(null);
|
|
13482
|
+
const imageInsetRef = useRef(null);
|
|
13483
|
+
const fileCardSize = useSize(fileCardRef);
|
|
13484
|
+
useLayoutEffect(() => {
|
|
13485
|
+
if (!imageInsetRef.current || !fileCardSize)
|
|
13486
|
+
return;
|
|
13487
|
+
imageInsetRef.current.style.height = `${fileCardSize.height * 4}px`;
|
|
13488
|
+
}, [fileCardSize]);
|
|
13489
|
+
const fileName2 = useMemo(() => {
|
|
13490
|
+
if (!file)
|
|
13491
|
+
return;
|
|
13492
|
+
return truncateLength !== void 0 ? truncate(file.name, truncateLength) : file.name;
|
|
13493
|
+
}, [file, truncateLength]);
|
|
13494
|
+
return /* @__PURE__ */ jsxs(
|
|
13495
|
+
Flex,
|
|
13496
|
+
{
|
|
13497
|
+
className: classNames$1(className, styles$4.ImageCard),
|
|
13498
|
+
width: "100%",
|
|
13499
|
+
direction: "column",
|
|
13500
|
+
position: "relative",
|
|
13501
|
+
height: "max-content",
|
|
13502
|
+
gap: "0",
|
|
13503
|
+
ref: forwardedRef,
|
|
13504
|
+
...rest,
|
|
13505
|
+
children: [
|
|
13506
|
+
!file && !error2 && /* @__PURE__ */ jsx(Flex, { width: "100%", height: "100%", align: "center", justify: "center", position: "absolute", children: /* @__PURE__ */ jsx(Spinner, {}) }),
|
|
13507
|
+
/* @__PURE__ */ jsx(Inset, { className: styles$4.ImageInset, ref: imageInsetRef, clip: "padding-box", side: "y", pb: "0", children: file && !error2 && /* @__PURE__ */ jsx("img", { className: styles$4.Image, src: URL.createObjectURL(file), alt: alt ?? file.name }) }),
|
|
13508
|
+
/* @__PURE__ */ jsx(
|
|
13509
|
+
OvermapItem,
|
|
13510
|
+
{
|
|
13511
|
+
className: classNames$1(styles$4.Footer, {
|
|
13512
|
+
[styles$4.Loading]: !file
|
|
13513
|
+
}),
|
|
13514
|
+
size,
|
|
13515
|
+
ref: fileCardRef,
|
|
13516
|
+
leftSlot: error2 ? /* @__PURE__ */ jsx(RiIcon, { icon: "RiFileWarningLine" }) : file && /* @__PURE__ */ jsx(FileIcon, { fileType: file.type }),
|
|
13517
|
+
rightSlot,
|
|
13518
|
+
children: error2 ?? fileName2
|
|
13519
|
+
}
|
|
13520
|
+
)
|
|
13521
|
+
]
|
|
13522
|
+
}
|
|
13523
|
+
);
|
|
13524
|
+
})
|
|
13525
|
+
);
|
|
13071
13526
|
const UploadInput = memo((props) => {
|
|
13072
13527
|
var _a2;
|
|
13073
13528
|
const [{ inputId, labelId, size, severity, helpText, showInputOnly, field, fieldProps }, rest] = useFormikInput(props);
|
|
@@ -13666,7 +14121,7 @@ const initialFormValues = (fields, values) => {
|
|
|
13666
14121
|
};
|
|
13667
14122
|
const useAttachImagesToFormRevisionFields = (revision) => {
|
|
13668
14123
|
const { sdk } = useSDK();
|
|
13669
|
-
const attachments = useAppSelector(
|
|
14124
|
+
const attachments = useAppSelector(selectAttachmentsOfFormRevision((revision == null ? void 0 : revision.offline_id) ?? ""));
|
|
13670
14125
|
return useMemo(() => {
|
|
13671
14126
|
if (!revision || !attachments)
|
|
13672
14127
|
return revision;
|
|
@@ -13748,7 +14203,7 @@ const FormRenderer = memo(
|
|
|
13748
14203
|
const FormSubmissionViewer = memo(
|
|
13749
14204
|
forwardRef((props, ref) => {
|
|
13750
14205
|
const { submission, showFormDescription = false, showFormTitle = true } = props;
|
|
13751
|
-
const revision = useAppSelector(
|
|
14206
|
+
const revision = useAppSelector(selectUserFormRevision(submission.form_revision));
|
|
13752
14207
|
const { sdk } = useSDK();
|
|
13753
14208
|
if (!revision) {
|
|
13754
14209
|
throw new Error(
|
|
@@ -13763,7 +14218,7 @@ const FormSubmissionViewer = memo(
|
|
|
13763
14218
|
return formRevisionToSchema(revisionWithImages, { readonly: true });
|
|
13764
14219
|
}, [revisionWithImages]);
|
|
13765
14220
|
const submissionValuesWithAttachments = useMemo(() => {
|
|
13766
|
-
const attachments =
|
|
14221
|
+
const attachments = selectAttachmentsOfFormSubmission(submission.offline_id)(sdk.store.getState()) ?? [];
|
|
13767
14222
|
const downloadedAttachments = {};
|
|
13768
14223
|
for (const attachment of attachments) {
|
|
13769
14224
|
const promise = sdk.files.fetchFileFromUrl(attachment.file, attachment.file_sha1, attachment.file_name);
|
|
@@ -13941,16 +14396,13 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
13941
14396
|
const { submission, onSubmissionClick, compact, labelType, rowDecorator } = props;
|
|
13942
14397
|
const currentUser = useAppSelector(selectCurrentUser);
|
|
13943
14398
|
const createdBy = useAppSelector(selectUser("created_by" in submission ? submission.created_by : currentUser.id));
|
|
13944
|
-
const dateToUse =
|
|
13945
|
-
const formattedDateTime =
|
|
13946
|
-
|
|
13947
|
-
minute: "2-digit"
|
|
13948
|
-
}) : getLocalDateString(dateToUse);
|
|
13949
|
-
const revision = useAppSelector(selectFormRevision(submission.form_revision));
|
|
14399
|
+
const dateToUse = submission.submitted_at;
|
|
14400
|
+
const formattedDateTime = getLocalDateString(dateToUse);
|
|
14401
|
+
const revision = useAppSelector(selectUserFormRevision(submission.form_revision));
|
|
13950
14402
|
if (!revision) {
|
|
13951
14403
|
throw new Error(`Could not find revision ${submission.form_revision} for submission ${submission.offline_id}.`);
|
|
13952
14404
|
}
|
|
13953
|
-
const latestRevisionNumber = (_a2 = useAppSelector(
|
|
14405
|
+
const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevisionOfForm(revision.form))) == null ? void 0 : _a2.revision;
|
|
13954
14406
|
const creatorProfileSrc = useFileSrc({
|
|
13955
14407
|
file: (createdBy == null ? void 0 : createdBy.profile.file) ?? null,
|
|
13956
14408
|
fileSha1: (createdBy == null ? void 0 : createdBy.profile.file_sha1) ?? null
|
|
@@ -13981,10 +14433,6 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
13981
14433
|
return row;
|
|
13982
14434
|
});
|
|
13983
14435
|
FormSubmissionBrowserEntry.displayName = "FormSubmissionBrowserEntry";
|
|
13984
|
-
const getCreatedAtOrSubmittedAtDate = (submission) => {
|
|
13985
|
-
const date = "created_at" in submission ? submission.created_at : submission.submitted_at;
|
|
13986
|
-
return new Date(date);
|
|
13987
|
-
};
|
|
13988
14436
|
const FormSubmissionBrowser = memo((props) => {
|
|
13989
14437
|
const {
|
|
13990
14438
|
formId: formId2,
|
|
@@ -13998,10 +14446,10 @@ const FormSubmissionBrowser = memo((props) => {
|
|
|
13998
14446
|
if (!!formId2 === !!propSubmissions) {
|
|
13999
14447
|
throw new Error("Either formId or submissions must be provided, but not both.");
|
|
14000
14448
|
}
|
|
14001
|
-
const submissions = useAppSelector(propSubmissions ? () => propSubmissions :
|
|
14449
|
+
const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectFormSubmissionsOfForm(formId2));
|
|
14002
14450
|
const sortedSubmissions = useMemo(
|
|
14003
14451
|
() => submissions == null ? void 0 : submissions.sort((a, b) => {
|
|
14004
|
-
return
|
|
14452
|
+
return a.submitted_at.localeCompare(b.submitted_at);
|
|
14005
14453
|
}),
|
|
14006
14454
|
[submissions]
|
|
14007
14455
|
);
|
|
@@ -14204,17 +14652,15 @@ const FieldActions = memo((props) => {
|
|
|
14204
14652
|
Action.key
|
|
14205
14653
|
)) }),
|
|
14206
14654
|
/* @__PURE__ */ jsx(Box, { display: forMobile(true, "block"), children: /* @__PURE__ */ jsx(
|
|
14207
|
-
|
|
14655
|
+
OvermapDropdownMenu,
|
|
14208
14656
|
{
|
|
14209
14657
|
trigger: /* @__PURE__ */ jsx(IconButton, { variant: "ghost", "aria-label": "Actions menu", children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiMore2Line" }) }),
|
|
14210
14658
|
items: actions.map((Action) => {
|
|
14211
14659
|
var _a2;
|
|
14212
14660
|
return {
|
|
14213
|
-
|
|
14214
|
-
|
|
14215
|
-
|
|
14216
|
-
] }, Action.key),
|
|
14217
|
-
onSelect: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
|
|
14661
|
+
leftSlot: /* @__PURE__ */ jsx(Action.Icon, {}),
|
|
14662
|
+
children: Action.text,
|
|
14663
|
+
onClick: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
|
|
14218
14664
|
};
|
|
14219
14665
|
})
|
|
14220
14666
|
}
|
|
@@ -14272,10 +14718,8 @@ const useFieldTypeItems = (onSelect = () => null) => {
|
|
|
14272
14718
|
const field = FieldTypeToClsMapping[identifier];
|
|
14273
14719
|
const Icon = field.Icon;
|
|
14274
14720
|
return {
|
|
14275
|
-
|
|
14276
|
-
|
|
14277
|
-
/* @__PURE__ */ jsx(Text$1, { children: field.fieldTypeName })
|
|
14278
|
-
] }, identifier),
|
|
14721
|
+
children: field.fieldTypeName,
|
|
14722
|
+
leftSlot: /* @__PURE__ */ jsx(Icon, {}),
|
|
14279
14723
|
value: identifier,
|
|
14280
14724
|
onSelect: () => {
|
|
14281
14725
|
onSelect(identifier);
|
|
@@ -14479,7 +14923,7 @@ const FieldBuilder = memo((props) => {
|
|
|
14479
14923
|
}
|
|
14480
14924
|
),
|
|
14481
14925
|
/* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "3", children: [
|
|
14482
|
-
/* @__PURE__ */ jsx(Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.
|
|
14926
|
+
/* @__PURE__ */ jsx(Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.children }),
|
|
14483
14927
|
showPopoverInputs && /* @__PURE__ */ jsx(FieldSettingsPopover, { popoverInputs, hasError: popoverHasErrors })
|
|
14484
14928
|
] }),
|
|
14485
14929
|
resolvedImage && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -14840,7 +15284,7 @@ const FieldSectionWithActions = memo((props) => {
|
|
|
14840
15284
|
)),
|
|
14841
15285
|
droppableProvided.placeholder,
|
|
14842
15286
|
/* @__PURE__ */ jsx(
|
|
14843
|
-
|
|
15287
|
+
OvermapDropdownMenu,
|
|
14844
15288
|
{
|
|
14845
15289
|
trigger: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", children: [
|
|
14846
15290
|
/* @__PURE__ */ jsx(RiIcon, { icon: "RiAddLine" }),
|
|
@@ -15276,6 +15720,8 @@ export {
|
|
|
15276
15720
|
IssuePriority,
|
|
15277
15721
|
IssueService,
|
|
15278
15722
|
IssueStatus,
|
|
15723
|
+
IssueUpdateChange,
|
|
15724
|
+
IssueUpdateService,
|
|
15279
15725
|
LicenseLevel,
|
|
15280
15726
|
LicenseService,
|
|
15281
15727
|
LicenseStatus,
|
|
@@ -15321,6 +15767,7 @@ export {
|
|
|
15321
15767
|
VerificationCodeType,
|
|
15322
15768
|
WorkspaceService,
|
|
15323
15769
|
YELLOW,
|
|
15770
|
+
_selectLatestFormRevision,
|
|
15324
15771
|
_setLatestRetryTime,
|
|
15325
15772
|
acceptProjectInvite,
|
|
15326
15773
|
addActiveProjectFormSubmissionsCount,
|
|
@@ -15336,9 +15783,23 @@ export {
|
|
|
15336
15783
|
addDocuments,
|
|
15337
15784
|
addEmailDomain,
|
|
15338
15785
|
addFavouriteProjectId,
|
|
15786
|
+
addForm,
|
|
15787
|
+
addFormRevision,
|
|
15788
|
+
addFormRevisionAttachment,
|
|
15789
|
+
addFormRevisionAttachments,
|
|
15790
|
+
addFormRevisions,
|
|
15791
|
+
addFormSubmission,
|
|
15792
|
+
addFormSubmissionAttachment,
|
|
15793
|
+
addFormSubmissionAttachments,
|
|
15794
|
+
addFormSubmissions,
|
|
15795
|
+
addForms,
|
|
15339
15796
|
addIssue,
|
|
15340
15797
|
addIssueAttachment,
|
|
15341
15798
|
addIssueAttachments,
|
|
15799
|
+
addIssueComment,
|
|
15800
|
+
addIssueComments,
|
|
15801
|
+
addIssueUpdate,
|
|
15802
|
+
addIssueUpdates,
|
|
15342
15803
|
addLicenses,
|
|
15343
15804
|
addOrReplaceCategories,
|
|
15344
15805
|
addOrReplaceIssueComment,
|
|
@@ -15352,13 +15813,6 @@ export {
|
|
|
15352
15813
|
addStageCompletions,
|
|
15353
15814
|
addStages,
|
|
15354
15815
|
addToRecentIssues,
|
|
15355
|
-
addUserForm,
|
|
15356
|
-
addUserFormRevision,
|
|
15357
|
-
addUserFormRevisionAttachment,
|
|
15358
|
-
addUserFormRevisions,
|
|
15359
|
-
addUserFormSubmissionAttachment,
|
|
15360
|
-
addUserFormSubmissions,
|
|
15361
|
-
addUserForms,
|
|
15362
15816
|
addUsers,
|
|
15363
15817
|
addWorkspace,
|
|
15364
15818
|
areArraysEqual,
|
|
@@ -15389,12 +15843,16 @@ export {
|
|
|
15389
15843
|
defaultBadgeColor,
|
|
15390
15844
|
defaultStore,
|
|
15391
15845
|
deleteComponentType,
|
|
15846
|
+
deleteForm,
|
|
15847
|
+
deleteFormRevision,
|
|
15848
|
+
deleteFormRevisionAttachment,
|
|
15849
|
+
deleteFormRevisionAttachments,
|
|
15850
|
+
deleteFormRevisions,
|
|
15851
|
+
deleteFormSubmission,
|
|
15852
|
+
deleteFormSubmissionAttachment,
|
|
15853
|
+
deleteFormSubmissionAttachments,
|
|
15854
|
+
deleteFormSubmissions,
|
|
15392
15855
|
deleteProject,
|
|
15393
|
-
deleteUserForm,
|
|
15394
|
-
deleteUserFormRevision,
|
|
15395
|
-
deleteUserFormRevisions,
|
|
15396
|
-
deleteUserFormSubmission,
|
|
15397
|
-
deleteUserFormSubmissions,
|
|
15398
15856
|
dequeue,
|
|
15399
15857
|
deserialize,
|
|
15400
15858
|
deserializeField,
|
|
@@ -15423,7 +15881,11 @@ export {
|
|
|
15423
15881
|
fileSlice,
|
|
15424
15882
|
fileToBlob,
|
|
15425
15883
|
flipCoordinates,
|
|
15884
|
+
formRevisionReducer,
|
|
15426
15885
|
formRevisionToSchema,
|
|
15886
|
+
formRevisionsSlice,
|
|
15887
|
+
formSubmissionReducer,
|
|
15888
|
+
formSubmissionSlice,
|
|
15427
15889
|
index as forms,
|
|
15428
15890
|
fullComponentMarkerSize,
|
|
15429
15891
|
generateBadgeColors,
|
|
@@ -15498,6 +15960,9 @@ export {
|
|
|
15498
15960
|
removeIssue,
|
|
15499
15961
|
removeIssueAttachment,
|
|
15500
15962
|
removeIssueComment,
|
|
15963
|
+
removeIssueComments,
|
|
15964
|
+
removeIssueUpdate,
|
|
15965
|
+
removeIssueUpdates,
|
|
15501
15966
|
removeOrganizationAccess,
|
|
15502
15967
|
removeProjectAccess,
|
|
15503
15968
|
removeProjectAccessesOfProject,
|
|
@@ -15543,6 +16008,8 @@ export {
|
|
|
15543
16008
|
selectAttachmentsOfComponentByType,
|
|
15544
16009
|
selectAttachmentsOfComponentType,
|
|
15545
16010
|
selectAttachmentsOfComponentTypeByType,
|
|
16011
|
+
selectAttachmentsOfFormRevision,
|
|
16012
|
+
selectAttachmentsOfFormSubmission,
|
|
15546
16013
|
selectAttachmentsOfIssue,
|
|
15547
16014
|
selectAttachmentsOfIssueByType,
|
|
15548
16015
|
selectAttachmentsOfProject,
|
|
@@ -15564,6 +16031,7 @@ export {
|
|
|
15564
16031
|
selectComponentTypeForm,
|
|
15565
16032
|
selectComponentTypeFromComponent,
|
|
15566
16033
|
selectComponentTypeFromComponents,
|
|
16034
|
+
selectComponentTypeStagesMapping,
|
|
15567
16035
|
selectComponentTypes,
|
|
15568
16036
|
selectComponentTypesByName,
|
|
15569
16037
|
selectComponentTypesFromIds,
|
|
@@ -15571,6 +16039,7 @@ export {
|
|
|
15571
16039
|
selectComponents,
|
|
15572
16040
|
selectComponentsByType,
|
|
15573
16041
|
selectComponentsFromComponentType,
|
|
16042
|
+
selectComponentsMapping,
|
|
15574
16043
|
selectCreateProjectType,
|
|
15575
16044
|
selectCurrentUser,
|
|
15576
16045
|
selectDeletedRequests,
|
|
@@ -15588,7 +16057,17 @@ export {
|
|
|
15588
16057
|
selectFavouriteProjects,
|
|
15589
16058
|
selectFileAttachmentsOfIssue,
|
|
15590
16059
|
selectFilteredUserForms,
|
|
15591
|
-
|
|
16060
|
+
selectFormRevisionMapping,
|
|
16061
|
+
selectFormRevisions,
|
|
16062
|
+
selectFormRevisionsOfForm,
|
|
16063
|
+
selectFormSubmission,
|
|
16064
|
+
selectFormSubmissionAttachmentsMapping,
|
|
16065
|
+
selectFormSubmissions,
|
|
16066
|
+
selectFormSubmissionsByComponents,
|
|
16067
|
+
selectFormSubmissionsMapping,
|
|
16068
|
+
selectFormSubmissionsOfComponent,
|
|
16069
|
+
selectFormSubmissionsOfForm,
|
|
16070
|
+
selectFormSubmissionsOfIssue,
|
|
15592
16071
|
selectHiddenCategoryCount,
|
|
15593
16072
|
selectHiddenComponentTypeIds,
|
|
15594
16073
|
selectIsFetchingInitialData,
|
|
@@ -15599,11 +16078,13 @@ export {
|
|
|
15599
16078
|
selectIssueAttachmentMapping,
|
|
15600
16079
|
selectIssueAttachments,
|
|
15601
16080
|
selectIssueMapping,
|
|
16081
|
+
selectIssueUpdateMapping,
|
|
16082
|
+
selectIssueUpdatesOfIssue,
|
|
15602
16083
|
selectIssues,
|
|
15603
|
-
|
|
16084
|
+
selectLatestFormRevisionByForm,
|
|
16085
|
+
selectLatestFormRevisionOfForm,
|
|
16086
|
+
selectLatestFormRevisionsOfComponentTypes,
|
|
15604
16087
|
selectLatestRetryTime,
|
|
15605
|
-
selectLatestRevisionByFormId,
|
|
15606
|
-
selectLatestRevisionsFromComponentTypeIds,
|
|
15607
16088
|
selectLicense,
|
|
15608
16089
|
selectLicenseForProject,
|
|
15609
16090
|
selectLicenses,
|
|
@@ -15641,8 +16122,6 @@ export {
|
|
|
15641
16122
|
selectRecentIssuesAsSearchResults,
|
|
15642
16123
|
selectRecentProjects,
|
|
15643
16124
|
selectRehydrated,
|
|
15644
|
-
selectRevisionAttachments,
|
|
15645
|
-
selectRevisionsForForm,
|
|
15646
16125
|
selectRootDocuments,
|
|
15647
16126
|
selectShowTooltips,
|
|
15648
16127
|
selectSortedEmailDomains,
|
|
@@ -15650,21 +16129,20 @@ export {
|
|
|
15650
16129
|
selectSortedOrganizationUsers,
|
|
15651
16130
|
selectSortedProjectUsers,
|
|
15652
16131
|
selectSortedProjects,
|
|
16132
|
+
selectStage,
|
|
15653
16133
|
selectStageFormIdsFromStageIds,
|
|
15654
16134
|
selectStageMapping,
|
|
15655
16135
|
selectStages,
|
|
15656
16136
|
selectStagesFromComponentType,
|
|
15657
16137
|
selectStagesFromComponentTypeIds,
|
|
15658
16138
|
selectStagesFromStageIds,
|
|
15659
|
-
selectSubmissionAttachments,
|
|
15660
|
-
selectSubmissionsForComponent,
|
|
15661
|
-
selectSubmissionsForForm,
|
|
15662
|
-
selectSubmissionsForIssue,
|
|
15663
16139
|
selectUploadUrl,
|
|
15664
16140
|
selectUsedColors,
|
|
15665
16141
|
selectUser,
|
|
15666
16142
|
selectUserForm,
|
|
15667
16143
|
selectUserFormMapping,
|
|
16144
|
+
selectUserFormRevision,
|
|
16145
|
+
selectUserFormRevisionAttachmentsMapping,
|
|
15668
16146
|
selectUsersAsMapping,
|
|
15669
16147
|
selectVisibleStatuses,
|
|
15670
16148
|
selectVisibleUserIds,
|
|
@@ -15690,11 +16168,20 @@ export {
|
|
|
15690
16168
|
setEnableClustering,
|
|
15691
16169
|
setEnableDuplicateIssues,
|
|
15692
16170
|
setEnablePlacementMode,
|
|
16171
|
+
setFormRevision,
|
|
16172
|
+
setFormRevisionAttachments,
|
|
16173
|
+
setFormRevisions,
|
|
16174
|
+
setFormSubmission,
|
|
16175
|
+
setFormSubmissionAttachments,
|
|
16176
|
+
setFormSubmissions,
|
|
16177
|
+
setForms,
|
|
15693
16178
|
setIsFetchingInitialData,
|
|
15694
16179
|
setIsImportingProjectFile,
|
|
15695
16180
|
setIsLoading,
|
|
15696
16181
|
setIssueAttachments,
|
|
16182
|
+
setIssueComment,
|
|
15697
16183
|
setIssueComments,
|
|
16184
|
+
setIssueUpdates,
|
|
15698
16185
|
setIssues,
|
|
15699
16186
|
setLicenses,
|
|
15700
16187
|
setLoggedIn,
|
|
@@ -15712,9 +16199,6 @@ export {
|
|
|
15712
16199
|
setTokens,
|
|
15713
16200
|
setTourStep,
|
|
15714
16201
|
setUploadUrl,
|
|
15715
|
-
setUserFormRevisionAttachments,
|
|
15716
|
-
setUserFormSubmissionAttachments,
|
|
15717
|
-
setUserFormSubmissions,
|
|
15718
16202
|
setUsers,
|
|
15719
16203
|
setVisibleStatuses,
|
|
15720
16204
|
setVisibleUserIds,
|
|
@@ -15738,11 +16222,12 @@ export {
|
|
|
15738
16222
|
updateComponentAttachment,
|
|
15739
16223
|
updateComponentTypeAttachment,
|
|
15740
16224
|
updateDocuments,
|
|
16225
|
+
updateFormSubmission,
|
|
16226
|
+
updateFormSubmissions,
|
|
15741
16227
|
updateIssue,
|
|
15742
16228
|
updateIssueAttachment,
|
|
15743
16229
|
updateLicense,
|
|
15744
16230
|
updateOrCreateProject,
|
|
15745
|
-
updateOrCreateUserFormSubmission,
|
|
15746
16231
|
updateOrganizationAccess,
|
|
15747
16232
|
updateProjectAccess,
|
|
15748
16233
|
updateProjectAttachment,
|