@overmap-ai/core 1.0.48-add-agent-response-rating.1 → 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 +1028 -533
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +1027 -532
- 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
|
-
});
|
|
3451
|
+
// revision related actions
|
|
3452
|
+
setFormRevision: (state, action) => {
|
|
3453
|
+
state.formRevisions[action.payload.offline_id] = action.payload;
|
|
3454
|
+
considerCachingFormRevision(action.payload);
|
|
3346
3455
|
},
|
|
3347
|
-
|
|
3348
|
-
state.
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
});
|
|
3354
|
-
},
|
|
3355
|
-
addUserFormRevisions: (state, action) => {
|
|
3356
|
-
action.payload.forEach((userFormRevision) => {
|
|
3357
|
-
state.revisions[userFormRevision.offline_id] = userFormRevision;
|
|
3358
|
-
considerCachingRevision(userFormRevision);
|
|
3359
|
-
});
|
|
3360
|
-
},
|
|
3361
|
-
addUserFormRevision: (state, action) => {
|
|
3362
|
-
state.revisions[action.payload.offline_id] = action.payload;
|
|
3363
|
-
considerCachingRevision(action.payload);
|
|
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
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
}
|
|
3505
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3506
|
+
}
|
|
3507
|
+
},
|
|
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`);
|
|
3406
3511
|
}
|
|
3512
|
+
state.attachments[action.payload.offline_id] = action.payload;
|
|
3407
3513
|
},
|
|
3408
|
-
|
|
3409
|
-
state.revisionAttachments = {};
|
|
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];
|
|
3431
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
|
+
}
|
|
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) => {
|
|
@@ -3514,67 +3704,184 @@ const selectFilteredUserForms = restructureCreateSelectorWithArgs(
|
|
|
3514
3704
|
break;
|
|
3515
3705
|
}
|
|
3516
3706
|
}
|
|
3517
|
-
const maxRegularMatches = maxResults - favoriteMatches.length;
|
|
3518
|
-
return [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)];
|
|
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`);
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
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
|
-
);
|
|
3550
|
-
const selectUserForm = (formId2) => (state) => {
|
|
3551
|
-
return state.userFormReducer.userForms[formId2];
|
|
3552
|
-
};
|
|
3553
|
-
const selectSubmissionMapping = (state) => state.userFormReducer.submissions;
|
|
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
3867
|
);
|
|
3564
|
-
const
|
|
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) {
|
|
@@ -4254,7 +4544,17 @@ function runMiddleware(action) {
|
|
|
4254
4544
|
const discardStatuses = [400, 409, 403, 404, 405, 500];
|
|
4255
4545
|
const statusMessages = {
|
|
4256
4546
|
403: { title: "Forbidden", description: "You are not authorized to perform this action.", severity: "danger" },
|
|
4257
|
-
404: { title: "Not found", description: "The requested resource was not found.", severity: "danger" }
|
|
4547
|
+
404: { title: "Not found", description: "The requested resource was not found.", severity: "danger" },
|
|
4548
|
+
405: {
|
|
4549
|
+
title: "Not supported",
|
|
4550
|
+
description: "It's not you. It's us. Sorry for the inconvenience.",
|
|
4551
|
+
severity: "danger"
|
|
4552
|
+
},
|
|
4553
|
+
500: {
|
|
4554
|
+
title: "Server error",
|
|
4555
|
+
description: "Our server seems to be experiencing problems at the moment. We have been alerted and will fix the problem as soon as possible.",
|
|
4556
|
+
severity: "danger"
|
|
4557
|
+
}
|
|
4258
4558
|
};
|
|
4259
4559
|
function discard(reason, action, retries = 0) {
|
|
4260
4560
|
var _a2;
|
|
@@ -4427,7 +4727,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4427
4727
|
}
|
|
4428
4728
|
// Attachments aren't models, so we use the OptimisticGenericResult type instead
|
|
4429
4729
|
async addIssueAttachment(attachmentPayload) {
|
|
4430
|
-
const {
|
|
4730
|
+
const { issue, file_sha1, offline_id } = attachmentPayload;
|
|
4431
4731
|
if (!attachmentPayload.file.objectURL) {
|
|
4432
4732
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4433
4733
|
}
|
|
@@ -4435,7 +4735,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4435
4735
|
...attachmentPayload,
|
|
4436
4736
|
file: attachmentPayload.file.objectURL,
|
|
4437
4737
|
file_name: attachmentPayload.file.name,
|
|
4438
|
-
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
|
|
4439
4741
|
};
|
|
4440
4742
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4441
4743
|
this.client.store.dispatch(addIssueAttachment(offlineAttachment));
|
|
@@ -4447,10 +4749,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4447
4749
|
blocks: [offline_id, issue],
|
|
4448
4750
|
blockers: [file_sha1],
|
|
4449
4751
|
payload: {
|
|
4450
|
-
|
|
4451
|
-
issue,
|
|
4452
|
-
description: description2 ?? "",
|
|
4453
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4752
|
+
...offlineAttachment,
|
|
4454
4753
|
...fileProps
|
|
4455
4754
|
}
|
|
4456
4755
|
});
|
|
@@ -4461,7 +4760,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4461
4760
|
return [offlineAttachment, promise];
|
|
4462
4761
|
}
|
|
4463
4762
|
async addComponentAttachment(attachmentPayload) {
|
|
4464
|
-
const {
|
|
4763
|
+
const { component, file_sha1, offline_id } = attachmentPayload;
|
|
4465
4764
|
if (!attachmentPayload.file.objectURL) {
|
|
4466
4765
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4467
4766
|
}
|
|
@@ -4469,7 +4768,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4469
4768
|
...attachmentPayload,
|
|
4470
4769
|
file: attachmentPayload.file.objectURL,
|
|
4471
4770
|
file_name: attachmentPayload.file.name,
|
|
4472
|
-
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
|
|
4473
4774
|
};
|
|
4474
4775
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4475
4776
|
this.client.store.dispatch(addComponentAttachment(offlineAttachment));
|
|
@@ -4481,10 +4782,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4481
4782
|
blocks: [offline_id, component],
|
|
4482
4783
|
blockers: [file_sha1],
|
|
4483
4784
|
payload: {
|
|
4484
|
-
|
|
4485
|
-
component,
|
|
4486
|
-
description: description2 ?? "",
|
|
4487
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4785
|
+
...offlineAttachment,
|
|
4488
4786
|
...fileProps
|
|
4489
4787
|
}
|
|
4490
4788
|
});
|
|
@@ -4495,7 +4793,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4495
4793
|
return [offlineAttachment, promise];
|
|
4496
4794
|
}
|
|
4497
4795
|
async addComponentTypeAttachment(attachmentPayload) {
|
|
4498
|
-
const {
|
|
4796
|
+
const { component_type, file_sha1, offline_id } = attachmentPayload;
|
|
4499
4797
|
if (!attachmentPayload.file.objectURL) {
|
|
4500
4798
|
throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
|
|
4501
4799
|
}
|
|
@@ -4503,7 +4801,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4503
4801
|
...attachmentPayload,
|
|
4504
4802
|
file: attachmentPayload.file.objectURL,
|
|
4505
4803
|
file_name: attachmentPayload.file.name,
|
|
4506
|
-
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
|
|
4507
4807
|
};
|
|
4508
4808
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4509
4809
|
this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
|
|
@@ -4515,10 +4815,7 @@ class AttachmentService extends BaseApiService {
|
|
|
4515
4815
|
blocks: [offline_id, component_type],
|
|
4516
4816
|
blockers: [file_sha1],
|
|
4517
4817
|
payload: {
|
|
4518
|
-
|
|
4519
|
-
component_type,
|
|
4520
|
-
description: description2 ?? "",
|
|
4521
|
-
submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
|
|
4818
|
+
...offlineAttachment,
|
|
4522
4819
|
...fileProps
|
|
4523
4820
|
}
|
|
4524
4821
|
});
|
|
@@ -4537,7 +4834,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4537
4834
|
...attachmentPayload,
|
|
4538
4835
|
file: attachmentPayload.file.objectURL,
|
|
4539
4836
|
file_name: attachmentPayload.file.name,
|
|
4540
|
-
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
|
|
4541
4840
|
};
|
|
4542
4841
|
await this.client.files.addCache(attachmentPayload.file, file_sha1);
|
|
4543
4842
|
this.client.store.dispatch(addProjectAttachment(offlineAttachment));
|
|
@@ -4577,7 +4876,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4577
4876
|
file_name: file2.name,
|
|
4578
4877
|
file_type: file2.type,
|
|
4579
4878
|
issue: issueId,
|
|
4580
|
-
file_sha1: hash
|
|
4879
|
+
file_sha1: hash,
|
|
4880
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4881
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4581
4882
|
});
|
|
4582
4883
|
return this.addIssueAttachment(attachment);
|
|
4583
4884
|
};
|
|
@@ -4596,7 +4897,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4596
4897
|
file_name: file2.name,
|
|
4597
4898
|
file_type: file2.type,
|
|
4598
4899
|
component: componentId,
|
|
4599
|
-
file_sha1: hash
|
|
4900
|
+
file_sha1: hash,
|
|
4901
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4902
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4600
4903
|
});
|
|
4601
4904
|
return this.addComponentAttachment(attachment);
|
|
4602
4905
|
};
|
|
@@ -4615,7 +4918,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4615
4918
|
file_name: file2.name,
|
|
4616
4919
|
file_type: file2.type,
|
|
4617
4920
|
component_type: componentTypeId,
|
|
4618
|
-
file_sha1: hash
|
|
4921
|
+
file_sha1: hash,
|
|
4922
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4923
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4619
4924
|
});
|
|
4620
4925
|
return this.addComponentTypeAttachment(attachment);
|
|
4621
4926
|
};
|
|
@@ -4634,7 +4939,9 @@ class AttachmentService extends BaseApiService {
|
|
|
4634
4939
|
file_name: file2.name,
|
|
4635
4940
|
file_type: file2.type,
|
|
4636
4941
|
project: projectId,
|
|
4637
|
-
file_sha1: hash
|
|
4942
|
+
file_sha1: hash,
|
|
4943
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4944
|
+
created_by: this.client.store.getState().userReducer.currentUser.id
|
|
4638
4945
|
});
|
|
4639
4946
|
return this.addProjectAttachment(attachment);
|
|
4640
4947
|
};
|
|
@@ -5711,49 +6018,35 @@ class ComponentTypeService extends BaseApiService {
|
|
|
5711
6018
|
}
|
|
5712
6019
|
}
|
|
5713
6020
|
class IssueCommentService extends BaseApiService {
|
|
6021
|
+
// Omit author and submitted_at since these will always be set internally
|
|
5714
6022
|
add(comment) {
|
|
5715
|
-
const offlinePayload = offline(comment);
|
|
5716
|
-
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
5717
6023
|
const { store } = this.client;
|
|
5718
|
-
const offlineComment = {
|
|
5719
|
-
...
|
|
6024
|
+
const offlineComment = offline({
|
|
6025
|
+
...comment,
|
|
5720
6026
|
author: store.getState().userReducer.currentUser.id,
|
|
5721
|
-
|
|
5722
|
-
};
|
|
5723
|
-
store.dispatch(
|
|
6027
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6028
|
+
});
|
|
6029
|
+
store.dispatch(addIssueComment(offlineComment));
|
|
5724
6030
|
const promise = this.enqueueRequest({
|
|
5725
6031
|
description: `${truncate(comment.content, 80)}`,
|
|
5726
6032
|
method: HttpMethod.POST,
|
|
5727
6033
|
url: `/issues/${comment.issue}/comment/`,
|
|
5728
|
-
payload:
|
|
6034
|
+
payload: offlineComment,
|
|
5729
6035
|
blockers: [comment.issue],
|
|
5730
|
-
blocks: [
|
|
6036
|
+
blocks: [offlineComment.offline_id]
|
|
6037
|
+
});
|
|
6038
|
+
promise.catch(() => {
|
|
6039
|
+
store.dispatch(removeIssueComment(offlineComment.offline_id));
|
|
5731
6040
|
});
|
|
5732
6041
|
return [offlineComment, promise];
|
|
5733
6042
|
}
|
|
5734
|
-
|
|
6043
|
+
update(comment) {
|
|
5735
6044
|
const { store } = this.client;
|
|
5736
|
-
const
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
// TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
|
|
5740
|
-
url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
|
|
5741
|
-
blockers: [],
|
|
5742
|
-
blocks: []
|
|
5743
|
-
});
|
|
5744
|
-
let filteredResult = result.filter(onlyUniqueOfflineIds);
|
|
5745
|
-
filteredResult = filteredResult.map((comment) => {
|
|
5746
|
-
return { ...comment };
|
|
5747
|
-
});
|
|
5748
|
-
if (result.length !== filteredResult.length) {
|
|
5749
|
-
console.error(
|
|
5750
|
-
`Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
|
|
5751
|
-
);
|
|
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`);
|
|
5752
6048
|
}
|
|
5753
|
-
store.dispatch(
|
|
5754
|
-
}
|
|
5755
|
-
update(comment) {
|
|
5756
|
-
this.client.store.dispatch(addOrReplaceIssueComment(comment));
|
|
6049
|
+
store.dispatch(setIssueComment(comment));
|
|
5757
6050
|
const promise = this.enqueueRequest({
|
|
5758
6051
|
description: `Edit comment: ${truncate(comment.content, 80)}`,
|
|
5759
6052
|
method: HttpMethod.PATCH,
|
|
@@ -5762,17 +6055,62 @@ class IssueCommentService extends BaseApiService {
|
|
|
5762
6055
|
blockers: [comment.issue],
|
|
5763
6056
|
blocks: [comment.offline_id]
|
|
5764
6057
|
});
|
|
6058
|
+
promise.catch(() => {
|
|
6059
|
+
store.dispatch(setIssueComment(commentToUpdate));
|
|
6060
|
+
});
|
|
5765
6061
|
return [comment, promise];
|
|
5766
6062
|
}
|
|
5767
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
|
+
}
|
|
5768
6068
|
this.client.store.dispatch(removeIssueComment(offline_id));
|
|
5769
|
-
|
|
6069
|
+
const promise = this.enqueueRequest({
|
|
5770
6070
|
description: "Delete comment",
|
|
5771
6071
|
method: HttpMethod.DELETE,
|
|
5772
6072
|
url: `/issues/comments/${offline_id}/`,
|
|
5773
6073
|
blockers: [offline_id],
|
|
5774
6074
|
blocks: []
|
|
5775
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));
|
|
5776
6114
|
}
|
|
5777
6115
|
}
|
|
5778
6116
|
class IssueService extends BaseApiService {
|
|
@@ -5853,7 +6191,83 @@ class IssueService extends BaseApiService {
|
|
|
5853
6191
|
return [offlineIssues, promise];
|
|
5854
6192
|
}
|
|
5855
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
|
+
}
|
|
5856
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));
|
|
5857
6271
|
const promise = this.enqueueRequest({
|
|
5858
6272
|
description: "Edit issue",
|
|
5859
6273
|
method: HttpMethod.PATCH,
|
|
@@ -5862,23 +6276,30 @@ class IssueService extends BaseApiService {
|
|
|
5862
6276
|
blockers: [issue.offline_id],
|
|
5863
6277
|
blocks: [issue.offline_id]
|
|
5864
6278
|
});
|
|
6279
|
+
promise.catch(() => {
|
|
6280
|
+
this.client.store.dispatch(updateIssue(issueToBeUpdated));
|
|
6281
|
+
this.client.store.dispatch(removeIssueUpdate(offlineIssueUpdate.offline_id));
|
|
6282
|
+
});
|
|
5865
6283
|
const fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id];
|
|
5866
6284
|
return [fullIssue, promise];
|
|
5867
6285
|
}
|
|
5868
6286
|
async remove(id) {
|
|
5869
6287
|
const { store } = this.client;
|
|
5870
6288
|
const state = store.getState();
|
|
6289
|
+
const dispatch = store.dispatch;
|
|
5871
6290
|
const backup = state.issueReducer.issues[id];
|
|
5872
6291
|
if (!backup) {
|
|
5873
6292
|
throw new Error(`No issue with id ${id} found in the store`);
|
|
5874
6293
|
}
|
|
5875
6294
|
const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue === id);
|
|
5876
6295
|
const attachmentsOfIssue = selectAttachmentsOfIssue(id)(state);
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
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)));
|
|
5882
6303
|
try {
|
|
5883
6304
|
return await this.enqueueRequest({
|
|
5884
6305
|
description: "Delete issue",
|
|
@@ -5888,9 +6309,10 @@ class IssueService extends BaseApiService {
|
|
|
5888
6309
|
blocks: []
|
|
5889
6310
|
});
|
|
5890
6311
|
} catch (e) {
|
|
5891
|
-
|
|
5892
|
-
|
|
5893
|
-
|
|
6312
|
+
dispatch(addIssue(backup));
|
|
6313
|
+
dispatch(addIssueAttachments(attachments));
|
|
6314
|
+
dispatch(addIssueUpdates(updatesOfIssue));
|
|
6315
|
+
dispatch(addActiveProjectIssuesCount(1));
|
|
5894
6316
|
throw e;
|
|
5895
6317
|
}
|
|
5896
6318
|
}
|
|
@@ -6072,6 +6494,7 @@ class MainService extends BaseApiService {
|
|
|
6072
6494
|
store.dispatch(setProjectAttachments(project_attachments));
|
|
6073
6495
|
});
|
|
6074
6496
|
void this.client.documents.refreshStore();
|
|
6497
|
+
void this.client.issueUpdates.refreshStore();
|
|
6075
6498
|
}
|
|
6076
6499
|
store.dispatch(setIsFetchingInitialData(false));
|
|
6077
6500
|
if (overwrite) {
|
|
@@ -6436,7 +6859,7 @@ class UserFormService extends BaseApiService {
|
|
|
6436
6859
|
...revisionAttachmentPayload,
|
|
6437
6860
|
file: URL.createObjectURL(image)
|
|
6438
6861
|
};
|
|
6439
|
-
store.dispatch(
|
|
6862
|
+
store.dispatch(addFormRevisionAttachment(offlinePayload));
|
|
6440
6863
|
return attach;
|
|
6441
6864
|
});
|
|
6442
6865
|
});
|
|
@@ -6470,8 +6893,8 @@ class UserFormService extends BaseApiService {
|
|
|
6470
6893
|
revision: 0
|
|
6471
6894
|
};
|
|
6472
6895
|
const { store } = this.client;
|
|
6473
|
-
store.dispatch(
|
|
6474
|
-
store.dispatch(
|
|
6896
|
+
store.dispatch(addForm(retForm));
|
|
6897
|
+
store.dispatch(addFormRevision(retRevision));
|
|
6475
6898
|
const formPromise = this.enqueueRequest({
|
|
6476
6899
|
description: "Create form",
|
|
6477
6900
|
method: HttpMethod.POST,
|
|
@@ -6489,8 +6912,8 @@ class UserFormService extends BaseApiService {
|
|
|
6489
6912
|
});
|
|
6490
6913
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevisionPayload.offline_id);
|
|
6491
6914
|
void formPromise.catch((e) => {
|
|
6492
|
-
store.dispatch(
|
|
6493
|
-
store.dispatch(
|
|
6915
|
+
store.dispatch(deleteForm(retForm.offline_id));
|
|
6916
|
+
store.dispatch(deleteFormRevision(retRevision.offline_id));
|
|
6494
6917
|
throw e;
|
|
6495
6918
|
});
|
|
6496
6919
|
const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
|
|
@@ -6532,7 +6955,7 @@ class UserFormService extends BaseApiService {
|
|
|
6532
6955
|
revision: "Pending",
|
|
6533
6956
|
form: formId2
|
|
6534
6957
|
};
|
|
6535
|
-
store.dispatch(
|
|
6958
|
+
store.dispatch(addFormRevision(fullRevision));
|
|
6536
6959
|
const promise = this.enqueueRequest({
|
|
6537
6960
|
description: "Create form revision",
|
|
6538
6961
|
method: HttpMethod.PATCH,
|
|
@@ -6546,9 +6969,9 @@ class UserFormService extends BaseApiService {
|
|
|
6546
6969
|
});
|
|
6547
6970
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
|
|
6548
6971
|
void promise.then((result) => {
|
|
6549
|
-
store.dispatch(
|
|
6972
|
+
store.dispatch(setFormRevision(result));
|
|
6550
6973
|
}).catch(() => {
|
|
6551
|
-
store.dispatch(
|
|
6974
|
+
store.dispatch(deleteFormRevision(fullRevision.offline_id));
|
|
6552
6975
|
});
|
|
6553
6976
|
const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
|
|
6554
6977
|
return [fullRevision, settledPromise];
|
|
@@ -6594,15 +7017,15 @@ class UserFormService extends BaseApiService {
|
|
|
6594
7017
|
if (!userForm) {
|
|
6595
7018
|
throw new Error("Expected userForm to exist");
|
|
6596
7019
|
}
|
|
6597
|
-
const userFormSubmissions =
|
|
7020
|
+
const userFormSubmissions = selectFormSubmissionsOfForm(formId2)(state);
|
|
6598
7021
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6599
|
-
store.dispatch(
|
|
7022
|
+
store.dispatch(deleteFormSubmissions(userFormSubmissions.map(({ offline_id }) => offline_id)));
|
|
6600
7023
|
}
|
|
6601
|
-
const userFormRevisions =
|
|
7024
|
+
const userFormRevisions = selectFormRevisionsOfForm(formId2)(state);
|
|
6602
7025
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6603
|
-
store.dispatch(
|
|
7026
|
+
store.dispatch(deleteFormRevisions(userFormRevisions.map(({ offline_id }) => offline_id)));
|
|
6604
7027
|
}
|
|
6605
|
-
store.dispatch(
|
|
7028
|
+
store.dispatch(deleteForm(formId2));
|
|
6606
7029
|
try {
|
|
6607
7030
|
return await this.enqueueRequest({
|
|
6608
7031
|
description: "Delete form",
|
|
@@ -6612,12 +7035,12 @@ class UserFormService extends BaseApiService {
|
|
|
6612
7035
|
blocks: []
|
|
6613
7036
|
});
|
|
6614
7037
|
} catch (e) {
|
|
6615
|
-
store.dispatch(
|
|
7038
|
+
store.dispatch(addForm(userForm));
|
|
6616
7039
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6617
|
-
store.dispatch(
|
|
7040
|
+
store.dispatch(addFormRevisions(userFormRevisions));
|
|
6618
7041
|
}
|
|
6619
7042
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6620
|
-
store.dispatch(
|
|
7043
|
+
store.dispatch(addFormSubmissions(userFormSubmissions));
|
|
6621
7044
|
}
|
|
6622
7045
|
throw e;
|
|
6623
7046
|
}
|
|
@@ -6631,16 +7054,15 @@ class UserFormService extends BaseApiService {
|
|
|
6631
7054
|
blockers: [],
|
|
6632
7055
|
blocks: []
|
|
6633
7056
|
});
|
|
6634
|
-
store.dispatch(
|
|
6635
|
-
store.dispatch(
|
|
6636
|
-
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)));
|
|
6637
7060
|
}
|
|
6638
7061
|
}
|
|
6639
7062
|
const isArrayOfFiles = (value) => {
|
|
6640
7063
|
return Array.isArray(value) && value[0] instanceof File;
|
|
6641
7064
|
};
|
|
6642
|
-
const separateFilesFromValues = (
|
|
6643
|
-
const { values } = payload;
|
|
7065
|
+
const separateFilesFromValues = (values) => {
|
|
6644
7066
|
const files = {};
|
|
6645
7067
|
const newValues = {};
|
|
6646
7068
|
for (const key in values) {
|
|
@@ -6655,17 +7077,13 @@ const separateFilesFromValues = (payload) => {
|
|
|
6655
7077
|
newValues[key] = value;
|
|
6656
7078
|
}
|
|
6657
7079
|
}
|
|
6658
|
-
|
|
6659
|
-
...payload,
|
|
6660
|
-
values: newValues
|
|
6661
|
-
};
|
|
6662
|
-
return { payloadWithoutFiles, files };
|
|
7080
|
+
return { values: newValues, files };
|
|
6663
7081
|
};
|
|
6664
7082
|
class UserFormSubmissionService extends BaseApiService {
|
|
6665
7083
|
constructor() {
|
|
6666
7084
|
super(...arguments);
|
|
6667
7085
|
// Attach files to submission, after uploading them to S3
|
|
6668
|
-
__publicField(this, "getAttachFilesPromises", (files,
|
|
7086
|
+
__publicField(this, "getAttachFilesPromises", (files, submission) => {
|
|
6669
7087
|
const { store } = this.client;
|
|
6670
7088
|
return Object.entries(files).map(async ([key, fileArray]) => {
|
|
6671
7089
|
const attachResults = [];
|
|
@@ -6675,24 +7093,27 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6675
7093
|
const [fileProps] = await this.client.files.uploadFileToS3(sha1);
|
|
6676
7094
|
const submissionAttachmentPayload = offline({
|
|
6677
7095
|
...fileProps,
|
|
6678
|
-
submission:
|
|
7096
|
+
submission: submission.offline_id,
|
|
6679
7097
|
field_identifier: key
|
|
6680
7098
|
});
|
|
6681
7099
|
const attach = await this.enqueueRequest({
|
|
6682
7100
|
description: "Attach file to form submission",
|
|
6683
7101
|
method: HttpMethod.POST,
|
|
6684
|
-
url: `/forms/submission/${
|
|
7102
|
+
url: `/forms/submission/${submission.offline_id}/attachments/`,
|
|
6685
7103
|
payload: submissionAttachmentPayload,
|
|
6686
|
-
blockers: [
|
|
6687
|
-
|
|
6688
|
-
|
|
7104
|
+
blockers: [
|
|
7105
|
+
submission.component,
|
|
7106
|
+
submission.component_stage,
|
|
7107
|
+
submission.issue,
|
|
7108
|
+
submission.form_revision
|
|
7109
|
+
].filter((x) => x !== void 0),
|
|
6689
7110
|
blocks: [submissionAttachmentPayload.offline_id]
|
|
6690
7111
|
});
|
|
6691
7112
|
const offlinePayload = {
|
|
6692
7113
|
...submissionAttachmentPayload,
|
|
6693
7114
|
file: URL.createObjectURL(file)
|
|
6694
7115
|
};
|
|
6695
|
-
store.dispatch(
|
|
7116
|
+
store.dispatch(addFormSubmissionAttachment(offlinePayload));
|
|
6696
7117
|
attachResults.push(attach);
|
|
6697
7118
|
}
|
|
6698
7119
|
return attachResults;
|
|
@@ -6706,70 +7127,113 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6706
7127
|
if (!activeProjectId) {
|
|
6707
7128
|
throw new Error("Expected an active project");
|
|
6708
7129
|
}
|
|
6709
|
-
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
|
+
};
|
|
6710
7137
|
const promise = this.enqueueRequest({
|
|
6711
7138
|
description: "Respond to form",
|
|
6712
7139
|
method: HttpMethod.POST,
|
|
6713
7140
|
url: `/forms/revisions/${payload.form_revision}/respond/`,
|
|
6714
|
-
payload: { ...
|
|
7141
|
+
payload: { ...offlineSubmission, project: activeProjectId },
|
|
6715
7142
|
blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
|
|
6716
7143
|
(x) => x !== void 0
|
|
6717
7144
|
),
|
|
6718
7145
|
blocks: [payload.offline_id]
|
|
6719
7146
|
});
|
|
6720
|
-
const attachFilesPromises = this.getAttachFilesPromises(files,
|
|
6721
|
-
|
|
6722
|
-
const fullOfflineResult = {
|
|
6723
|
-
...payload,
|
|
6724
|
-
created_by: state.userReducer.currentUser.id,
|
|
6725
|
-
created_at: now,
|
|
6726
|
-
updated_at: now
|
|
6727
|
-
};
|
|
6728
|
-
const offlineResultWithoutFiles = {
|
|
6729
|
-
...fullOfflineResult,
|
|
6730
|
-
...payloadWithoutFiles
|
|
6731
|
-
};
|
|
6732
|
-
store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
|
|
7147
|
+
const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
|
|
7148
|
+
store.dispatch(addFormSubmission(offlineSubmission));
|
|
6733
7149
|
void promise.then((result) => {
|
|
6734
7150
|
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
6735
|
-
store.dispatch(
|
|
7151
|
+
store.dispatch(setFormSubmission(result));
|
|
6736
7152
|
return result;
|
|
6737
7153
|
}).catch(() => {
|
|
6738
|
-
store.dispatch(
|
|
7154
|
+
store.dispatch(deleteFormSubmission(payload.offline_id));
|
|
6739
7155
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
6740
7156
|
});
|
|
6741
7157
|
const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
6742
|
-
return [
|
|
7158
|
+
return [offlineSubmission, settledPromise];
|
|
6743
7159
|
}
|
|
6744
|
-
|
|
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;
|
|
6745
7164
|
const { store } = this.client;
|
|
6746
|
-
const
|
|
6747
|
-
|
|
6748
|
-
|
|
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);
|
|
6749
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);
|
|
6750
7208
|
const attachFilesPromises = this.getAttachFilesPromises(files, submission);
|
|
6751
|
-
const
|
|
6752
|
-
...
|
|
6753
|
-
|
|
7209
|
+
const offlineSubmission = {
|
|
7210
|
+
...submission,
|
|
7211
|
+
values
|
|
6754
7212
|
};
|
|
6755
|
-
store.
|
|
7213
|
+
const submissionToBeUpdated = store.getState().formSubmissionReducer.formSubmissions[submission.offline_id];
|
|
7214
|
+
store.dispatch(updateFormSubmission(offlineSubmission));
|
|
6756
7215
|
const promise = this.enqueueRequest({
|
|
6757
7216
|
description: "Patch form submission",
|
|
6758
7217
|
method: HttpMethod.PATCH,
|
|
6759
7218
|
url: `/forms/submissions/${submission.offline_id}/`,
|
|
6760
|
-
payload:
|
|
6761
|
-
blockers: [
|
|
7219
|
+
payload: offlineSubmission,
|
|
7220
|
+
blockers: [offlineSubmission.issue, offlineSubmission.component, offlineSubmission.component_stage].filter(
|
|
6762
7221
|
(x) => x !== void 0
|
|
6763
7222
|
),
|
|
6764
|
-
blocks: [
|
|
7223
|
+
blocks: [offlineSubmission.offline_id]
|
|
7224
|
+
});
|
|
7225
|
+
promise.then((createdSubmission) => {
|
|
7226
|
+
store.dispatch(setFormSubmission(createdSubmission));
|
|
7227
|
+
}).catch(() => {
|
|
7228
|
+
store.dispatch(setFormSubmission(submissionToBeUpdated));
|
|
6765
7229
|
});
|
|
6766
|
-
return Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
7230
|
+
return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
|
|
6767
7231
|
}
|
|
6768
7232
|
async delete(submissionId) {
|
|
6769
7233
|
const { store } = this.client;
|
|
6770
7234
|
const state = store.getState();
|
|
6771
|
-
const submission = state.
|
|
6772
|
-
store.dispatch(
|
|
7235
|
+
const submission = state.formSubmissionReducer.formSubmissions[submissionId];
|
|
7236
|
+
store.dispatch(deleteFormSubmission(submissionId));
|
|
6773
7237
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
6774
7238
|
try {
|
|
6775
7239
|
return await this.enqueueRequest({
|
|
@@ -6780,10 +7244,8 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6780
7244
|
blocks: []
|
|
6781
7245
|
});
|
|
6782
7246
|
} catch (e) {
|
|
6783
|
-
|
|
6784
|
-
|
|
6785
|
-
store.dispatch(updateOrCreateUserFormSubmission(submission));
|
|
6786
|
-
}
|
|
7247
|
+
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
7248
|
+
store.dispatch(addFormSubmission(submission));
|
|
6787
7249
|
throw e;
|
|
6788
7250
|
}
|
|
6789
7251
|
}
|
|
@@ -6797,7 +7259,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6797
7259
|
blockers: [],
|
|
6798
7260
|
blocks: []
|
|
6799
7261
|
});
|
|
6800
|
-
store.dispatch(
|
|
7262
|
+
store.dispatch(setFormSubmissions(submissions));
|
|
6801
7263
|
const attachments = await this.enqueueRequest({
|
|
6802
7264
|
description: "Fetch form attachments",
|
|
6803
7265
|
method: HttpMethod.GET,
|
|
@@ -6805,7 +7267,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
6805
7267
|
blockers: [],
|
|
6806
7268
|
blocks: []
|
|
6807
7269
|
});
|
|
6808
|
-
store.dispatch(
|
|
7270
|
+
store.dispatch(setFormSubmissionAttachments(attachments));
|
|
6809
7271
|
}
|
|
6810
7272
|
}
|
|
6811
7273
|
class WorkspaceService extends BaseApiService {
|
|
@@ -7503,7 +7965,7 @@ class AgentService extends BaseApiService {
|
|
|
7503
7965
|
const activeProjectId = this.client.store.getState().projectReducer.activeProjectId;
|
|
7504
7966
|
return this.enqueueRequest({
|
|
7505
7967
|
description: "Prompt agent",
|
|
7506
|
-
method: HttpMethod.
|
|
7968
|
+
method: HttpMethod.POST,
|
|
7507
7969
|
url: "/agents/prompt/",
|
|
7508
7970
|
payload: {
|
|
7509
7971
|
prompt: request2,
|
|
@@ -7517,7 +7979,7 @@ class AgentService extends BaseApiService {
|
|
|
7517
7979
|
async rate(responseId, rating) {
|
|
7518
7980
|
return this.enqueueRequest({
|
|
7519
7981
|
description: "Rate agent response",
|
|
7520
|
-
method: HttpMethod.
|
|
7982
|
+
method: HttpMethod.PUT,
|
|
7521
7983
|
url: `/agents/responses/${responseId}/rate/`,
|
|
7522
7984
|
payload: { rating },
|
|
7523
7985
|
blockers: ["rate"],
|
|
@@ -7539,6 +8001,7 @@ class OvermapSDK {
|
|
|
7539
8001
|
__publicField(this, "organizationAccess", new OrganizationAccessService(this));
|
|
7540
8002
|
__publicField(this, "issues", new IssueService(this));
|
|
7541
8003
|
__publicField(this, "issueComments", new IssueCommentService(this));
|
|
8004
|
+
__publicField(this, "issueUpdates", new IssueUpdateService(this));
|
|
7542
8005
|
__publicField(this, "workspaces", new WorkspaceService(this));
|
|
7543
8006
|
__publicField(this, "main", new MainService(this));
|
|
7544
8007
|
__publicField(this, "components", new ComponentService(this));
|
|
@@ -13012,52 +13475,54 @@ const styles$4 = {
|
|
|
13012
13475
|
Footer,
|
|
13013
13476
|
Loading
|
|
13014
13477
|
};
|
|
13015
|
-
const ImageCard = memo(
|
|
13016
|
-
|
|
13017
|
-
|
|
13018
|
-
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
|
|
13022
|
-
|
|
13023
|
-
|
|
13024
|
-
|
|
13025
|
-
|
|
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
|
-
|
|
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
|
+
);
|
|
13061
13526
|
const UploadInput = memo((props) => {
|
|
13062
13527
|
var _a2;
|
|
13063
13528
|
const [{ inputId, labelId, size, severity, helpText, showInputOnly, field, fieldProps }, rest] = useFormikInput(props);
|
|
@@ -13656,7 +14121,7 @@ const initialFormValues = (fields, values) => {
|
|
|
13656
14121
|
};
|
|
13657
14122
|
const useAttachImagesToFormRevisionFields = (revision) => {
|
|
13658
14123
|
const { sdk } = useSDK();
|
|
13659
|
-
const attachments = useAppSelector(
|
|
14124
|
+
const attachments = useAppSelector(selectAttachmentsOfFormRevision((revision == null ? void 0 : revision.offline_id) ?? ""));
|
|
13660
14125
|
return useMemo(() => {
|
|
13661
14126
|
if (!revision || !attachments)
|
|
13662
14127
|
return revision;
|
|
@@ -13738,7 +14203,7 @@ const FormRenderer = memo(
|
|
|
13738
14203
|
const FormSubmissionViewer = memo(
|
|
13739
14204
|
forwardRef((props, ref) => {
|
|
13740
14205
|
const { submission, showFormDescription = false, showFormTitle = true } = props;
|
|
13741
|
-
const revision = useAppSelector(
|
|
14206
|
+
const revision = useAppSelector(selectUserFormRevision(submission.form_revision));
|
|
13742
14207
|
const { sdk } = useSDK();
|
|
13743
14208
|
if (!revision) {
|
|
13744
14209
|
throw new Error(
|
|
@@ -13753,7 +14218,7 @@ const FormSubmissionViewer = memo(
|
|
|
13753
14218
|
return formRevisionToSchema(revisionWithImages, { readonly: true });
|
|
13754
14219
|
}, [revisionWithImages]);
|
|
13755
14220
|
const submissionValuesWithAttachments = useMemo(() => {
|
|
13756
|
-
const attachments =
|
|
14221
|
+
const attachments = selectAttachmentsOfFormSubmission(submission.offline_id)(sdk.store.getState()) ?? [];
|
|
13757
14222
|
const downloadedAttachments = {};
|
|
13758
14223
|
for (const attachment of attachments) {
|
|
13759
14224
|
const promise = sdk.files.fetchFileFromUrl(attachment.file, attachment.file_sha1, attachment.file_name);
|
|
@@ -13931,16 +14396,13 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
13931
14396
|
const { submission, onSubmissionClick, compact, labelType, rowDecorator } = props;
|
|
13932
14397
|
const currentUser = useAppSelector(selectCurrentUser);
|
|
13933
14398
|
const createdBy = useAppSelector(selectUser("created_by" in submission ? submission.created_by : currentUser.id));
|
|
13934
|
-
const dateToUse =
|
|
13935
|
-
const formattedDateTime =
|
|
13936
|
-
|
|
13937
|
-
minute: "2-digit"
|
|
13938
|
-
}) : getLocalDateString(dateToUse);
|
|
13939
|
-
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));
|
|
13940
14402
|
if (!revision) {
|
|
13941
14403
|
throw new Error(`Could not find revision ${submission.form_revision} for submission ${submission.offline_id}.`);
|
|
13942
14404
|
}
|
|
13943
|
-
const latestRevisionNumber = (_a2 = useAppSelector(
|
|
14405
|
+
const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevisionOfForm(revision.form))) == null ? void 0 : _a2.revision;
|
|
13944
14406
|
const creatorProfileSrc = useFileSrc({
|
|
13945
14407
|
file: (createdBy == null ? void 0 : createdBy.profile.file) ?? null,
|
|
13946
14408
|
fileSha1: (createdBy == null ? void 0 : createdBy.profile.file_sha1) ?? null
|
|
@@ -13971,10 +14433,6 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
13971
14433
|
return row;
|
|
13972
14434
|
});
|
|
13973
14435
|
FormSubmissionBrowserEntry.displayName = "FormSubmissionBrowserEntry";
|
|
13974
|
-
const getCreatedAtOrSubmittedAtDate = (submission) => {
|
|
13975
|
-
const date = "created_at" in submission ? submission.created_at : submission.submitted_at;
|
|
13976
|
-
return new Date(date);
|
|
13977
|
-
};
|
|
13978
14436
|
const FormSubmissionBrowser = memo((props) => {
|
|
13979
14437
|
const {
|
|
13980
14438
|
formId: formId2,
|
|
@@ -13988,10 +14446,10 @@ const FormSubmissionBrowser = memo((props) => {
|
|
|
13988
14446
|
if (!!formId2 === !!propSubmissions) {
|
|
13989
14447
|
throw new Error("Either formId or submissions must be provided, but not both.");
|
|
13990
14448
|
}
|
|
13991
|
-
const submissions = useAppSelector(propSubmissions ? () => propSubmissions :
|
|
14449
|
+
const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectFormSubmissionsOfForm(formId2));
|
|
13992
14450
|
const sortedSubmissions = useMemo(
|
|
13993
14451
|
() => submissions == null ? void 0 : submissions.sort((a, b) => {
|
|
13994
|
-
return
|
|
14452
|
+
return a.submitted_at.localeCompare(b.submitted_at);
|
|
13995
14453
|
}),
|
|
13996
14454
|
[submissions]
|
|
13997
14455
|
);
|
|
@@ -14194,17 +14652,15 @@ const FieldActions = memo((props) => {
|
|
|
14194
14652
|
Action.key
|
|
14195
14653
|
)) }),
|
|
14196
14654
|
/* @__PURE__ */ jsx(Box, { display: forMobile(true, "block"), children: /* @__PURE__ */ jsx(
|
|
14197
|
-
|
|
14655
|
+
OvermapDropdownMenu,
|
|
14198
14656
|
{
|
|
14199
14657
|
trigger: /* @__PURE__ */ jsx(IconButton, { variant: "ghost", "aria-label": "Actions menu", children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiMore2Line" }) }),
|
|
14200
14658
|
items: actions.map((Action) => {
|
|
14201
14659
|
var _a2;
|
|
14202
14660
|
return {
|
|
14203
|
-
|
|
14204
|
-
|
|
14205
|
-
|
|
14206
|
-
] }, Action.key),
|
|
14207
|
-
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
|
|
14208
14664
|
};
|
|
14209
14665
|
})
|
|
14210
14666
|
}
|
|
@@ -14262,10 +14718,8 @@ const useFieldTypeItems = (onSelect = () => null) => {
|
|
|
14262
14718
|
const field = FieldTypeToClsMapping[identifier];
|
|
14263
14719
|
const Icon = field.Icon;
|
|
14264
14720
|
return {
|
|
14265
|
-
|
|
14266
|
-
|
|
14267
|
-
/* @__PURE__ */ jsx(Text$1, { children: field.fieldTypeName })
|
|
14268
|
-
] }, identifier),
|
|
14721
|
+
children: field.fieldTypeName,
|
|
14722
|
+
leftSlot: /* @__PURE__ */ jsx(Icon, {}),
|
|
14269
14723
|
value: identifier,
|
|
14270
14724
|
onSelect: () => {
|
|
14271
14725
|
onSelect(identifier);
|
|
@@ -14469,7 +14923,7 @@ const FieldBuilder = memo((props) => {
|
|
|
14469
14923
|
}
|
|
14470
14924
|
),
|
|
14471
14925
|
/* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "3", children: [
|
|
14472
|
-
/* @__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 }),
|
|
14473
14927
|
showPopoverInputs && /* @__PURE__ */ jsx(FieldSettingsPopover, { popoverInputs, hasError: popoverHasErrors })
|
|
14474
14928
|
] }),
|
|
14475
14929
|
resolvedImage && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -14830,7 +15284,7 @@ const FieldSectionWithActions = memo((props) => {
|
|
|
14830
15284
|
)),
|
|
14831
15285
|
droppableProvided.placeholder,
|
|
14832
15286
|
/* @__PURE__ */ jsx(
|
|
14833
|
-
|
|
15287
|
+
OvermapDropdownMenu,
|
|
14834
15288
|
{
|
|
14835
15289
|
trigger: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", children: [
|
|
14836
15290
|
/* @__PURE__ */ jsx(RiIcon, { icon: "RiAddLine" }),
|
|
@@ -15266,6 +15720,8 @@ export {
|
|
|
15266
15720
|
IssuePriority,
|
|
15267
15721
|
IssueService,
|
|
15268
15722
|
IssueStatus,
|
|
15723
|
+
IssueUpdateChange,
|
|
15724
|
+
IssueUpdateService,
|
|
15269
15725
|
LicenseLevel,
|
|
15270
15726
|
LicenseService,
|
|
15271
15727
|
LicenseStatus,
|
|
@@ -15311,6 +15767,7 @@ export {
|
|
|
15311
15767
|
VerificationCodeType,
|
|
15312
15768
|
WorkspaceService,
|
|
15313
15769
|
YELLOW,
|
|
15770
|
+
_selectLatestFormRevision,
|
|
15314
15771
|
_setLatestRetryTime,
|
|
15315
15772
|
acceptProjectInvite,
|
|
15316
15773
|
addActiveProjectFormSubmissionsCount,
|
|
@@ -15326,9 +15783,23 @@ export {
|
|
|
15326
15783
|
addDocuments,
|
|
15327
15784
|
addEmailDomain,
|
|
15328
15785
|
addFavouriteProjectId,
|
|
15786
|
+
addForm,
|
|
15787
|
+
addFormRevision,
|
|
15788
|
+
addFormRevisionAttachment,
|
|
15789
|
+
addFormRevisionAttachments,
|
|
15790
|
+
addFormRevisions,
|
|
15791
|
+
addFormSubmission,
|
|
15792
|
+
addFormSubmissionAttachment,
|
|
15793
|
+
addFormSubmissionAttachments,
|
|
15794
|
+
addFormSubmissions,
|
|
15795
|
+
addForms,
|
|
15329
15796
|
addIssue,
|
|
15330
15797
|
addIssueAttachment,
|
|
15331
15798
|
addIssueAttachments,
|
|
15799
|
+
addIssueComment,
|
|
15800
|
+
addIssueComments,
|
|
15801
|
+
addIssueUpdate,
|
|
15802
|
+
addIssueUpdates,
|
|
15332
15803
|
addLicenses,
|
|
15333
15804
|
addOrReplaceCategories,
|
|
15334
15805
|
addOrReplaceIssueComment,
|
|
@@ -15342,13 +15813,6 @@ export {
|
|
|
15342
15813
|
addStageCompletions,
|
|
15343
15814
|
addStages,
|
|
15344
15815
|
addToRecentIssues,
|
|
15345
|
-
addUserForm,
|
|
15346
|
-
addUserFormRevision,
|
|
15347
|
-
addUserFormRevisionAttachment,
|
|
15348
|
-
addUserFormRevisions,
|
|
15349
|
-
addUserFormSubmissionAttachment,
|
|
15350
|
-
addUserFormSubmissions,
|
|
15351
|
-
addUserForms,
|
|
15352
15816
|
addUsers,
|
|
15353
15817
|
addWorkspace,
|
|
15354
15818
|
areArraysEqual,
|
|
@@ -15379,12 +15843,16 @@ export {
|
|
|
15379
15843
|
defaultBadgeColor,
|
|
15380
15844
|
defaultStore,
|
|
15381
15845
|
deleteComponentType,
|
|
15846
|
+
deleteForm,
|
|
15847
|
+
deleteFormRevision,
|
|
15848
|
+
deleteFormRevisionAttachment,
|
|
15849
|
+
deleteFormRevisionAttachments,
|
|
15850
|
+
deleteFormRevisions,
|
|
15851
|
+
deleteFormSubmission,
|
|
15852
|
+
deleteFormSubmissionAttachment,
|
|
15853
|
+
deleteFormSubmissionAttachments,
|
|
15854
|
+
deleteFormSubmissions,
|
|
15382
15855
|
deleteProject,
|
|
15383
|
-
deleteUserForm,
|
|
15384
|
-
deleteUserFormRevision,
|
|
15385
|
-
deleteUserFormRevisions,
|
|
15386
|
-
deleteUserFormSubmission,
|
|
15387
|
-
deleteUserFormSubmissions,
|
|
15388
15856
|
dequeue,
|
|
15389
15857
|
deserialize,
|
|
15390
15858
|
deserializeField,
|
|
@@ -15413,7 +15881,11 @@ export {
|
|
|
15413
15881
|
fileSlice,
|
|
15414
15882
|
fileToBlob,
|
|
15415
15883
|
flipCoordinates,
|
|
15884
|
+
formRevisionReducer,
|
|
15416
15885
|
formRevisionToSchema,
|
|
15886
|
+
formRevisionsSlice,
|
|
15887
|
+
formSubmissionReducer,
|
|
15888
|
+
formSubmissionSlice,
|
|
15417
15889
|
index as forms,
|
|
15418
15890
|
fullComponentMarkerSize,
|
|
15419
15891
|
generateBadgeColors,
|
|
@@ -15488,6 +15960,9 @@ export {
|
|
|
15488
15960
|
removeIssue,
|
|
15489
15961
|
removeIssueAttachment,
|
|
15490
15962
|
removeIssueComment,
|
|
15963
|
+
removeIssueComments,
|
|
15964
|
+
removeIssueUpdate,
|
|
15965
|
+
removeIssueUpdates,
|
|
15491
15966
|
removeOrganizationAccess,
|
|
15492
15967
|
removeProjectAccess,
|
|
15493
15968
|
removeProjectAccessesOfProject,
|
|
@@ -15533,6 +16008,8 @@ export {
|
|
|
15533
16008
|
selectAttachmentsOfComponentByType,
|
|
15534
16009
|
selectAttachmentsOfComponentType,
|
|
15535
16010
|
selectAttachmentsOfComponentTypeByType,
|
|
16011
|
+
selectAttachmentsOfFormRevision,
|
|
16012
|
+
selectAttachmentsOfFormSubmission,
|
|
15536
16013
|
selectAttachmentsOfIssue,
|
|
15537
16014
|
selectAttachmentsOfIssueByType,
|
|
15538
16015
|
selectAttachmentsOfProject,
|
|
@@ -15554,6 +16031,7 @@ export {
|
|
|
15554
16031
|
selectComponentTypeForm,
|
|
15555
16032
|
selectComponentTypeFromComponent,
|
|
15556
16033
|
selectComponentTypeFromComponents,
|
|
16034
|
+
selectComponentTypeStagesMapping,
|
|
15557
16035
|
selectComponentTypes,
|
|
15558
16036
|
selectComponentTypesByName,
|
|
15559
16037
|
selectComponentTypesFromIds,
|
|
@@ -15561,6 +16039,7 @@ export {
|
|
|
15561
16039
|
selectComponents,
|
|
15562
16040
|
selectComponentsByType,
|
|
15563
16041
|
selectComponentsFromComponentType,
|
|
16042
|
+
selectComponentsMapping,
|
|
15564
16043
|
selectCreateProjectType,
|
|
15565
16044
|
selectCurrentUser,
|
|
15566
16045
|
selectDeletedRequests,
|
|
@@ -15578,7 +16057,17 @@ export {
|
|
|
15578
16057
|
selectFavouriteProjects,
|
|
15579
16058
|
selectFileAttachmentsOfIssue,
|
|
15580
16059
|
selectFilteredUserForms,
|
|
15581
|
-
|
|
16060
|
+
selectFormRevisionMapping,
|
|
16061
|
+
selectFormRevisions,
|
|
16062
|
+
selectFormRevisionsOfForm,
|
|
16063
|
+
selectFormSubmission,
|
|
16064
|
+
selectFormSubmissionAttachmentsMapping,
|
|
16065
|
+
selectFormSubmissions,
|
|
16066
|
+
selectFormSubmissionsByComponents,
|
|
16067
|
+
selectFormSubmissionsMapping,
|
|
16068
|
+
selectFormSubmissionsOfComponent,
|
|
16069
|
+
selectFormSubmissionsOfForm,
|
|
16070
|
+
selectFormSubmissionsOfIssue,
|
|
15582
16071
|
selectHiddenCategoryCount,
|
|
15583
16072
|
selectHiddenComponentTypeIds,
|
|
15584
16073
|
selectIsFetchingInitialData,
|
|
@@ -15589,11 +16078,13 @@ export {
|
|
|
15589
16078
|
selectIssueAttachmentMapping,
|
|
15590
16079
|
selectIssueAttachments,
|
|
15591
16080
|
selectIssueMapping,
|
|
16081
|
+
selectIssueUpdateMapping,
|
|
16082
|
+
selectIssueUpdatesOfIssue,
|
|
15592
16083
|
selectIssues,
|
|
15593
|
-
|
|
16084
|
+
selectLatestFormRevisionByForm,
|
|
16085
|
+
selectLatestFormRevisionOfForm,
|
|
16086
|
+
selectLatestFormRevisionsOfComponentTypes,
|
|
15594
16087
|
selectLatestRetryTime,
|
|
15595
|
-
selectLatestRevisionByFormId,
|
|
15596
|
-
selectLatestRevisionsFromComponentTypeIds,
|
|
15597
16088
|
selectLicense,
|
|
15598
16089
|
selectLicenseForProject,
|
|
15599
16090
|
selectLicenses,
|
|
@@ -15631,8 +16122,6 @@ export {
|
|
|
15631
16122
|
selectRecentIssuesAsSearchResults,
|
|
15632
16123
|
selectRecentProjects,
|
|
15633
16124
|
selectRehydrated,
|
|
15634
|
-
selectRevisionAttachments,
|
|
15635
|
-
selectRevisionsForForm,
|
|
15636
16125
|
selectRootDocuments,
|
|
15637
16126
|
selectShowTooltips,
|
|
15638
16127
|
selectSortedEmailDomains,
|
|
@@ -15640,21 +16129,20 @@ export {
|
|
|
15640
16129
|
selectSortedOrganizationUsers,
|
|
15641
16130
|
selectSortedProjectUsers,
|
|
15642
16131
|
selectSortedProjects,
|
|
16132
|
+
selectStage,
|
|
15643
16133
|
selectStageFormIdsFromStageIds,
|
|
15644
16134
|
selectStageMapping,
|
|
15645
16135
|
selectStages,
|
|
15646
16136
|
selectStagesFromComponentType,
|
|
15647
16137
|
selectStagesFromComponentTypeIds,
|
|
15648
16138
|
selectStagesFromStageIds,
|
|
15649
|
-
selectSubmissionAttachments,
|
|
15650
|
-
selectSubmissionsForComponent,
|
|
15651
|
-
selectSubmissionsForForm,
|
|
15652
|
-
selectSubmissionsForIssue,
|
|
15653
16139
|
selectUploadUrl,
|
|
15654
16140
|
selectUsedColors,
|
|
15655
16141
|
selectUser,
|
|
15656
16142
|
selectUserForm,
|
|
15657
16143
|
selectUserFormMapping,
|
|
16144
|
+
selectUserFormRevision,
|
|
16145
|
+
selectUserFormRevisionAttachmentsMapping,
|
|
15658
16146
|
selectUsersAsMapping,
|
|
15659
16147
|
selectVisibleStatuses,
|
|
15660
16148
|
selectVisibleUserIds,
|
|
@@ -15680,11 +16168,20 @@ export {
|
|
|
15680
16168
|
setEnableClustering,
|
|
15681
16169
|
setEnableDuplicateIssues,
|
|
15682
16170
|
setEnablePlacementMode,
|
|
16171
|
+
setFormRevision,
|
|
16172
|
+
setFormRevisionAttachments,
|
|
16173
|
+
setFormRevisions,
|
|
16174
|
+
setFormSubmission,
|
|
16175
|
+
setFormSubmissionAttachments,
|
|
16176
|
+
setFormSubmissions,
|
|
16177
|
+
setForms,
|
|
15683
16178
|
setIsFetchingInitialData,
|
|
15684
16179
|
setIsImportingProjectFile,
|
|
15685
16180
|
setIsLoading,
|
|
15686
16181
|
setIssueAttachments,
|
|
16182
|
+
setIssueComment,
|
|
15687
16183
|
setIssueComments,
|
|
16184
|
+
setIssueUpdates,
|
|
15688
16185
|
setIssues,
|
|
15689
16186
|
setLicenses,
|
|
15690
16187
|
setLoggedIn,
|
|
@@ -15702,9 +16199,6 @@ export {
|
|
|
15702
16199
|
setTokens,
|
|
15703
16200
|
setTourStep,
|
|
15704
16201
|
setUploadUrl,
|
|
15705
|
-
setUserFormRevisionAttachments,
|
|
15706
|
-
setUserFormSubmissionAttachments,
|
|
15707
|
-
setUserFormSubmissions,
|
|
15708
16202
|
setUsers,
|
|
15709
16203
|
setVisibleStatuses,
|
|
15710
16204
|
setVisibleUserIds,
|
|
@@ -15728,11 +16222,12 @@ export {
|
|
|
15728
16222
|
updateComponentAttachment,
|
|
15729
16223
|
updateComponentTypeAttachment,
|
|
15730
16224
|
updateDocuments,
|
|
16225
|
+
updateFormSubmission,
|
|
16226
|
+
updateFormSubmissions,
|
|
15731
16227
|
updateIssue,
|
|
15732
16228
|
updateIssueAttachment,
|
|
15733
16229
|
updateLicense,
|
|
15734
16230
|
updateOrCreateProject,
|
|
15735
|
-
updateOrCreateUserFormSubmission,
|
|
15736
16231
|
updateOrganizationAccess,
|
|
15737
16232
|
updateProjectAccess,
|
|
15738
16233
|
updateProjectAttachment,
|