@overmap-ai/core 1.0.51-add-submitted-at-to-form-revisions.1 → 1.0.51-add-teams.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/forms/builder/constants.d.ts +1 -0
- package/dist/forms/builder/utils.d.ts +1 -1
- package/dist/forms/fields/QrField/QrField.d.ts +21 -0
- package/dist/forms/fields/QrField/QrInput.d.ts +10 -0
- package/dist/forms/fields/QrField/index.d.ts +2 -0
- package/dist/forms/fields/constants.d.ts +8 -0
- package/dist/forms/fields/index.d.ts +1 -0
- package/dist/forms/renderer/FormSubmissionBrowser/FormSubmissionBrowser.d.ts +5 -5
- package/dist/forms/renderer/FormSubmissionViewer/FormSubmissionViewer.d.ts +3 -3
- package/dist/forms/typings.d.ts +5 -2
- package/dist/overmap-core.js +1119 -457
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +1120 -459
- package/dist/overmap-core.umd.cjs.map +1 -1
- package/dist/sdk/sdk.d.ts +2 -1
- package/dist/sdk/services/TeamService.d.ts +12 -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 +4 -1
- package/dist/store/slices/documentSlice.d.ts +4 -1
- package/dist/store/slices/formRevisionSlice.d.ts +66 -0
- package/dist/store/slices/formSlice.d.ts +110 -0
- package/dist/store/slices/formSubmissionSlice.d.ts +47 -0
- package/dist/store/slices/index.d.ts +4 -1
- package/dist/store/slices/issueSlice.d.ts +4 -1
- package/dist/store/slices/projectFileSlice.d.ts +4 -1
- package/dist/store/slices/teamSlice.d.ts +19 -0
- package/dist/store/slices/utils.d.ts +1 -0
- package/dist/store/slices/workspaceSlice.d.ts +4 -1
- package/dist/store/store.d.ts +13 -4
- package/dist/style.css +5 -0
- package/dist/typings/files.d.ts +11 -1
- package/dist/typings/models/attachments.d.ts +8 -11
- package/dist/typings/models/base.d.ts +10 -0
- package/dist/typings/models/forms.d.ts +6 -11
- package/dist/typings/models/index.d.ts +1 -0
- package/dist/typings/models/teams.d.ts +10 -0
- package/dist/utils/file.d.ts +2 -0
- package/dist/utils/forms.d.ts +2 -0
- package/package.json +2 -1
- package/dist/store/slices/userFormSlice.d.ts +0 -145
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,
|
|
11
|
+
import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, Overlay, Button, Spinner, useViewportSize, ButtonGroup, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, 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";
|
|
@@ -27,6 +27,7 @@ import { useField, useFormikContext, useFormik, FormikProvider } from "formik";
|
|
|
27
27
|
import get from "lodash.get";
|
|
28
28
|
import Linkify from "linkify-react";
|
|
29
29
|
import { DragDropContext, Droppable, Draggable } from "@hello-pangea/dnd";
|
|
30
|
+
import QrScannerAPI from "qr-scanner";
|
|
30
31
|
import { read, utils } from "xlsx";
|
|
31
32
|
import { pdfjs, Document, Page } from "react-pdf";
|
|
32
33
|
import "react-pdf/dist/Page/AnnotationLayer.css";
|
|
@@ -677,15 +678,15 @@ const wrapMigration = (migrator) => (state) => {
|
|
|
677
678
|
};
|
|
678
679
|
const migrations = [initialVersioning, signOut, signOut, createOutboxState];
|
|
679
680
|
const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
|
|
680
|
-
const initialState$
|
|
681
|
+
const initialState$q = {
|
|
681
682
|
accessToken: "",
|
|
682
683
|
refreshToken: "",
|
|
683
684
|
isLoggedIn: false
|
|
684
685
|
};
|
|
685
686
|
const authSlice = createSlice({
|
|
686
687
|
name: "auth",
|
|
687
|
-
initialState: initialState$
|
|
688
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
688
|
+
initialState: initialState$q,
|
|
689
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$q)),
|
|
689
690
|
reducers: {
|
|
690
691
|
setTokens: (state, action) => {
|
|
691
692
|
state.accessToken = action.payload.accessToken;
|
|
@@ -850,6 +851,19 @@ function downloadInMemoryFile(filename, text) {
|
|
|
850
851
|
element.click();
|
|
851
852
|
document.body.removeChild(element);
|
|
852
853
|
}
|
|
854
|
+
const constructUploadedFilePayloads = async (files) => {
|
|
855
|
+
const filePayloads = {};
|
|
856
|
+
for (const file of files) {
|
|
857
|
+
const sha1 = await hashFile(file);
|
|
858
|
+
filePayloads[sha1] = {
|
|
859
|
+
sha1,
|
|
860
|
+
extension: file.name.split(".").pop() || "",
|
|
861
|
+
file_type: file.type,
|
|
862
|
+
size: file.size
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
return Object.values(filePayloads);
|
|
866
|
+
};
|
|
853
867
|
const fileToBlob = async (dataUrl) => {
|
|
854
868
|
return (await fetch(dataUrl)).blob();
|
|
855
869
|
};
|
|
@@ -1416,7 +1430,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
|
|
|
1416
1430
|
return getLocalDateString(date);
|
|
1417
1431
|
return relative.format(days, "days");
|
|
1418
1432
|
});
|
|
1419
|
-
const initialState$
|
|
1433
|
+
const initialState$p = {
|
|
1420
1434
|
categories: {},
|
|
1421
1435
|
usedCategoryColors: [],
|
|
1422
1436
|
categoryVisibility: {
|
|
@@ -1426,8 +1440,8 @@ const initialState$m = {
|
|
|
1426
1440
|
};
|
|
1427
1441
|
const categorySlice = createSlice({
|
|
1428
1442
|
name: "categories",
|
|
1429
|
-
initialState: initialState$
|
|
1430
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1443
|
+
initialState: initialState$p,
|
|
1444
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$p)),
|
|
1431
1445
|
reducers: {
|
|
1432
1446
|
setCategories: (state, action) => {
|
|
1433
1447
|
if (!Array.isArray(action.payload))
|
|
@@ -1596,14 +1610,14 @@ function removeAttachments(state, action) {
|
|
|
1596
1610
|
delete state.attachments[attachmentId];
|
|
1597
1611
|
}
|
|
1598
1612
|
}
|
|
1599
|
-
const initialState$
|
|
1613
|
+
const initialState$o = {
|
|
1600
1614
|
components: {},
|
|
1601
1615
|
attachments: {}
|
|
1602
1616
|
};
|
|
1603
1617
|
const componentSlice = createSlice({
|
|
1604
1618
|
name: "components",
|
|
1605
|
-
initialState: initialState$
|
|
1606
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1619
|
+
initialState: initialState$o,
|
|
1620
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$o)),
|
|
1607
1621
|
reducers: {
|
|
1608
1622
|
addComponent: (state, action) => {
|
|
1609
1623
|
state.components[action.payload.offline_id] = action.payload;
|
|
@@ -1759,13 +1773,13 @@ const {
|
|
|
1759
1773
|
removeAllComponentsOfType
|
|
1760
1774
|
} = componentSlice.actions;
|
|
1761
1775
|
const componentReducer = componentSlice.reducer;
|
|
1762
|
-
const initialState$
|
|
1776
|
+
const initialState$n = {
|
|
1763
1777
|
completionsByComponentId: {}
|
|
1764
1778
|
};
|
|
1765
1779
|
const componentStageCompletionSlice = createSlice({
|
|
1766
1780
|
name: "componentStageCompletions",
|
|
1767
|
-
initialState: initialState$
|
|
1768
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1781
|
+
initialState: initialState$n,
|
|
1782
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
|
|
1769
1783
|
reducers: {
|
|
1770
1784
|
addStageCompletion: (state, action) => {
|
|
1771
1785
|
let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
|
|
@@ -1816,13 +1830,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
|
|
|
1816
1830
|
return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
|
|
1817
1831
|
};
|
|
1818
1832
|
const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
|
|
1819
|
-
const initialState$
|
|
1833
|
+
const initialState$m = {
|
|
1820
1834
|
stages: {}
|
|
1821
1835
|
};
|
|
1822
1836
|
const componentStageSlice = createSlice({
|
|
1823
1837
|
name: "componentStages",
|
|
1824
|
-
initialState: initialState$
|
|
1825
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1838
|
+
initialState: initialState$m,
|
|
1839
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
|
|
1826
1840
|
reducers: {
|
|
1827
1841
|
addStages: (state, action) => {
|
|
1828
1842
|
Object.assign(state.stages, toOfflineIdRecord(action.payload));
|
|
@@ -1932,15 +1946,15 @@ const selectStageFormIdsFromStageIds = restructureCreateSelectorWithArgs(
|
|
|
1932
1946
|
);
|
|
1933
1947
|
const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
|
|
1934
1948
|
const componentStageReducer = componentStageSlice.reducer;
|
|
1935
|
-
const initialState$
|
|
1949
|
+
const initialState$l = {
|
|
1936
1950
|
componentTypes: {},
|
|
1937
1951
|
hiddenComponentTypeIds: {},
|
|
1938
1952
|
attachments: {}
|
|
1939
1953
|
};
|
|
1940
1954
|
const componentTypeSlice = createSlice({
|
|
1941
1955
|
name: "componentTypes",
|
|
1942
|
-
initialState: initialState$
|
|
1943
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
1956
|
+
initialState: initialState$l,
|
|
1957
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
|
|
1944
1958
|
reducers: {
|
|
1945
1959
|
addComponentType: (state, action) => {
|
|
1946
1960
|
state.componentTypes[action.payload.offline_id] = action.payload;
|
|
@@ -2051,13 +2065,13 @@ const {
|
|
|
2051
2065
|
deleteComponentType
|
|
2052
2066
|
} = componentTypeSlice.actions;
|
|
2053
2067
|
const componentTypeReducer = componentTypeSlice.reducer;
|
|
2054
|
-
const initialState$
|
|
2068
|
+
const initialState$k = {
|
|
2055
2069
|
workspaces: {},
|
|
2056
2070
|
activeWorkspaceId: null
|
|
2057
2071
|
};
|
|
2058
2072
|
const workspaceSlice = createSlice({
|
|
2059
2073
|
name: "workspace",
|
|
2060
|
-
initialState: initialState$
|
|
2074
|
+
initialState: initialState$k,
|
|
2061
2075
|
// The `reducers` field lets us define reducers and generate associated actions
|
|
2062
2076
|
reducers: {
|
|
2063
2077
|
setWorkspaces: (state, action) => {
|
|
@@ -2114,7 +2128,7 @@ const selectPermittedWorkspaceIds = createSelector(
|
|
|
2114
2128
|
);
|
|
2115
2129
|
const workspaceReducer = workspaceSlice.reducer;
|
|
2116
2130
|
const maxRecentIssues = 10;
|
|
2117
|
-
const initialState$
|
|
2131
|
+
const initialState$j = {
|
|
2118
2132
|
issues: {},
|
|
2119
2133
|
attachments: {},
|
|
2120
2134
|
comments: {},
|
|
@@ -2126,9 +2140,9 @@ const initialState$g = {
|
|
|
2126
2140
|
};
|
|
2127
2141
|
const issueSlice = createSlice({
|
|
2128
2142
|
name: "issues",
|
|
2129
|
-
initialState: initialState$
|
|
2143
|
+
initialState: initialState$j,
|
|
2130
2144
|
extraReducers: (builder) => builder.addCase("RESET", (state) => {
|
|
2131
|
-
Object.assign(state, initialState$
|
|
2145
|
+
Object.assign(state, initialState$j);
|
|
2132
2146
|
}),
|
|
2133
2147
|
reducers: {
|
|
2134
2148
|
setIssues: (state, action) => {
|
|
@@ -2536,15 +2550,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
|
|
|
2536
2550
|
}
|
|
2537
2551
|
);
|
|
2538
2552
|
const issueReducer = issueSlice.reducer;
|
|
2539
|
-
const initialState$
|
|
2553
|
+
const initialState$i = {
|
|
2540
2554
|
s3Urls: {}
|
|
2541
2555
|
};
|
|
2542
2556
|
const msPerHour = 1e3 * 60 * 60;
|
|
2543
2557
|
const msPerWeek = msPerHour * 24 * 7;
|
|
2544
2558
|
const fileSlice = createSlice({
|
|
2545
2559
|
name: "file",
|
|
2546
|
-
initialState: initialState$
|
|
2547
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2560
|
+
initialState: initialState$i,
|
|
2561
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
|
|
2548
2562
|
reducers: {
|
|
2549
2563
|
setUploadUrl: (state, action) => {
|
|
2550
2564
|
const { url, fields, sha1 } = action.payload;
|
|
@@ -2571,7 +2585,7 @@ const selectUploadUrl = (sha1) => (state) => {
|
|
|
2571
2585
|
return url;
|
|
2572
2586
|
};
|
|
2573
2587
|
const fileReducer = fileSlice.reducer;
|
|
2574
|
-
const initialState$
|
|
2588
|
+
const initialState$h = {
|
|
2575
2589
|
// TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
|
|
2576
2590
|
mapStyle: MapStyle.SATELLITE,
|
|
2577
2591
|
showTooltips: false,
|
|
@@ -2579,8 +2593,8 @@ const initialState$e = {
|
|
|
2579
2593
|
};
|
|
2580
2594
|
const mapSlice = createSlice({
|
|
2581
2595
|
name: "map",
|
|
2582
|
-
initialState: initialState$
|
|
2583
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2596
|
+
initialState: initialState$h,
|
|
2597
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
|
|
2584
2598
|
reducers: {
|
|
2585
2599
|
setMapStyle: (state, action) => {
|
|
2586
2600
|
state.mapStyle = action.payload;
|
|
@@ -2649,7 +2663,7 @@ var LicenseStatus = /* @__PURE__ */ ((LicenseStatus2) => {
|
|
|
2649
2663
|
LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
|
|
2650
2664
|
return LicenseStatus2;
|
|
2651
2665
|
})(LicenseStatus || {});
|
|
2652
|
-
const initialState$
|
|
2666
|
+
const initialState$g = {
|
|
2653
2667
|
users: {},
|
|
2654
2668
|
currentUser: {
|
|
2655
2669
|
id: 0,
|
|
@@ -2660,8 +2674,8 @@ const initialState$d = {
|
|
|
2660
2674
|
};
|
|
2661
2675
|
const userSlice = createSlice({
|
|
2662
2676
|
name: "users",
|
|
2663
|
-
initialState: initialState$
|
|
2664
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2677
|
+
initialState: initialState$g,
|
|
2678
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
|
|
2665
2679
|
reducers: {
|
|
2666
2680
|
setUsers: (state, action) => {
|
|
2667
2681
|
const usersMapping = {};
|
|
@@ -2723,13 +2737,13 @@ const selectUser = (userId) => (state) => {
|
|
|
2723
2737
|
const selectUsersAsMapping = (state) => state.userReducer.users;
|
|
2724
2738
|
const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
|
|
2725
2739
|
const userReducer = userSlice.reducer;
|
|
2726
|
-
const initialState$
|
|
2740
|
+
const initialState$f = {
|
|
2727
2741
|
organizationAccesses: {}
|
|
2728
2742
|
};
|
|
2729
2743
|
const organizationAccessSlice = createSlice({
|
|
2730
2744
|
name: "organizationAccess",
|
|
2731
|
-
initialState: initialState$
|
|
2732
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2745
|
+
initialState: initialState$f,
|
|
2746
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
|
|
2733
2747
|
reducers: {
|
|
2734
2748
|
setOrganizationAccesses: (state, action) => {
|
|
2735
2749
|
if (!Array.isArray(action.payload))
|
|
@@ -2792,13 +2806,13 @@ const selectOrganizationAccessUserMapping = (state) => {
|
|
|
2792
2806
|
return organizationAccesses;
|
|
2793
2807
|
};
|
|
2794
2808
|
const organizationAccessReducer = organizationAccessSlice.reducer;
|
|
2795
|
-
const initialState$
|
|
2809
|
+
const initialState$e = {
|
|
2796
2810
|
licenses: {}
|
|
2797
2811
|
};
|
|
2798
2812
|
const licenseSlice = createSlice({
|
|
2799
2813
|
name: "license",
|
|
2800
|
-
initialState: initialState$
|
|
2801
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2814
|
+
initialState: initialState$e,
|
|
2815
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
|
|
2802
2816
|
reducers: {
|
|
2803
2817
|
setLicenses: (state, action) => {
|
|
2804
2818
|
if (!Array.isArray(action.payload))
|
|
@@ -2843,13 +2857,13 @@ const selectLicensesForProjectsMapping = createSelector(
|
|
|
2843
2857
|
(licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
|
|
2844
2858
|
);
|
|
2845
2859
|
const licenseReducer = licenseSlice.reducer;
|
|
2846
|
-
const initialState$
|
|
2860
|
+
const initialState$d = {
|
|
2847
2861
|
projectAccesses: {}
|
|
2848
2862
|
};
|
|
2849
2863
|
const projectAccessSlice = createSlice({
|
|
2850
2864
|
name: "projectAccess",
|
|
2851
|
-
initialState: initialState$
|
|
2852
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
2865
|
+
initialState: initialState$d,
|
|
2866
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
|
|
2853
2867
|
reducers: {
|
|
2854
2868
|
setProjectAccesses: (state, action) => {
|
|
2855
2869
|
if (!Array.isArray(action.payload))
|
|
@@ -2917,7 +2931,7 @@ const selectProjectAccessUserMapping = (state) => {
|
|
|
2917
2931
|
return projectAccesses;
|
|
2918
2932
|
};
|
|
2919
2933
|
const projectAccessReducer = projectAccessSlice.reducer;
|
|
2920
|
-
const initialState$
|
|
2934
|
+
const initialState$c = {
|
|
2921
2935
|
projects: {},
|
|
2922
2936
|
activeProjectId: null,
|
|
2923
2937
|
recentProjectIds: [],
|
|
@@ -2927,7 +2941,7 @@ const initialState$9 = {
|
|
|
2927
2941
|
};
|
|
2928
2942
|
const projectSlice = createSlice({
|
|
2929
2943
|
name: "projects",
|
|
2930
|
-
initialState: initialState$
|
|
2944
|
+
initialState: initialState$c,
|
|
2931
2945
|
reducers: {
|
|
2932
2946
|
setProjects: (state, action) => {
|
|
2933
2947
|
const projectsMap = {};
|
|
@@ -3114,14 +3128,14 @@ const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(
|
|
|
3114
3128
|
}
|
|
3115
3129
|
)
|
|
3116
3130
|
);
|
|
3117
|
-
const initialState$
|
|
3131
|
+
const initialState$b = {
|
|
3118
3132
|
organizations: {},
|
|
3119
3133
|
activeOrganizationId: null
|
|
3120
3134
|
};
|
|
3121
3135
|
const organizationSlice = createSlice({
|
|
3122
3136
|
name: "organizations",
|
|
3123
|
-
initialState: initialState$
|
|
3124
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3137
|
+
initialState: initialState$b,
|
|
3138
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
|
|
3125
3139
|
reducers: {
|
|
3126
3140
|
setOrganizations: (state, action) => {
|
|
3127
3141
|
for (const org of action.payload) {
|
|
@@ -3240,14 +3254,14 @@ const createOfflineAction = (request2, baseUrl) => {
|
|
|
3240
3254
|
}
|
|
3241
3255
|
};
|
|
3242
3256
|
};
|
|
3243
|
-
const initialState$
|
|
3257
|
+
const initialState$a = {
|
|
3244
3258
|
deletedRequests: [],
|
|
3245
3259
|
latestRetryTime: 0
|
|
3246
3260
|
};
|
|
3247
3261
|
const outboxSlice = createSlice({
|
|
3248
3262
|
name: "outbox",
|
|
3249
|
-
initialState: initialState$
|
|
3250
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3263
|
+
initialState: initialState$a,
|
|
3264
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
|
|
3251
3265
|
reducers: {
|
|
3252
3266
|
// enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
|
|
3253
3267
|
// Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
|
|
@@ -3279,7 +3293,7 @@ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
|
|
|
3279
3293
|
const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
|
|
3280
3294
|
const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
|
|
3281
3295
|
const outboxReducer = outboxSlice.reducer;
|
|
3282
|
-
const initialState$
|
|
3296
|
+
const initialState$9 = {
|
|
3283
3297
|
projectFiles: {},
|
|
3284
3298
|
activeProjectFileId: null,
|
|
3285
3299
|
isImportingProjectFile: false,
|
|
@@ -3287,8 +3301,8 @@ const initialState$6 = {
|
|
|
3287
3301
|
};
|
|
3288
3302
|
const projectFileSlice = createSlice({
|
|
3289
3303
|
name: "projectFiles",
|
|
3290
|
-
initialState: initialState$
|
|
3291
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3304
|
+
initialState: initialState$9,
|
|
3305
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
|
|
3292
3306
|
reducers: {
|
|
3293
3307
|
addOrReplaceProjectFiles: (state, action) => {
|
|
3294
3308
|
for (let fileObj of action.payload) {
|
|
@@ -3389,12 +3403,12 @@ const selectProjectFiles = createSelector(
|
|
|
3389
3403
|
const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
|
|
3390
3404
|
const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
|
|
3391
3405
|
const projectFileReducer = projectFileSlice.reducer;
|
|
3392
|
-
const initialState$
|
|
3406
|
+
const initialState$8 = {
|
|
3393
3407
|
isRehydrated: false
|
|
3394
3408
|
};
|
|
3395
3409
|
const rehydratedSlice = createSlice({
|
|
3396
3410
|
name: "rehydrated",
|
|
3397
|
-
initialState: initialState$
|
|
3411
|
+
initialState: initialState$8,
|
|
3398
3412
|
// The `reducers` field lets us define reducers and generate associated actions
|
|
3399
3413
|
reducers: {
|
|
3400
3414
|
setRehydrated: (state, action) => {
|
|
@@ -3404,7 +3418,7 @@ const rehydratedSlice = createSlice({
|
|
|
3404
3418
|
});
|
|
3405
3419
|
const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
|
|
3406
3420
|
const rehydratedReducer = rehydratedSlice.reducer;
|
|
3407
|
-
const initialState$
|
|
3421
|
+
const initialState$7 = {
|
|
3408
3422
|
useIssueTemplate: false,
|
|
3409
3423
|
placementMode: false,
|
|
3410
3424
|
enableClustering: false,
|
|
@@ -3421,8 +3435,8 @@ const initialState$4 = {
|
|
|
3421
3435
|
};
|
|
3422
3436
|
const settingSlice = createSlice({
|
|
3423
3437
|
name: "settings",
|
|
3424
|
-
initialState: initialState$
|
|
3425
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$
|
|
3438
|
+
initialState: initialState$7,
|
|
3439
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
|
|
3426
3440
|
reducers: {
|
|
3427
3441
|
setEnableDuplicateIssues: (state, action) => {
|
|
3428
3442
|
state.useIssueTemplate = action.payload;
|
|
@@ -3468,146 +3482,231 @@ const selectAppearance = (state) => state.settingReducer.appearance;
|
|
|
3468
3482
|
const settingReducer = settingSlice.reducer;
|
|
3469
3483
|
const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
|
|
3470
3484
|
const selectIsLoading = (state) => state.settingReducer.isLoading;
|
|
3471
|
-
const
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
if (
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
return;
|
|
3483
|
-
}
|
|
3484
|
-
if (revision.revision === "Pending") {
|
|
3485
|
-
if (preferPending) {
|
|
3486
|
-
LATEST_REVISION_CACHE[revision.form] = revision;
|
|
3487
|
-
}
|
|
3488
|
-
return;
|
|
3489
|
-
}
|
|
3490
|
-
const cachedRevision = (_a2 = LATEST_REVISION_CACHE[revision.form]) == null ? void 0 : _a2.revision;
|
|
3491
|
-
if (revision.revision > (typeof cachedRevision === "number" ? cachedRevision : -1)) {
|
|
3492
|
-
LATEST_REVISION_CACHE[revision.form] = revision;
|
|
3485
|
+
const formRevisionSortFn = (formRevisionA, formRevisionB) => {
|
|
3486
|
+
const revisionA = formRevisionA.revision;
|
|
3487
|
+
const revisionB = formRevisionB.revision;
|
|
3488
|
+
if (revisionA === "Pending" && revisionB === "Pending") {
|
|
3489
|
+
return formRevisionA.submitted_at < formRevisionB.submitted_at ? -1 : 1;
|
|
3490
|
+
} else if (revisionA === "Pending") {
|
|
3491
|
+
return 1;
|
|
3492
|
+
} else if (revisionB === "Pending") {
|
|
3493
|
+
return -1;
|
|
3494
|
+
} else {
|
|
3495
|
+
return revisionA < revisionB ? -1 : 1;
|
|
3493
3496
|
}
|
|
3494
|
-
}
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
}
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
revisionAttachments: {}
|
|
3504
|
-
};
|
|
3505
|
-
const userFormSlice = createSlice({
|
|
3506
|
-
name: "userForms",
|
|
3507
|
-
initialState: initialState$3,
|
|
3508
|
-
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
|
|
3497
|
+
};
|
|
3498
|
+
const initialState$6 = {
|
|
3499
|
+
formRevisions: {},
|
|
3500
|
+
attachments: {}
|
|
3501
|
+
};
|
|
3502
|
+
const formRevisionsSlice = createSlice({
|
|
3503
|
+
name: "formRevisions",
|
|
3504
|
+
initialState: initialState$6,
|
|
3505
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
|
|
3509
3506
|
reducers: {
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
action.payload.
|
|
3513
|
-
state.userForms[userForm.offline_id] = userForm;
|
|
3514
|
-
});
|
|
3515
|
-
},
|
|
3516
|
-
addUserForm: (state, action) => {
|
|
3517
|
-
state.userForms[action.payload.offline_id] = action.payload;
|
|
3507
|
+
// revision related actions
|
|
3508
|
+
setFormRevision: (state, action) => {
|
|
3509
|
+
state.formRevisions[action.payload.offline_id] = action.payload;
|
|
3518
3510
|
},
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
addUserFormRevisions: (state, action) => {
|
|
3525
|
-
action.payload.forEach((userFormRevision) => {
|
|
3526
|
-
state.revisions[userFormRevision.offline_id] = userFormRevision;
|
|
3527
|
-
considerCachingRevision(userFormRevision);
|
|
3528
|
-
});
|
|
3529
|
-
},
|
|
3530
|
-
addUserFormRevision: (state, action) => {
|
|
3531
|
-
state.revisions[action.payload.offline_id] = action.payload;
|
|
3532
|
-
considerCachingRevision(action.payload);
|
|
3511
|
+
setFormRevisions: (state, action) => {
|
|
3512
|
+
state.formRevisions = {};
|
|
3513
|
+
for (const revision of action.payload) {
|
|
3514
|
+
state.formRevisions[revision.offline_id] = revision;
|
|
3515
|
+
}
|
|
3533
3516
|
},
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3517
|
+
addFormRevision: (state, action) => {
|
|
3518
|
+
if (state.formRevisions[action.payload.offline_id] !== void 0) {
|
|
3519
|
+
throw new Error(`Revision with offline_id ${action.payload.offline_id} already exists`);
|
|
3520
|
+
}
|
|
3521
|
+
state.formRevisions[action.payload.offline_id] = action.payload;
|
|
3537
3522
|
},
|
|
3538
|
-
|
|
3523
|
+
addFormRevisions: (state, action) => {
|
|
3539
3524
|
for (const userFormRevision of action.payload) {
|
|
3540
|
-
|
|
3541
|
-
|
|
3525
|
+
if (state.formRevisions[userFormRevision.offline_id] !== void 0) {
|
|
3526
|
+
throw new Error(`Revision with offline_id ${userFormRevision.offline_id} already exists`);
|
|
3527
|
+
}
|
|
3542
3528
|
}
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
state.submissions[action.payload.offline_id] = action.payload;
|
|
3546
|
-
},
|
|
3547
|
-
addUserFormSubmissionAttachment: (state, action) => {
|
|
3548
|
-
const submissionId = action.payload.submission;
|
|
3549
|
-
const submissionAttachments = state.submissionAttachments[submissionId];
|
|
3550
|
-
if (submissionAttachments) {
|
|
3551
|
-
submissionAttachments.push(action.payload);
|
|
3552
|
-
} else {
|
|
3553
|
-
state.submissionAttachments[submissionId] = [action.payload];
|
|
3529
|
+
for (const userFormRevision of action.payload) {
|
|
3530
|
+
state.formRevisions[userFormRevision.offline_id] = userFormRevision;
|
|
3554
3531
|
}
|
|
3555
3532
|
},
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
revisionAttachments.push(action.payload);
|
|
3561
|
-
} else {
|
|
3562
|
-
state.revisionAttachments[revisionId] = [action.payload];
|
|
3533
|
+
// UserFormRevisions do not get updated
|
|
3534
|
+
deleteFormRevision: (state, action) => {
|
|
3535
|
+
if (state.formRevisions[action.payload] === void 0) {
|
|
3536
|
+
throw new Error(`Revision with offline_id ${action.payload} does not exist`);
|
|
3563
3537
|
}
|
|
3538
|
+
delete state.formRevisions[action.payload];
|
|
3564
3539
|
},
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
const submissionAttachments = state.submissionAttachments[submissionId];
|
|
3570
|
-
if (submissionAttachments) {
|
|
3571
|
-
submissionAttachments.push(attachment);
|
|
3572
|
-
} else {
|
|
3573
|
-
state.submissionAttachments[submissionId] = [attachment];
|
|
3540
|
+
deleteFormRevisions: (state, action) => {
|
|
3541
|
+
for (const offlineId of action.payload) {
|
|
3542
|
+
if (state.formRevisions[offlineId] === void 0) {
|
|
3543
|
+
throw new Error(`Revision with offline_id ${offlineId} does not exist`);
|
|
3574
3544
|
}
|
|
3575
3545
|
}
|
|
3546
|
+
for (const offlineId of action.payload) {
|
|
3547
|
+
delete state.formRevisions[offlineId];
|
|
3548
|
+
}
|
|
3576
3549
|
},
|
|
3577
|
-
|
|
3578
|
-
|
|
3550
|
+
// attachment related actions
|
|
3551
|
+
setFormRevisionAttachments: (state, action) => {
|
|
3552
|
+
state.attachments = {};
|
|
3579
3553
|
for (const attachment of action.payload) {
|
|
3580
|
-
|
|
3581
|
-
const revisionAttachments = state.revisionAttachments[revisionId];
|
|
3582
|
-
if (revisionAttachments) {
|
|
3583
|
-
revisionAttachments.push(attachment);
|
|
3584
|
-
} else {
|
|
3585
|
-
state.revisionAttachments[revisionId] = [attachment];
|
|
3586
|
-
}
|
|
3554
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3587
3555
|
}
|
|
3588
3556
|
},
|
|
3589
|
-
|
|
3590
|
-
|
|
3557
|
+
addFormRevisionAttachment: (state, action) => {
|
|
3558
|
+
if (state.attachments[action.payload.offline_id] !== void 0) {
|
|
3559
|
+
throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
|
|
3560
|
+
}
|
|
3561
|
+
state.attachments[action.payload.offline_id] = action.payload;
|
|
3591
3562
|
},
|
|
3592
|
-
|
|
3593
|
-
for (const
|
|
3594
|
-
|
|
3563
|
+
addFormRevisionAttachments: (state, action) => {
|
|
3564
|
+
for (const attachment of action.payload) {
|
|
3565
|
+
if (state.attachments[attachment.offline_id] !== void 0) {
|
|
3566
|
+
throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
|
|
3567
|
+
}
|
|
3568
|
+
}
|
|
3569
|
+
for (const attachment of action.payload) {
|
|
3570
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3595
3571
|
}
|
|
3596
3572
|
},
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
|
|
3573
|
+
deleteFormRevisionAttachment: (state, action) => {
|
|
3574
|
+
if (state.attachments[action.payload] === void 0) {
|
|
3575
|
+
throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
|
|
3600
3576
|
}
|
|
3577
|
+
delete state.attachments[action.payload];
|
|
3601
3578
|
},
|
|
3602
|
-
|
|
3603
|
-
|
|
3604
|
-
|
|
3605
|
-
|
|
3579
|
+
deleteFormRevisionAttachments: (state, action) => {
|
|
3580
|
+
for (const offlineId of action.payload) {
|
|
3581
|
+
if (state.attachments[offlineId] === void 0) {
|
|
3582
|
+
throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3585
|
+
for (const offlineId of action.payload) {
|
|
3586
|
+
delete state.attachments[offlineId];
|
|
3587
|
+
}
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
});
|
|
3591
|
+
const {
|
|
3592
|
+
setFormRevision,
|
|
3593
|
+
setFormRevisions,
|
|
3594
|
+
addFormRevision,
|
|
3595
|
+
addFormRevisions,
|
|
3596
|
+
deleteFormRevision,
|
|
3597
|
+
deleteFormRevisions,
|
|
3598
|
+
setFormRevisionAttachments,
|
|
3599
|
+
addFormRevisionAttachment,
|
|
3600
|
+
addFormRevisionAttachments,
|
|
3601
|
+
deleteFormRevisionAttachment,
|
|
3602
|
+
deleteFormRevisionAttachments
|
|
3603
|
+
} = formRevisionsSlice.actions;
|
|
3604
|
+
const selectFormRevisionMapping = (state) => state.formRevisionReducer.formRevisions;
|
|
3605
|
+
const selectFormRevisions = createSelector(
|
|
3606
|
+
[selectFormRevisionMapping],
|
|
3607
|
+
(formRevisions) => Object.values(formRevisions)
|
|
3608
|
+
);
|
|
3609
|
+
const selectFormRevision = (formRevisionId) => (state) => {
|
|
3610
|
+
return state.formRevisionReducer.formRevisions[formRevisionId];
|
|
3611
|
+
};
|
|
3612
|
+
const _selectLatestFormRevision = (formRevisions, formId2) => {
|
|
3613
|
+
let ret = null;
|
|
3614
|
+
for (const candidate of Object.values(formRevisions)) {
|
|
3615
|
+
if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
|
|
3616
|
+
ret = candidate;
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
if (!ret) {
|
|
3620
|
+
throw new Error("No form revision found for form " + formId2);
|
|
3621
|
+
}
|
|
3622
|
+
return ret;
|
|
3623
|
+
};
|
|
3624
|
+
const selectLatestFormRevisionOfForm = restructureCreateSelectorWithArgs(
|
|
3625
|
+
createSelector([selectFormRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
|
|
3626
|
+
return revisions.filter((revision) => revision.form === formId2).sort(formRevisionSortFn).pop();
|
|
3627
|
+
})
|
|
3628
|
+
);
|
|
3629
|
+
const selectFormRevisionsOfForm = restructureCreateSelectorWithArgs(
|
|
3630
|
+
createSelector([selectFormRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
|
|
3631
|
+
return revisions.filter((revision) => {
|
|
3632
|
+
return revision.form === formId2;
|
|
3633
|
+
});
|
|
3634
|
+
})
|
|
3635
|
+
);
|
|
3636
|
+
const selectLatestFormRevisionsOfComponentTypes = restructureCreateSelectorWithArgs(
|
|
3637
|
+
createSelector(
|
|
3638
|
+
[
|
|
3639
|
+
(state) => state.formReducer.forms,
|
|
3640
|
+
selectFormRevisionMapping,
|
|
3641
|
+
(_state, componentTypeIds) => componentTypeIds
|
|
3642
|
+
],
|
|
3643
|
+
(userForms, revisions, componentTypeIds) => {
|
|
3644
|
+
const componentTypeIdsSet = new Set(componentTypeIds);
|
|
3645
|
+
const formsOfComponentTypes = {};
|
|
3646
|
+
const ret = {};
|
|
3647
|
+
for (const form of Object.values(userForms)) {
|
|
3648
|
+
if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
|
|
3649
|
+
formsOfComponentTypes[form.offline_id] = form;
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
for (const revision of Object.values(revisions)) {
|
|
3653
|
+
const form = formsOfComponentTypes[revision.form];
|
|
3654
|
+
if (!form || !form.component_type || ret[form.component_type] && formRevisionSortFn(ret[form.component_type], revision) > 0)
|
|
3655
|
+
continue;
|
|
3656
|
+
ret[form.component_type] = revision;
|
|
3657
|
+
}
|
|
3658
|
+
return ret;
|
|
3659
|
+
}
|
|
3660
|
+
)
|
|
3661
|
+
);
|
|
3662
|
+
const selectLatestFormRevisionByForm = createSelector([selectFormRevisionMapping], (revisions) => {
|
|
3663
|
+
const latestRevisions = {};
|
|
3664
|
+
for (const revision of Object.values(revisions)) {
|
|
3665
|
+
const formId2 = revision.form;
|
|
3666
|
+
const currentLatestRevision = latestRevisions[formId2];
|
|
3667
|
+
if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
|
|
3668
|
+
latestRevisions[formId2] = revision;
|
|
3669
|
+
}
|
|
3670
|
+
}
|
|
3671
|
+
return latestRevisions;
|
|
3672
|
+
});
|
|
3673
|
+
const selectUserFormRevisionAttachmentsMapping = (state) => {
|
|
3674
|
+
return state.formRevisionReducer.attachments;
|
|
3675
|
+
};
|
|
3676
|
+
const selectAttachmentsOfFormRevision = restructureCreateSelectorWithArgs(
|
|
3677
|
+
createSelector(
|
|
3678
|
+
[selectUserFormRevisionAttachmentsMapping, (_state, revisionId) => revisionId],
|
|
3679
|
+
(attachments, revisionId) => {
|
|
3680
|
+
return Object.values(attachments).filter((attachment) => attachment.revision === revisionId);
|
|
3681
|
+
}
|
|
3682
|
+
)
|
|
3683
|
+
);
|
|
3684
|
+
const formRevisionReducer = formRevisionsSlice.reducer;
|
|
3685
|
+
const initialState$5 = {
|
|
3686
|
+
forms: {}
|
|
3687
|
+
};
|
|
3688
|
+
const formSlice = createSlice({
|
|
3689
|
+
name: "forms",
|
|
3690
|
+
initialState: initialState$5,
|
|
3691
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$5)),
|
|
3692
|
+
reducers: {
|
|
3693
|
+
setForms: (state, action) => {
|
|
3694
|
+
state.forms = {};
|
|
3695
|
+
action.payload.forEach((userForm) => {
|
|
3696
|
+
state.forms[userForm.offline_id] = userForm;
|
|
3606
3697
|
});
|
|
3607
3698
|
},
|
|
3699
|
+
addForm: (state, action) => {
|
|
3700
|
+
state.forms[action.payload.offline_id] = action.payload;
|
|
3701
|
+
},
|
|
3702
|
+
addForms: (state, action) => {
|
|
3703
|
+
for (const userForm of action.payload) {
|
|
3704
|
+
state.forms[userForm.offline_id] = userForm;
|
|
3705
|
+
}
|
|
3706
|
+
},
|
|
3608
3707
|
favoriteForm: (state, action) => {
|
|
3609
3708
|
const { formId: formId2 } = action.payload;
|
|
3610
|
-
const form = state.
|
|
3709
|
+
const form = state.forms[formId2];
|
|
3611
3710
|
if (!form) {
|
|
3612
3711
|
throw new Error("No form exists with the id " + formId2);
|
|
3613
3712
|
}
|
|
@@ -3615,48 +3714,23 @@ const userFormSlice = createSlice({
|
|
|
3615
3714
|
},
|
|
3616
3715
|
unfavoriteForm: (state, action) => {
|
|
3617
3716
|
const { formId: formId2 } = action.payload;
|
|
3618
|
-
const form = state.
|
|
3717
|
+
const form = state.forms[formId2];
|
|
3619
3718
|
if (!form) {
|
|
3620
3719
|
throw new Error("No form exists with the id " + formId2);
|
|
3621
3720
|
}
|
|
3622
3721
|
form.favorite = false;
|
|
3623
3722
|
},
|
|
3624
|
-
|
|
3625
|
-
delete state.
|
|
3723
|
+
deleteForm: (state, action) => {
|
|
3724
|
+
delete state.forms[action.payload];
|
|
3626
3725
|
}
|
|
3627
3726
|
}
|
|
3628
3727
|
});
|
|
3629
|
-
const {
|
|
3630
|
-
|
|
3631
|
-
addUserForms,
|
|
3632
|
-
addUserFormRevisions,
|
|
3633
|
-
updateOrCreateUserFormSubmission,
|
|
3634
|
-
addUserFormSubmissions,
|
|
3635
|
-
deleteUserFormSubmission,
|
|
3636
|
-
deleteUserFormSubmissions,
|
|
3637
|
-
favoriteForm,
|
|
3638
|
-
unfavoriteForm,
|
|
3639
|
-
deleteUserForm,
|
|
3640
|
-
deleteUserFormRevision,
|
|
3641
|
-
deleteUserFormRevisions,
|
|
3642
|
-
setUserFormSubmissions,
|
|
3643
|
-
addUserFormRevision,
|
|
3644
|
-
addUserFormSubmissionAttachment,
|
|
3645
|
-
addUserFormRevisionAttachment,
|
|
3646
|
-
setUserFormSubmissionAttachments,
|
|
3647
|
-
setUserFormRevisionAttachments
|
|
3648
|
-
} = userFormSlice.actions;
|
|
3649
|
-
const selectSubmissionAttachments = (submissionId) => (state) => {
|
|
3650
|
-
return state.userFormReducer.submissionAttachments[submissionId] || [];
|
|
3651
|
-
};
|
|
3652
|
-
const selectRevisionAttachments = (revisionId) => (state) => {
|
|
3653
|
-
return state.userFormReducer.revisionAttachments[revisionId] || [];
|
|
3654
|
-
};
|
|
3655
|
-
const selectFilteredUserForms = restructureCreateSelectorWithArgs(
|
|
3728
|
+
const { setForms, addForm, addForms, favoriteForm, unfavoriteForm, deleteForm } = formSlice.actions;
|
|
3729
|
+
const selectFilteredForms = restructureCreateSelectorWithArgs(
|
|
3656
3730
|
createSelector(
|
|
3657
3731
|
[
|
|
3658
|
-
(state) => state.
|
|
3659
|
-
(state) => state.
|
|
3732
|
+
(state) => state.formReducer.forms,
|
|
3733
|
+
(state) => state.formRevisionReducer.formRevisions,
|
|
3660
3734
|
(_state, search) => search
|
|
3661
3735
|
],
|
|
3662
3736
|
(userForms, revisions, search) => {
|
|
@@ -3690,63 +3764,188 @@ const selectFilteredUserForms = restructureCreateSelectorWithArgs(
|
|
|
3690
3764
|
{ memoizeOptions: { equalityCheck: shallowEqual$1 } }
|
|
3691
3765
|
)
|
|
3692
3766
|
);
|
|
3693
|
-
const
|
|
3694
|
-
return state.
|
|
3767
|
+
const selectForm = (formId2) => (state) => {
|
|
3768
|
+
return state.formReducer.forms[formId2];
|
|
3695
3769
|
};
|
|
3696
|
-
const
|
|
3697
|
-
|
|
3698
|
-
for (const candidate of Object.values(revisions)) {
|
|
3699
|
-
if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
|
|
3700
|
-
ret = candidate;
|
|
3701
|
-
}
|
|
3702
|
-
}
|
|
3703
|
-
if (!ret) {
|
|
3704
|
-
throw new Error("No revision found for form " + formId2);
|
|
3705
|
-
}
|
|
3706
|
-
return ret;
|
|
3770
|
+
const selectFormMapping = (state) => {
|
|
3771
|
+
return state.formReducer.forms;
|
|
3707
3772
|
};
|
|
3708
|
-
const
|
|
3773
|
+
const selectFormOfComponentType = restructureCreateSelectorWithArgs(
|
|
3709
3774
|
createSelector(
|
|
3710
|
-
[
|
|
3711
|
-
(
|
|
3712
|
-
|
|
3713
|
-
throw new Error("formId is required");
|
|
3714
|
-
}
|
|
3715
|
-
return _selectLatestFormRevision(revisions, formId2);
|
|
3775
|
+
[selectFormMapping, (_state, componentTypeId) => componentTypeId],
|
|
3776
|
+
(userForms, componentTypeId) => {
|
|
3777
|
+
return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
|
|
3716
3778
|
}
|
|
3717
3779
|
)
|
|
3718
3780
|
);
|
|
3719
|
-
const
|
|
3720
|
-
return
|
|
3721
|
-
};
|
|
3722
|
-
const
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
const
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3781
|
+
const selectFormsCount = createSelector([selectFormMapping], (userForms) => {
|
|
3782
|
+
return Object.keys(userForms).length;
|
|
3783
|
+
});
|
|
3784
|
+
const selectGeneralFormCount = createSelector([selectFormMapping], (userForms) => {
|
|
3785
|
+
return Object.values(userForms).filter((form) => !form.component_type).length;
|
|
3786
|
+
});
|
|
3787
|
+
const formReducer = formSlice.reducer;
|
|
3788
|
+
const initialState$4 = {
|
|
3789
|
+
formSubmissions: {},
|
|
3790
|
+
attachments: {}
|
|
3791
|
+
};
|
|
3792
|
+
const formSubmissionSlice = createSlice({
|
|
3793
|
+
name: "formSubmissions",
|
|
3794
|
+
initialState: initialState$4,
|
|
3795
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
|
|
3796
|
+
reducers: {
|
|
3797
|
+
setFormSubmission: (state, action) => {
|
|
3798
|
+
state.formSubmissions[action.payload.offline_id] = action.payload;
|
|
3799
|
+
},
|
|
3800
|
+
setFormSubmissions: (state, action) => {
|
|
3801
|
+
state.formSubmissions = {};
|
|
3802
|
+
for (const submission of action.payload) {
|
|
3803
|
+
state.formSubmissions[submission.offline_id] = submission;
|
|
3804
|
+
}
|
|
3805
|
+
},
|
|
3806
|
+
addFormSubmission: (state, action) => {
|
|
3807
|
+
if (action.payload.offline_id in state.formSubmissions) {
|
|
3808
|
+
throw new Error(`Submission with offline_id ${action.payload.offline_id} already exists`);
|
|
3809
|
+
}
|
|
3810
|
+
state.formSubmissions[action.payload.offline_id] = action.payload;
|
|
3811
|
+
},
|
|
3812
|
+
addFormSubmissions: (state, action) => {
|
|
3813
|
+
for (const submission of action.payload) {
|
|
3814
|
+
if (state.formSubmissions[submission.offline_id] !== void 0) {
|
|
3815
|
+
throw new Error(`Submission with offline_id ${submission.offline_id} already exists`);
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
for (const submission of action.payload) {
|
|
3819
|
+
state.formSubmissions[submission.offline_id] = submission;
|
|
3820
|
+
}
|
|
3821
|
+
},
|
|
3822
|
+
updateFormSubmission: (state, action) => {
|
|
3823
|
+
if (state.formSubmissions[action.payload.offline_id] === void 0) {
|
|
3824
|
+
throw new Error(`Submission with offline_id ${action.payload.offline_id} does not exist`);
|
|
3825
|
+
}
|
|
3826
|
+
state.formSubmissions[action.payload.offline_id] = action.payload;
|
|
3827
|
+
},
|
|
3828
|
+
updateFormSubmissions: (state, action) => {
|
|
3829
|
+
for (const submission of action.payload) {
|
|
3830
|
+
if (state.formSubmissions[submission.offline_id] === void 0) {
|
|
3831
|
+
throw new Error(`Submission with offline_id ${submission.offline_id} does not exist`);
|
|
3832
|
+
}
|
|
3833
|
+
}
|
|
3834
|
+
for (const submission of action.payload) {
|
|
3835
|
+
state.formSubmissions[submission.offline_id] = submission;
|
|
3836
|
+
}
|
|
3837
|
+
},
|
|
3838
|
+
deleteFormSubmission: (state, action) => {
|
|
3839
|
+
if (state.formSubmissions[action.payload] === void 0) {
|
|
3840
|
+
throw new Error(`Submission with offline_id ${action.payload} does not exist`);
|
|
3841
|
+
}
|
|
3842
|
+
delete state.formSubmissions[action.payload];
|
|
3843
|
+
},
|
|
3844
|
+
deleteFormSubmissions: (state, action) => {
|
|
3845
|
+
for (const offlineId of action.payload) {
|
|
3846
|
+
if (state.formSubmissions[offlineId] === void 0) {
|
|
3847
|
+
throw new Error(`Submission with offline_id ${offlineId} does not exist`);
|
|
3848
|
+
}
|
|
3849
|
+
delete state.formSubmissions[offlineId];
|
|
3850
|
+
}
|
|
3851
|
+
for (const offlineId of action.payload) {
|
|
3852
|
+
delete state.formSubmissions[offlineId];
|
|
3853
|
+
}
|
|
3854
|
+
},
|
|
3855
|
+
// Attachments
|
|
3856
|
+
addFormSubmissionAttachment: (state, action) => {
|
|
3857
|
+
if (state.attachments[action.payload.offline_id] !== void 0) {
|
|
3858
|
+
throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
|
|
3859
|
+
}
|
|
3860
|
+
state.attachments[action.payload.offline_id] = action.payload;
|
|
3861
|
+
},
|
|
3862
|
+
addFormSubmissionAttachments: (state, action) => {
|
|
3863
|
+
for (const attachment of action.payload) {
|
|
3864
|
+
if (state.attachments[attachment.offline_id] !== void 0) {
|
|
3865
|
+
throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
|
|
3866
|
+
}
|
|
3867
|
+
}
|
|
3868
|
+
for (const attachment of action.payload) {
|
|
3869
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3870
|
+
}
|
|
3871
|
+
},
|
|
3872
|
+
// We only need a multi set for attachments because they are not updated, only added and deleted
|
|
3873
|
+
setFormSubmissionAttachments: (state, action) => {
|
|
3874
|
+
state.attachments = {};
|
|
3875
|
+
for (const attachment of action.payload) {
|
|
3876
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3877
|
+
}
|
|
3878
|
+
},
|
|
3879
|
+
updateFormSubmissionAttachments: (state, action) => {
|
|
3880
|
+
for (const attachment of action.payload) {
|
|
3881
|
+
if (state.attachments[attachment.offline_id] === void 0) {
|
|
3882
|
+
throw new Error(`Attachment with offline_id ${attachment.offline_id} does not exist`);
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
for (const attachment of action.payload) {
|
|
3886
|
+
state.attachments[attachment.offline_id] = attachment;
|
|
3887
|
+
}
|
|
3888
|
+
},
|
|
3889
|
+
// The delete actions for UserFormSubmissionAttachments are not used in the app, but are included for completeness
|
|
3890
|
+
// Could be used if editing a submission is ever supported, will be applicable for supporting tip tap content in submissions
|
|
3891
|
+
deleteFormSubmissionAttachment: (state, action) => {
|
|
3892
|
+
if (state.attachments[action.payload] === void 0) {
|
|
3893
|
+
throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
|
|
3894
|
+
}
|
|
3895
|
+
delete state.attachments[action.payload];
|
|
3896
|
+
},
|
|
3897
|
+
deleteFormSubmissionAttachments: (state, action) => {
|
|
3898
|
+
for (const offlineId of action.payload) {
|
|
3899
|
+
if (state.attachments[offlineId] === void 0) {
|
|
3900
|
+
throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
|
|
3901
|
+
}
|
|
3902
|
+
delete state.attachments[offlineId];
|
|
3903
|
+
}
|
|
3904
|
+
}
|
|
3905
|
+
}
|
|
3906
|
+
});
|
|
3907
|
+
const {
|
|
3908
|
+
setFormSubmission,
|
|
3909
|
+
setFormSubmissions,
|
|
3910
|
+
addFormSubmission,
|
|
3911
|
+
addFormSubmissions,
|
|
3912
|
+
updateFormSubmission,
|
|
3913
|
+
updateFormSubmissions,
|
|
3914
|
+
deleteFormSubmission,
|
|
3915
|
+
deleteFormSubmissions,
|
|
3916
|
+
addFormSubmissionAttachment,
|
|
3917
|
+
addFormSubmissionAttachments,
|
|
3918
|
+
setFormSubmissionAttachments,
|
|
3919
|
+
updateFormSubmissionAttachments,
|
|
3920
|
+
deleteFormSubmissionAttachment,
|
|
3921
|
+
deleteFormSubmissionAttachments
|
|
3922
|
+
} = formSubmissionSlice.actions;
|
|
3923
|
+
const selectFormSubmissionsMapping = (state) => {
|
|
3924
|
+
return state.formSubmissionReducer.formSubmissions;
|
|
3925
|
+
};
|
|
3926
|
+
const selectFormSubmissions = createSelector(
|
|
3927
|
+
[selectFormSubmissionsMapping],
|
|
3928
|
+
(submissions) => {
|
|
3929
|
+
return Object.values(submissions);
|
|
3930
|
+
}
|
|
3735
3931
|
);
|
|
3736
|
-
const
|
|
3932
|
+
const selectFormSubmission = (submissionId) => (state) => {
|
|
3933
|
+
return state.formSubmissionReducer.formSubmissions[submissionId];
|
|
3934
|
+
};
|
|
3935
|
+
const selectFormSubmissionsOfForm = restructureCreateSelectorWithArgs(
|
|
3737
3936
|
createSelector(
|
|
3738
|
-
[
|
|
3937
|
+
[selectFormSubmissions, selectFormRevisionMapping, (_state, formId2) => formId2],
|
|
3739
3938
|
(submissions, revisionMapping, formId2) => {
|
|
3740
|
-
return
|
|
3939
|
+
return submissions.filter((submission) => {
|
|
3741
3940
|
const revision = revisionMapping[submission.form_revision];
|
|
3742
3941
|
return (revision == null ? void 0 : revision.form) === formId2;
|
|
3743
3942
|
});
|
|
3744
3943
|
}
|
|
3745
3944
|
)
|
|
3746
3945
|
);
|
|
3747
|
-
const
|
|
3946
|
+
const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(
|
|
3748
3947
|
createSelector(
|
|
3749
|
-
[
|
|
3948
|
+
[selectFormSubmissions, (_state, issueId) => issueId],
|
|
3750
3949
|
(submissions, issueId) => {
|
|
3751
3950
|
return Object.values(submissions).filter((submission) => {
|
|
3752
3951
|
return submission.issue === issueId;
|
|
@@ -3754,9 +3953,9 @@ const selectSubmissionsForIssue = restructureCreateSelectorWithArgs(
|
|
|
3754
3953
|
}
|
|
3755
3954
|
)
|
|
3756
3955
|
);
|
|
3757
|
-
const
|
|
3956
|
+
const selectFormSubmissionsOfComponent = restructureCreateSelectorWithArgs(
|
|
3758
3957
|
createSelector(
|
|
3759
|
-
[
|
|
3958
|
+
[selectFormSubmissions, (_state, componentId) => componentId],
|
|
3760
3959
|
(submissions, componentId) => {
|
|
3761
3960
|
return submissions.filter((submission) => {
|
|
3762
3961
|
return submission.component === componentId;
|
|
@@ -3764,8 +3963,8 @@ const selectSubmissionsForComponent = restructureCreateSelectorWithArgs(
|
|
|
3764
3963
|
}
|
|
3765
3964
|
)
|
|
3766
3965
|
);
|
|
3767
|
-
const
|
|
3768
|
-
[
|
|
3966
|
+
const selectFormSubmissionsByComponents = createSelector(
|
|
3967
|
+
[selectFormSubmissionsMapping, selectComponentsMapping],
|
|
3769
3968
|
(submissions, components) => {
|
|
3770
3969
|
var _a2;
|
|
3771
3970
|
const componentSubmissionMapping = {};
|
|
@@ -3779,62 +3978,26 @@ const selectComponentSubmissionMapping = createSelector(
|
|
|
3779
3978
|
}
|
|
3780
3979
|
}
|
|
3781
3980
|
return componentSubmissionMapping;
|
|
3782
|
-
}
|
|
3783
|
-
);
|
|
3784
|
-
const selectUserFormMapping = (state) => {
|
|
3785
|
-
return state.userFormReducer.userForms;
|
|
3786
|
-
};
|
|
3787
|
-
const selectComponentTypeForm = restructureCreateSelectorWithArgs(
|
|
3788
|
-
createSelector(
|
|
3789
|
-
[selectUserFormMapping, (_state, componentTypeId) => componentTypeId],
|
|
3790
|
-
(userForms, componentTypeId) => {
|
|
3791
|
-
return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
|
|
3792
|
-
}
|
|
3793
|
-
)
|
|
3981
|
+
}
|
|
3794
3982
|
);
|
|
3795
|
-
const
|
|
3983
|
+
const selectFormSubmissionAttachmentsMapping = (state) => {
|
|
3984
|
+
return state.formSubmissionReducer.attachments;
|
|
3985
|
+
};
|
|
3986
|
+
const selectAttachmentsOfFormSubmission = restructureCreateSelectorWithArgs(
|
|
3796
3987
|
createSelector(
|
|
3797
|
-
[
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
(_state, componentTypeIds) => componentTypeIds
|
|
3801
|
-
],
|
|
3802
|
-
(userForms, revisions, componentTypeIds) => {
|
|
3803
|
-
const componentTypeIdsSet = new Set(componentTypeIds);
|
|
3804
|
-
const ret = {};
|
|
3805
|
-
for (const form of Object.values(userForms)) {
|
|
3806
|
-
if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
|
|
3807
|
-
ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
|
|
3808
|
-
}
|
|
3809
|
-
}
|
|
3810
|
-
return ret;
|
|
3988
|
+
[selectFormSubmissionAttachmentsMapping, (_state, submissionId) => submissionId],
|
|
3989
|
+
(attachmentsMapping, submissionId) => {
|
|
3990
|
+
return Object.values(attachmentsMapping).filter((attachment) => attachment.submission === submissionId);
|
|
3811
3991
|
}
|
|
3812
3992
|
)
|
|
3813
3993
|
);
|
|
3814
|
-
const
|
|
3815
|
-
|
|
3816
|
-
for (const revision of Object.values(revisions)) {
|
|
3817
|
-
const formId2 = revision.form;
|
|
3818
|
-
const currentLatestRevision = latestRevisions[formId2];
|
|
3819
|
-
if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
|
|
3820
|
-
latestRevisions[formId2] = revision;
|
|
3821
|
-
}
|
|
3822
|
-
}
|
|
3823
|
-
return latestRevisions;
|
|
3824
|
-
});
|
|
3825
|
-
const selectNumberOfUserForms = createSelector([selectUserFormMapping], (userForms) => {
|
|
3826
|
-
return Object.keys(userForms).length;
|
|
3827
|
-
});
|
|
3828
|
-
const selectNumberOfGeneralUserForms = createSelector([selectUserFormMapping], (userForms) => {
|
|
3829
|
-
return Object.values(userForms).filter((form) => !form.component_type).length;
|
|
3830
|
-
});
|
|
3831
|
-
const userFormReducer = userFormSlice.reducer;
|
|
3832
|
-
const initialState$2 = {
|
|
3994
|
+
const formSubmissionReducer = formSubmissionSlice.reducer;
|
|
3995
|
+
const initialState$3 = {
|
|
3833
3996
|
emailDomains: {}
|
|
3834
3997
|
};
|
|
3835
3998
|
const emailDomainsSlice = createSlice({
|
|
3836
3999
|
name: "emailDomains",
|
|
3837
|
-
initialState: initialState$
|
|
4000
|
+
initialState: initialState$3,
|
|
3838
4001
|
reducers: {
|
|
3839
4002
|
setEmailDomains: (state, action) => {
|
|
3840
4003
|
const emailDomains = {};
|
|
@@ -3861,15 +4024,15 @@ const selectSortedEmailDomains = (state) => Object.values(state.emailDomainsRedu
|
|
|
3861
4024
|
(ed1, ed2) => ed1.domain.localeCompare(ed2.domain)
|
|
3862
4025
|
);
|
|
3863
4026
|
const emailDomainsReducer = emailDomainsSlice.reducer;
|
|
3864
|
-
const initialState$
|
|
4027
|
+
const initialState$2 = {
|
|
3865
4028
|
documents: {},
|
|
3866
4029
|
attachments: {}
|
|
3867
4030
|
};
|
|
3868
4031
|
const documentSlice = createSlice({
|
|
3869
4032
|
name: "documents",
|
|
3870
|
-
initialState: initialState$
|
|
4033
|
+
initialState: initialState$2,
|
|
3871
4034
|
extraReducers: (builder) => builder.addCase("RESET", (state) => {
|
|
3872
|
-
Object.assign(state, initialState$
|
|
4035
|
+
Object.assign(state, initialState$2);
|
|
3873
4036
|
}),
|
|
3874
4037
|
reducers: {
|
|
3875
4038
|
setDocuments: (state, action) => {
|
|
@@ -4085,6 +4248,62 @@ const selectAttachmentsOfDocumentByType = restructureCreateSelectorWithArgs(
|
|
|
4085
4248
|
)
|
|
4086
4249
|
);
|
|
4087
4250
|
const documentsReducer = documentSlice.reducer;
|
|
4251
|
+
const initialState$1 = {
|
|
4252
|
+
teams: {}
|
|
4253
|
+
};
|
|
4254
|
+
const teamSlice = createSlice({
|
|
4255
|
+
name: "teams",
|
|
4256
|
+
initialState: initialState$1,
|
|
4257
|
+
extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$1)),
|
|
4258
|
+
reducers: {
|
|
4259
|
+
setTeam: (state, action) => {
|
|
4260
|
+
state.teams[action.payload.offline_id] = action.payload;
|
|
4261
|
+
},
|
|
4262
|
+
setTeams: (state, action) => {
|
|
4263
|
+
state.teams = {};
|
|
4264
|
+
for (const team of action.payload) {
|
|
4265
|
+
state.teams[team.offline_id] = team;
|
|
4266
|
+
}
|
|
4267
|
+
},
|
|
4268
|
+
addTeam: (state, action) => {
|
|
4269
|
+
if (state.teams[action.payload.offline_id]) {
|
|
4270
|
+
throw new Error(`Team with offline_id ${action.payload.offline_id} already exists`);
|
|
4271
|
+
}
|
|
4272
|
+
state.teams[action.payload.offline_id] = action.payload;
|
|
4273
|
+
},
|
|
4274
|
+
updateTeam: (state, action) => {
|
|
4275
|
+
if (!state.teams[action.payload.offline_id]) {
|
|
4276
|
+
throw new Error(`Team with offline_id ${action.payload.offline_id} does not exist`);
|
|
4277
|
+
}
|
|
4278
|
+
state.teams[action.payload.offline_id] = action.payload;
|
|
4279
|
+
},
|
|
4280
|
+
deleteTeam: (state, action) => {
|
|
4281
|
+
delete state.teams[action.payload];
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
});
|
|
4285
|
+
const { setTeam, setTeams, addTeam, updateTeam, deleteTeam } = teamSlice.actions;
|
|
4286
|
+
const selectTeamsMapping = (state) => state.teamReducer.teams;
|
|
4287
|
+
const selectTeams = createSelector([selectTeamsMapping], (teams) => {
|
|
4288
|
+
return Object.values(teams);
|
|
4289
|
+
});
|
|
4290
|
+
const selectTeam = (teamId) => (state) => {
|
|
4291
|
+
return state.teamReducer.teams[teamId];
|
|
4292
|
+
};
|
|
4293
|
+
const selectTeamsOfOrganization = restructureCreateSelectorWithArgs(
|
|
4294
|
+
createSelector(
|
|
4295
|
+
[selectTeams, (_state, organizationId) => organizationId],
|
|
4296
|
+
(teams, organizationId) => {
|
|
4297
|
+
return teams.filter((team) => team.organization === organizationId);
|
|
4298
|
+
}
|
|
4299
|
+
)
|
|
4300
|
+
);
|
|
4301
|
+
const selectTeamsOfUser = restructureCreateSelectorWithArgs(
|
|
4302
|
+
createSelector([selectTeams, (_state, userId) => userId], (teams, userId) => {
|
|
4303
|
+
return teams.filter((team) => team.members.includes(userId));
|
|
4304
|
+
})
|
|
4305
|
+
);
|
|
4306
|
+
const teamReducer = teamSlice.reducer;
|
|
4088
4307
|
const initialState = {
|
|
4089
4308
|
version: 0
|
|
4090
4309
|
};
|
|
@@ -4126,12 +4345,15 @@ const overmapReducers = {
|
|
|
4126
4345
|
projectFileReducer,
|
|
4127
4346
|
rehydratedReducer,
|
|
4128
4347
|
settingReducer,
|
|
4129
|
-
|
|
4348
|
+
formReducer,
|
|
4349
|
+
formRevisionReducer,
|
|
4350
|
+
formSubmissionReducer,
|
|
4130
4351
|
userReducer,
|
|
4131
4352
|
workspaceReducer,
|
|
4132
4353
|
emailDomainsReducer,
|
|
4133
4354
|
licenseReducer,
|
|
4134
|
-
documentsReducer
|
|
4355
|
+
documentsReducer,
|
|
4356
|
+
teamReducer
|
|
4135
4357
|
};
|
|
4136
4358
|
const overmapReducer = combineReducers(overmapReducers);
|
|
4137
4359
|
const resetStore = "RESET";
|
|
@@ -4179,9 +4401,7 @@ function handleWorkspaceRemoval(draft, action) {
|
|
|
4179
4401
|
throw new Error(`Failed to update index_workspace of issue ${issue.offline_id} to main workspace`);
|
|
4180
4402
|
}
|
|
4181
4403
|
}
|
|
4182
|
-
const indexedForms = Object.values(draft.
|
|
4183
|
-
(form) => form.index_workspace === workspaceId
|
|
4184
|
-
);
|
|
4404
|
+
const indexedForms = Object.values(draft.formReducer.forms).filter((form) => form.index_workspace === workspaceId);
|
|
4185
4405
|
for (const form of indexedForms) {
|
|
4186
4406
|
form.index_workspace = mainWorkspace.offline_id;
|
|
4187
4407
|
}
|
|
@@ -6372,6 +6592,7 @@ class MainService extends BaseApiService {
|
|
|
6372
6592
|
}
|
|
6373
6593
|
if (currentOrgId) {
|
|
6374
6594
|
await this.client.organizations.fetchInitialOrganizationData(currentOrgId, false);
|
|
6595
|
+
void this.client.teams.refreshStore();
|
|
6375
6596
|
}
|
|
6376
6597
|
if (!isProjectIdValid) {
|
|
6377
6598
|
if (validProjects.length !== 0) {
|
|
@@ -6809,7 +7030,7 @@ class UserFormService extends BaseApiService {
|
|
|
6809
7030
|
...revisionAttachmentPayload,
|
|
6810
7031
|
file: URL.createObjectURL(image)
|
|
6811
7032
|
};
|
|
6812
|
-
store.dispatch(
|
|
7033
|
+
store.dispatch(addFormRevisionAttachment(offlinePayload));
|
|
6813
7034
|
return attach;
|
|
6814
7035
|
});
|
|
6815
7036
|
});
|
|
@@ -6845,8 +7066,8 @@ class UserFormService extends BaseApiService {
|
|
|
6845
7066
|
submitted_at: submittedAt
|
|
6846
7067
|
};
|
|
6847
7068
|
const { store } = this.client;
|
|
6848
|
-
store.dispatch(
|
|
6849
|
-
store.dispatch(
|
|
7069
|
+
store.dispatch(addForm(retForm));
|
|
7070
|
+
store.dispatch(addFormRevision(retRevision));
|
|
6850
7071
|
const formPromise = this.enqueueRequest({
|
|
6851
7072
|
description: "Create form",
|
|
6852
7073
|
method: HttpMethod.POST,
|
|
@@ -6864,8 +7085,8 @@ class UserFormService extends BaseApiService {
|
|
|
6864
7085
|
});
|
|
6865
7086
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevisionPayload.offline_id);
|
|
6866
7087
|
void formPromise.catch((e) => {
|
|
6867
|
-
store.dispatch(
|
|
6868
|
-
store.dispatch(
|
|
7088
|
+
store.dispatch(deleteForm(retForm.offline_id));
|
|
7089
|
+
store.dispatch(deleteFormRevision(retRevision.offline_id));
|
|
6869
7090
|
throw e;
|
|
6870
7091
|
});
|
|
6871
7092
|
const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
|
|
@@ -6908,7 +7129,7 @@ class UserFormService extends BaseApiService {
|
|
|
6908
7129
|
form: formId2,
|
|
6909
7130
|
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6910
7131
|
};
|
|
6911
|
-
store.dispatch(
|
|
7132
|
+
store.dispatch(addFormRevision(fullRevision));
|
|
6912
7133
|
const promise = this.enqueueRequest({
|
|
6913
7134
|
description: "Create form revision",
|
|
6914
7135
|
method: HttpMethod.PATCH,
|
|
@@ -6922,9 +7143,9 @@ class UserFormService extends BaseApiService {
|
|
|
6922
7143
|
});
|
|
6923
7144
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
|
|
6924
7145
|
void promise.then((result) => {
|
|
6925
|
-
store.dispatch(
|
|
7146
|
+
store.dispatch(setFormRevision(result));
|
|
6926
7147
|
}).catch(() => {
|
|
6927
|
-
store.dispatch(
|
|
7148
|
+
store.dispatch(deleteFormRevision(fullRevision.offline_id));
|
|
6928
7149
|
});
|
|
6929
7150
|
const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
|
|
6930
7151
|
return [fullRevision, settledPromise];
|
|
@@ -6966,19 +7187,19 @@ class UserFormService extends BaseApiService {
|
|
|
6966
7187
|
async delete(formId2) {
|
|
6967
7188
|
const { store } = this.client;
|
|
6968
7189
|
const state = store.getState();
|
|
6969
|
-
const userForm =
|
|
7190
|
+
const userForm = selectForm(formId2)(state);
|
|
6970
7191
|
if (!userForm) {
|
|
6971
7192
|
throw new Error("Expected userForm to exist");
|
|
6972
7193
|
}
|
|
6973
|
-
const userFormSubmissions =
|
|
7194
|
+
const userFormSubmissions = selectFormSubmissionsOfForm(formId2)(state);
|
|
6974
7195
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6975
|
-
store.dispatch(
|
|
7196
|
+
store.dispatch(deleteFormSubmissions(userFormSubmissions.map(({ offline_id }) => offline_id)));
|
|
6976
7197
|
}
|
|
6977
|
-
const userFormRevisions =
|
|
7198
|
+
const userFormRevisions = selectFormRevisionsOfForm(formId2)(state);
|
|
6978
7199
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6979
|
-
store.dispatch(
|
|
7200
|
+
store.dispatch(deleteFormRevisions(userFormRevisions.map(({ offline_id }) => offline_id)));
|
|
6980
7201
|
}
|
|
6981
|
-
store.dispatch(
|
|
7202
|
+
store.dispatch(deleteForm(formId2));
|
|
6982
7203
|
try {
|
|
6983
7204
|
return await this.enqueueRequest({
|
|
6984
7205
|
description: "Delete form",
|
|
@@ -6988,12 +7209,12 @@ class UserFormService extends BaseApiService {
|
|
|
6988
7209
|
blocks: []
|
|
6989
7210
|
});
|
|
6990
7211
|
} catch (e) {
|
|
6991
|
-
store.dispatch(
|
|
7212
|
+
store.dispatch(addForm(userForm));
|
|
6992
7213
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6993
|
-
store.dispatch(
|
|
7214
|
+
store.dispatch(addFormRevisions(userFormRevisions));
|
|
6994
7215
|
}
|
|
6995
7216
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6996
|
-
store.dispatch(
|
|
7217
|
+
store.dispatch(addFormSubmissions(userFormSubmissions));
|
|
6997
7218
|
}
|
|
6998
7219
|
throw e;
|
|
6999
7220
|
}
|
|
@@ -7007,16 +7228,15 @@ class UserFormService extends BaseApiService {
|
|
|
7007
7228
|
blockers: [],
|
|
7008
7229
|
blocks: []
|
|
7009
7230
|
});
|
|
7010
|
-
store.dispatch(
|
|
7011
|
-
store.dispatch(
|
|
7012
|
-
store.dispatch(
|
|
7231
|
+
store.dispatch(setForms(Object.values(result.forms)));
|
|
7232
|
+
store.dispatch(setFormRevisions(Object.values(result.revisions)));
|
|
7233
|
+
store.dispatch(setFormRevisionAttachments(Object.values(result.attachments)));
|
|
7013
7234
|
}
|
|
7014
7235
|
}
|
|
7015
7236
|
const isArrayOfFiles = (value) => {
|
|
7016
7237
|
return Array.isArray(value) && value[0] instanceof File;
|
|
7017
7238
|
};
|
|
7018
|
-
const separateFilesFromValues = (
|
|
7019
|
-
const { values } = payload;
|
|
7239
|
+
const separateFilesFromValues = (values) => {
|
|
7020
7240
|
const files = {};
|
|
7021
7241
|
const newValues = {};
|
|
7022
7242
|
for (const key in values) {
|
|
@@ -7031,17 +7251,13 @@ const separateFilesFromValues = (payload) => {
|
|
|
7031
7251
|
newValues[key] = value;
|
|
7032
7252
|
}
|
|
7033
7253
|
}
|
|
7034
|
-
|
|
7035
|
-
...payload,
|
|
7036
|
-
values: newValues
|
|
7037
|
-
};
|
|
7038
|
-
return { payloadWithoutFiles, files };
|
|
7254
|
+
return { values: newValues, files };
|
|
7039
7255
|
};
|
|
7040
7256
|
class UserFormSubmissionService extends BaseApiService {
|
|
7041
7257
|
constructor() {
|
|
7042
7258
|
super(...arguments);
|
|
7043
7259
|
// Attach files to submission, after uploading them to S3
|
|
7044
|
-
__publicField(this, "getAttachFilesPromises", (files,
|
|
7260
|
+
__publicField(this, "getAttachFilesPromises", (files, submission) => {
|
|
7045
7261
|
const { store } = this.client;
|
|
7046
7262
|
return Object.entries(files).map(async ([key, fileArray]) => {
|
|
7047
7263
|
const attachResults = [];
|
|
@@ -7051,24 +7267,27 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7051
7267
|
const [fileProps] = await this.client.files.uploadFileToS3(sha1);
|
|
7052
7268
|
const submissionAttachmentPayload = offline({
|
|
7053
7269
|
...fileProps,
|
|
7054
|
-
submission:
|
|
7270
|
+
submission: submission.offline_id,
|
|
7055
7271
|
field_identifier: key
|
|
7056
7272
|
});
|
|
7057
7273
|
const attach = await this.enqueueRequest({
|
|
7058
7274
|
description: "Attach file to form submission",
|
|
7059
7275
|
method: HttpMethod.POST,
|
|
7060
|
-
url: `/forms/submission/${
|
|
7276
|
+
url: `/forms/submission/${submission.offline_id}/attachments/`,
|
|
7061
7277
|
payload: submissionAttachmentPayload,
|
|
7062
|
-
blockers: [
|
|
7063
|
-
|
|
7064
|
-
|
|
7278
|
+
blockers: [
|
|
7279
|
+
submission.component,
|
|
7280
|
+
submission.component_stage,
|
|
7281
|
+
submission.issue,
|
|
7282
|
+
submission.form_revision
|
|
7283
|
+
].filter((x) => x !== void 0),
|
|
7065
7284
|
blocks: [submissionAttachmentPayload.offline_id]
|
|
7066
7285
|
});
|
|
7067
7286
|
const offlinePayload = {
|
|
7068
7287
|
...submissionAttachmentPayload,
|
|
7069
7288
|
file: URL.createObjectURL(file)
|
|
7070
7289
|
};
|
|
7071
|
-
store.dispatch(
|
|
7290
|
+
store.dispatch(addFormSubmissionAttachment(offlinePayload));
|
|
7072
7291
|
attachResults.push(attach);
|
|
7073
7292
|
}
|
|
7074
7293
|
return attachResults;
|
|
@@ -7082,71 +7301,168 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7082
7301
|
if (!activeProjectId) {
|
|
7083
7302
|
throw new Error("Expected an active project");
|
|
7084
7303
|
}
|
|
7085
|
-
const {
|
|
7304
|
+
const { values, files } = separateFilesFromValues(payload.values);
|
|
7305
|
+
const offlineSubmission = {
|
|
7306
|
+
...payload,
|
|
7307
|
+
values,
|
|
7308
|
+
created_by: state.userReducer.currentUser.id,
|
|
7309
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
7310
|
+
};
|
|
7086
7311
|
const promise = this.enqueueRequest({
|
|
7087
7312
|
description: "Respond to form",
|
|
7088
7313
|
method: HttpMethod.POST,
|
|
7089
7314
|
url: `/forms/revisions/${payload.form_revision}/respond/`,
|
|
7090
|
-
payload: { ...
|
|
7315
|
+
payload: { ...offlineSubmission, project: activeProjectId },
|
|
7091
7316
|
blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
|
|
7092
7317
|
(x) => x !== void 0
|
|
7093
7318
|
),
|
|
7094
7319
|
blocks: [payload.offline_id]
|
|
7095
7320
|
});
|
|
7096
|
-
const attachFilesPromises = this.getAttachFilesPromises(files,
|
|
7097
|
-
|
|
7098
|
-
const fullOfflineResult = {
|
|
7099
|
-
...payload,
|
|
7100
|
-
created_by: state.userReducer.currentUser.id,
|
|
7101
|
-
created_at: now,
|
|
7102
|
-
updated_at: now
|
|
7103
|
-
};
|
|
7104
|
-
const offlineResultWithoutFiles = {
|
|
7105
|
-
...fullOfflineResult,
|
|
7106
|
-
...payloadWithoutFiles
|
|
7107
|
-
};
|
|
7108
|
-
store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
|
|
7321
|
+
const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
|
|
7322
|
+
store.dispatch(addFormSubmission(offlineSubmission));
|
|
7109
7323
|
void promise.then((result) => {
|
|
7110
7324
|
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
7111
|
-
store.dispatch(
|
|
7325
|
+
store.dispatch(setFormSubmission(result));
|
|
7112
7326
|
return result;
|
|
7113
7327
|
}).catch(() => {
|
|
7114
|
-
store.dispatch(
|
|
7328
|
+
store.dispatch(deleteFormSubmission(payload.offline_id));
|
|
7115
7329
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
7116
7330
|
});
|
|
7117
7331
|
const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
7118
|
-
return [
|
|
7332
|
+
return [offlineSubmission, settledPromise];
|
|
7119
7333
|
}
|
|
7120
|
-
|
|
7334
|
+
// Note currently the bulkAdd method is specific to form submissions for components
|
|
7335
|
+
// TODO: adapt the support bulk adding to any model type
|
|
7336
|
+
async bulkAdd(args) {
|
|
7337
|
+
const { formRevision, values: argsValues, componentOfflineIds } = args;
|
|
7121
7338
|
const { store } = this.client;
|
|
7122
|
-
const
|
|
7123
|
-
|
|
7124
|
-
|
|
7339
|
+
const offlineSubmissions = [];
|
|
7340
|
+
const offlineAttachments = [];
|
|
7341
|
+
const submissionOfflineIds = [];
|
|
7342
|
+
const submissionsPayload = [];
|
|
7343
|
+
const attachmentsPayload = [];
|
|
7344
|
+
const { values, files } = separateFilesFromValues(argsValues);
|
|
7345
|
+
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
7346
|
+
const createdBy = store.getState().userReducer.currentUser.id;
|
|
7347
|
+
for (const component_id of componentOfflineIds) {
|
|
7348
|
+
const submission = offline({
|
|
7349
|
+
form_revision: formRevision,
|
|
7350
|
+
values,
|
|
7351
|
+
created_by: createdBy,
|
|
7352
|
+
submitted_at: submittedAt,
|
|
7353
|
+
component: component_id
|
|
7354
|
+
});
|
|
7355
|
+
submissionOfflineIds.push(submission.offline_id);
|
|
7356
|
+
submissionsPayload.push({ offline_id: submission.offline_id, component_id });
|
|
7357
|
+
offlineSubmissions.push(submission);
|
|
7358
|
+
for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
|
|
7359
|
+
for (const file of fileArray) {
|
|
7360
|
+
const sha1 = await hashFile(file);
|
|
7361
|
+
await this.client.files.addCache(file, sha1);
|
|
7362
|
+
const offlineAttachment = offline({
|
|
7363
|
+
file_name: file.name,
|
|
7364
|
+
file_sha1: sha1,
|
|
7365
|
+
file: URL.createObjectURL(file),
|
|
7366
|
+
submission: submission.offline_id,
|
|
7367
|
+
field_identifier: fieldIdentifier
|
|
7368
|
+
});
|
|
7369
|
+
offlineAttachments.push(offlineAttachment);
|
|
7370
|
+
attachmentsPayload.push({
|
|
7371
|
+
offline_id: offlineAttachment.offline_id,
|
|
7372
|
+
submission_id: submission.offline_id,
|
|
7373
|
+
sha1,
|
|
7374
|
+
name: file.name,
|
|
7375
|
+
field_identifier: fieldIdentifier
|
|
7376
|
+
});
|
|
7377
|
+
}
|
|
7378
|
+
}
|
|
7379
|
+
}
|
|
7380
|
+
const filesRecord = {};
|
|
7381
|
+
for (const file of Object.values(files).flat()) {
|
|
7382
|
+
const sha1 = await hashFile(file);
|
|
7383
|
+
filesRecord[sha1] = {
|
|
7384
|
+
sha1,
|
|
7385
|
+
extension: file.name.split(".").pop() || "",
|
|
7386
|
+
file_type: file.type,
|
|
7387
|
+
size: file.size
|
|
7388
|
+
};
|
|
7125
7389
|
}
|
|
7390
|
+
store.dispatch(addFormSubmissions(offlineSubmissions));
|
|
7391
|
+
store.dispatch(addFormSubmissionAttachments(offlineAttachments));
|
|
7392
|
+
const promise = this.enqueueRequest({
|
|
7393
|
+
description: "Bulk add form submissions",
|
|
7394
|
+
method: HttpMethod.POST,
|
|
7395
|
+
url: `/forms/revisions/${formRevision}/bulk-respond/`,
|
|
7396
|
+
payload: {
|
|
7397
|
+
form_data: values,
|
|
7398
|
+
submitted_at: submittedAt,
|
|
7399
|
+
submissions: submissionsPayload,
|
|
7400
|
+
attachments: attachmentsPayload,
|
|
7401
|
+
files: Object.values(filesRecord)
|
|
7402
|
+
},
|
|
7403
|
+
blockers: componentOfflineIds,
|
|
7404
|
+
blocks: submissionOfflineIds
|
|
7405
|
+
});
|
|
7406
|
+
promise.then(({ submissions, attachments, presigned_urls }) => {
|
|
7407
|
+
store.dispatch(updateFormSubmissions(submissions));
|
|
7408
|
+
store.dispatch(updateFormSubmissionAttachments(attachments));
|
|
7409
|
+
for (const [sha1, presigned_url] of Object.entries(presigned_urls)) {
|
|
7410
|
+
const file = filesRecord[sha1];
|
|
7411
|
+
if (!file)
|
|
7412
|
+
continue;
|
|
7413
|
+
void this.enqueueRequest({
|
|
7414
|
+
url: presigned_url.url,
|
|
7415
|
+
description: "Upload file",
|
|
7416
|
+
method: HttpMethod.POST,
|
|
7417
|
+
isExternalUrl: true,
|
|
7418
|
+
isAuthNeeded: false,
|
|
7419
|
+
attachmentHash: sha1,
|
|
7420
|
+
blockers: [`s3-${file.sha1}.${file.extension}`],
|
|
7421
|
+
blocks: [sha1],
|
|
7422
|
+
s3url: presigned_url
|
|
7423
|
+
});
|
|
7424
|
+
}
|
|
7425
|
+
}).catch(() => {
|
|
7426
|
+
store.dispatch(deleteFormSubmissions(submissionOfflineIds));
|
|
7427
|
+
store.dispatch(deleteFormSubmissionAttachments(offlineAttachments.map((x) => x.offline_id)));
|
|
7428
|
+
});
|
|
7429
|
+
return [offlineSubmissions, promise.then(({ submissions }) => submissions)];
|
|
7430
|
+
}
|
|
7431
|
+
update(submission) {
|
|
7432
|
+
const { store } = this.client;
|
|
7433
|
+
const { values, files } = separateFilesFromValues(submission.values);
|
|
7126
7434
|
const attachFilesPromises = this.getAttachFilesPromises(files, submission);
|
|
7127
|
-
const
|
|
7128
|
-
...
|
|
7129
|
-
|
|
7435
|
+
const offlineSubmission = {
|
|
7436
|
+
...submission,
|
|
7437
|
+
values
|
|
7130
7438
|
};
|
|
7131
|
-
store.
|
|
7439
|
+
const submissionToBeUpdated = store.getState().formSubmissionReducer.formSubmissions[submission.offline_id];
|
|
7440
|
+
store.dispatch(updateFormSubmission(offlineSubmission));
|
|
7132
7441
|
const promise = this.enqueueRequest({
|
|
7133
7442
|
description: "Patch form submission",
|
|
7134
7443
|
method: HttpMethod.PATCH,
|
|
7135
7444
|
url: `/forms/submissions/${submission.offline_id}/`,
|
|
7136
|
-
payload:
|
|
7137
|
-
blockers: [
|
|
7445
|
+
payload: offlineSubmission,
|
|
7446
|
+
blockers: [offlineSubmission.issue, offlineSubmission.component, offlineSubmission.component_stage].filter(
|
|
7138
7447
|
(x) => x !== void 0
|
|
7139
7448
|
),
|
|
7140
|
-
blocks: [
|
|
7449
|
+
blocks: [offlineSubmission.offline_id]
|
|
7450
|
+
});
|
|
7451
|
+
promise.then((createdSubmission) => {
|
|
7452
|
+
store.dispatch(setFormSubmission(createdSubmission));
|
|
7453
|
+
}).catch(() => {
|
|
7454
|
+
store.dispatch(setFormSubmission(submissionToBeUpdated));
|
|
7141
7455
|
});
|
|
7142
|
-
return Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
7456
|
+
return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
|
|
7143
7457
|
}
|
|
7144
7458
|
async delete(submissionId) {
|
|
7145
7459
|
const { store } = this.client;
|
|
7146
7460
|
const state = store.getState();
|
|
7147
|
-
const submission = state.
|
|
7148
|
-
|
|
7461
|
+
const submission = state.formSubmissionReducer.formSubmissions[submissionId];
|
|
7462
|
+
const submissionAttachments = selectAttachmentsOfFormSubmission(submissionId)(state);
|
|
7463
|
+
store.dispatch(deleteFormSubmission(submissionId));
|
|
7149
7464
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
7465
|
+
store.dispatch(deleteFormSubmissionAttachments(submissionAttachments.map((x) => x.offline_id)));
|
|
7150
7466
|
try {
|
|
7151
7467
|
return await this.enqueueRequest({
|
|
7152
7468
|
description: "Delete user form submissions",
|
|
@@ -7156,10 +7472,9 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7156
7472
|
blocks: []
|
|
7157
7473
|
});
|
|
7158
7474
|
} catch (e) {
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
|
|
7162
|
-
}
|
|
7475
|
+
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
7476
|
+
store.dispatch(addFormSubmission(submission));
|
|
7477
|
+
store.dispatch(addFormSubmissionAttachments(submissionAttachments));
|
|
7163
7478
|
throw e;
|
|
7164
7479
|
}
|
|
7165
7480
|
}
|
|
@@ -7173,7 +7488,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7173
7488
|
blockers: [],
|
|
7174
7489
|
blocks: []
|
|
7175
7490
|
});
|
|
7176
|
-
store.dispatch(
|
|
7491
|
+
store.dispatch(setFormSubmissions(submissions));
|
|
7177
7492
|
const attachments = await this.enqueueRequest({
|
|
7178
7493
|
description: "Fetch form attachments",
|
|
7179
7494
|
method: HttpMethod.GET,
|
|
@@ -7181,7 +7496,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7181
7496
|
blockers: [],
|
|
7182
7497
|
blocks: []
|
|
7183
7498
|
});
|
|
7184
|
-
store.dispatch(
|
|
7499
|
+
store.dispatch(setFormSubmissionAttachments(attachments));
|
|
7185
7500
|
}
|
|
7186
7501
|
}
|
|
7187
7502
|
class WorkspaceService extends BaseApiService {
|
|
@@ -7905,6 +8220,142 @@ class AgentService extends BaseApiService {
|
|
|
7905
8220
|
});
|
|
7906
8221
|
}
|
|
7907
8222
|
}
|
|
8223
|
+
class TeamService extends BaseApiService {
|
|
8224
|
+
add(teamPayload) {
|
|
8225
|
+
const { store } = this.client;
|
|
8226
|
+
const state = store.getState();
|
|
8227
|
+
const activeOrganizationId = state.organizationReducer.activeOrganizationId;
|
|
8228
|
+
if (!activeOrganizationId) {
|
|
8229
|
+
throw new Error(`Expected active organization to be set, got ${activeOrganizationId}`);
|
|
8230
|
+
}
|
|
8231
|
+
const offlineTeam = offline({
|
|
8232
|
+
...teamPayload,
|
|
8233
|
+
organization: activeOrganizationId,
|
|
8234
|
+
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
8235
|
+
// TODO: uncomment once supported
|
|
8236
|
+
// created_by: state.userReducer.currentUser.id,
|
|
8237
|
+
});
|
|
8238
|
+
store.dispatch(addTeam(offlineTeam));
|
|
8239
|
+
const promise = this.enqueueRequest({
|
|
8240
|
+
description: "Create team",
|
|
8241
|
+
method: HttpMethod.POST,
|
|
8242
|
+
url: `/organizations/${activeOrganizationId}/teams/`,
|
|
8243
|
+
payload: offlineTeam,
|
|
8244
|
+
// No blocks since users and organizations are not offline
|
|
8245
|
+
blockers: [],
|
|
8246
|
+
blocks: [offlineTeam.offline_id]
|
|
8247
|
+
});
|
|
8248
|
+
promise.then((createdTeam) => {
|
|
8249
|
+
store.dispatch(setTeam(createdTeam));
|
|
8250
|
+
}).catch(() => {
|
|
8251
|
+
store.dispatch(deleteTeam(offlineTeam.offline_id));
|
|
8252
|
+
});
|
|
8253
|
+
return [offlineTeam, promise];
|
|
8254
|
+
}
|
|
8255
|
+
// TODO: @Audiopolis / Magnus - should we pass a offline_id as one arg and a UpdatedTeamProps as a second arg instead of this set up?
|
|
8256
|
+
update(team) {
|
|
8257
|
+
const { store } = this.client;
|
|
8258
|
+
const teamToBeUpdated = store.getState().teamReducer.teams[team.offline_id];
|
|
8259
|
+
const offlineUpdatedTeam = {
|
|
8260
|
+
...teamToBeUpdated,
|
|
8261
|
+
...team
|
|
8262
|
+
};
|
|
8263
|
+
store.dispatch(updateTeam(offlineUpdatedTeam));
|
|
8264
|
+
const promise = this.enqueueRequest({
|
|
8265
|
+
description: "Update team",
|
|
8266
|
+
method: HttpMethod.PATCH,
|
|
8267
|
+
url: `/organizations/teams/${team.offline_id}/`,
|
|
8268
|
+
payload: offlineUpdatedTeam,
|
|
8269
|
+
blockers: [team.offline_id],
|
|
8270
|
+
blocks: [team.offline_id]
|
|
8271
|
+
});
|
|
8272
|
+
promise.then((updatedTeam) => {
|
|
8273
|
+
store.dispatch(setTeam(updatedTeam));
|
|
8274
|
+
}).catch(() => {
|
|
8275
|
+
store.dispatch(setTeam(teamToBeUpdated));
|
|
8276
|
+
});
|
|
8277
|
+
return [offlineUpdatedTeam, promise];
|
|
8278
|
+
}
|
|
8279
|
+
async delete(teamId) {
|
|
8280
|
+
const { store } = this.client;
|
|
8281
|
+
const state = store.getState();
|
|
8282
|
+
const team = state.teamReducer.teams[teamId];
|
|
8283
|
+
if (!team) {
|
|
8284
|
+
throw new Error(`Expected team with id ${teamId} to exist`);
|
|
8285
|
+
}
|
|
8286
|
+
store.dispatch(deleteTeam(teamId));
|
|
8287
|
+
try {
|
|
8288
|
+
return await this.enqueueRequest({
|
|
8289
|
+
description: "Delete team",
|
|
8290
|
+
method: HttpMethod.DELETE,
|
|
8291
|
+
url: `/organizations/teams/${teamId}/`,
|
|
8292
|
+
blockers: [teamId],
|
|
8293
|
+
blocks: [teamId]
|
|
8294
|
+
});
|
|
8295
|
+
} catch (e) {
|
|
8296
|
+
store.dispatch(setTeam(team));
|
|
8297
|
+
throw e;
|
|
8298
|
+
}
|
|
8299
|
+
}
|
|
8300
|
+
async setMembers(teamId, members) {
|
|
8301
|
+
const { store } = this.client;
|
|
8302
|
+
const team = store.getState().teamReducer.teams[teamId];
|
|
8303
|
+
if (!team) {
|
|
8304
|
+
throw new Error(`Expected team with id ${teamId} to exist`);
|
|
8305
|
+
}
|
|
8306
|
+
if (members.length !== new Set(members).size) {
|
|
8307
|
+
throw new Error("Duplicate members found in the list");
|
|
8308
|
+
}
|
|
8309
|
+
store.dispatch(updateTeam({ ...team, members }));
|
|
8310
|
+
const promise = this.enqueueRequest({
|
|
8311
|
+
description: "Set team members",
|
|
8312
|
+
method: HttpMethod.PUT,
|
|
8313
|
+
url: `/organizations/teams/${teamId}/set-members/`,
|
|
8314
|
+
payload: {
|
|
8315
|
+
users: members
|
|
8316
|
+
},
|
|
8317
|
+
blockers: [teamId],
|
|
8318
|
+
blocks: [teamId]
|
|
8319
|
+
});
|
|
8320
|
+
promise.catch(() => {
|
|
8321
|
+
store.dispatch(setTeam(team));
|
|
8322
|
+
});
|
|
8323
|
+
return promise;
|
|
8324
|
+
}
|
|
8325
|
+
async addMembers(teamId, members) {
|
|
8326
|
+
const { store } = this.client;
|
|
8327
|
+
const team = store.getState().teamReducer.teams[teamId];
|
|
8328
|
+
if (!team) {
|
|
8329
|
+
throw new Error(`Expected team with id ${teamId} to exist`);
|
|
8330
|
+
}
|
|
8331
|
+
const newMembers = [...team.members, ...members];
|
|
8332
|
+
return this.setMembers(teamId, newMembers);
|
|
8333
|
+
}
|
|
8334
|
+
async removeMembers(teamId, members) {
|
|
8335
|
+
const { store } = this.client;
|
|
8336
|
+
const team = store.getState().teamReducer.teams[teamId];
|
|
8337
|
+
if (!team) {
|
|
8338
|
+
throw new Error(`Expected team with id ${teamId} to exist`);
|
|
8339
|
+
}
|
|
8340
|
+
const newMembers = team.members.filter((member) => !members.includes(member));
|
|
8341
|
+
return this.setMembers(teamId, newMembers);
|
|
8342
|
+
}
|
|
8343
|
+
async refreshStore() {
|
|
8344
|
+
const { store } = this.client;
|
|
8345
|
+
const activeOrganizationId = store.getState().organizationReducer.activeOrganizationId;
|
|
8346
|
+
if (!activeOrganizationId) {
|
|
8347
|
+
throw new Error(`Expected active organization to be set, got ${activeOrganizationId}`);
|
|
8348
|
+
}
|
|
8349
|
+
const result = await this.enqueueRequest({
|
|
8350
|
+
description: "Fetch teams",
|
|
8351
|
+
method: HttpMethod.GET,
|
|
8352
|
+
url: `/organizations/${activeOrganizationId}/teams/`,
|
|
8353
|
+
blockers: [],
|
|
8354
|
+
blocks: []
|
|
8355
|
+
});
|
|
8356
|
+
store.dispatch(setTeams(result));
|
|
8357
|
+
}
|
|
8358
|
+
}
|
|
7908
8359
|
class OvermapSDK {
|
|
7909
8360
|
constructor(apiUrl, store) {
|
|
7910
8361
|
__publicField(this, "API_URL");
|
|
@@ -7934,6 +8385,7 @@ class OvermapSDK {
|
|
|
7934
8385
|
__publicField(this, "emailDomains", new EmailDomainsService(this));
|
|
7935
8386
|
__publicField(this, "licenses", new LicenseService(this));
|
|
7936
8387
|
__publicField(this, "documents", new DocumentService(this));
|
|
8388
|
+
__publicField(this, "teams", new TeamService(this));
|
|
7937
8389
|
this.API_URL = apiUrl;
|
|
7938
8390
|
this.store = store;
|
|
7939
8391
|
}
|
|
@@ -7975,7 +8427,7 @@ const tabTrigger = "_tabTrigger_1w0fq_69";
|
|
|
7975
8427
|
const patchfieldBorder = "_patchfieldBorder_1w0fq_73";
|
|
7976
8428
|
const title = "_title_1w0fq_73";
|
|
7977
8429
|
const error = "_error_1w0fq_89";
|
|
7978
|
-
const styles$
|
|
8430
|
+
const styles$d = {
|
|
7979
8431
|
description: description$2,
|
|
7980
8432
|
floatingButtonContainer: floatingButtonContainer$2,
|
|
7981
8433
|
FullScreenImageContainer: FullScreenImageContainer$2,
|
|
@@ -8096,7 +8548,7 @@ const fileName$1 = "_fileName_10o76_31";
|
|
|
8096
8548
|
const longIconButton$1 = "_longIconButton_10o76_36";
|
|
8097
8549
|
const previewImage$1 = "_previewImage_10o76_42";
|
|
8098
8550
|
const FullScreenImage$1 = "_FullScreenImage_10o76_12";
|
|
8099
|
-
const styles$
|
|
8551
|
+
const styles$c = {
|
|
8100
8552
|
description: description$1,
|
|
8101
8553
|
floatingButtonContainer: floatingButtonContainer$1,
|
|
8102
8554
|
FullScreenImageContainer: FullScreenImageContainer$1,
|
|
@@ -8120,7 +8572,7 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8120
8572
|
/* @__PURE__ */ jsx(
|
|
8121
8573
|
"button",
|
|
8122
8574
|
{
|
|
8123
|
-
className: styles$
|
|
8575
|
+
className: styles$c.FullScreenImageContainer,
|
|
8124
8576
|
type: "button",
|
|
8125
8577
|
onClick: () => {
|
|
8126
8578
|
setShowPreview(false);
|
|
@@ -8128,7 +8580,7 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8128
8580
|
children: /* @__PURE__ */ jsx(
|
|
8129
8581
|
"img",
|
|
8130
8582
|
{
|
|
8131
|
-
className: styles$
|
|
8583
|
+
className: styles$c.FullScreenImage,
|
|
8132
8584
|
src: url,
|
|
8133
8585
|
alt: name,
|
|
8134
8586
|
onClick: (e) => {
|
|
@@ -8138,11 +8590,11 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8138
8590
|
)
|
|
8139
8591
|
}
|
|
8140
8592
|
),
|
|
8141
|
-
/* @__PURE__ */ jsxs(Flex$1, { className: styles$
|
|
8593
|
+
/* @__PURE__ */ jsxs(Flex$1, { className: styles$c.TopBarContainer, align: "center", children: [
|
|
8142
8594
|
/* @__PURE__ */ jsx(
|
|
8143
8595
|
IconButton,
|
|
8144
8596
|
{
|
|
8145
|
-
className: styles$
|
|
8597
|
+
className: styles$c.longIconButton,
|
|
8146
8598
|
variant: "soft",
|
|
8147
8599
|
"aria-label": "Exit preview",
|
|
8148
8600
|
onClick: () => {
|
|
@@ -8151,11 +8603,11 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8151
8603
|
children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiArrowLeftLine" })
|
|
8152
8604
|
}
|
|
8153
8605
|
),
|
|
8154
|
-
/* @__PURE__ */ jsx(Text$1, { className: styles$
|
|
8606
|
+
/* @__PURE__ */ jsx(Text$1, { className: styles$c.fileName, children: name }),
|
|
8155
8607
|
/* @__PURE__ */ jsx(
|
|
8156
8608
|
IconButton,
|
|
8157
8609
|
{
|
|
8158
|
-
className: styles$
|
|
8610
|
+
className: styles$c.longIconButton,
|
|
8159
8611
|
variant: "soft",
|
|
8160
8612
|
"aria-label": `Download ${name}`,
|
|
8161
8613
|
onClick: handleDownload,
|
|
@@ -8183,7 +8635,7 @@ const InputWithLabel = (props) => {
|
|
|
8183
8635
|
/* @__PURE__ */ jsx(
|
|
8184
8636
|
"img",
|
|
8185
8637
|
{
|
|
8186
|
-
className: styles$
|
|
8638
|
+
className: styles$c.previewImage,
|
|
8187
8639
|
src: resolvedImageURL,
|
|
8188
8640
|
alt: resolvedImage.name,
|
|
8189
8641
|
onClick: () => {
|
|
@@ -8211,7 +8663,7 @@ const InputWithHelpText = (props) => {
|
|
|
8211
8663
|
const { helpText, children, severity } = props;
|
|
8212
8664
|
return /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "1", children: [
|
|
8213
8665
|
children,
|
|
8214
|
-
/* @__PURE__ */ jsx(Flex$1, { direction: "column", children: /* @__PURE__ */ jsx(Text$1, { size: "1", severity, className: styles$
|
|
8666
|
+
/* @__PURE__ */ jsx(Flex$1, { direction: "column", children: /* @__PURE__ */ jsx(Text$1, { size: "1", severity, className: styles$c.description, children: helpText }) })
|
|
8215
8667
|
] });
|
|
8216
8668
|
};
|
|
8217
8669
|
const InputWithLabelAndHelpText = (props) => {
|
|
@@ -8445,6 +8897,9 @@ function RiArrowUpLine(props) {
|
|
|
8445
8897
|
function RiCalendarLine(props) {
|
|
8446
8898
|
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "d": "M9 1V3H15V1H17V3H21C21.5523 3 22 3.44772 22 4V20C22 20.5523 21.5523 21 21 21H3C2.44772 21 2 20.5523 2 20V4C2 3.44772 2.44772 3 3 3H7V1H9ZM20 11H4V19H20V11ZM7 5H4V9H20V5H17V7H15V5H9V7H7V5Z" }, "child": [] }] })(props);
|
|
8447
8899
|
}
|
|
8900
|
+
function RiQrCodeLine(props) {
|
|
8901
|
+
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "d": "M16 17V16H13V13H16V15H18V17H17V19H15V21H13V18H15V17H16ZM21 21H17V19H19V17H21V21ZM3 3H11V11H3V3ZM5 5V9H9V5H5ZM13 3H21V11H13V3ZM15 5V9H19V5H15ZM3 13H11V21H3V13ZM5 15V19H9V15H5ZM18 13H21V15H18V13ZM6 6H8V8H6V6ZM6 16H8V18H6V16ZM16 6H18V8H16V6Z" }, "child": [] }] })(props);
|
|
8902
|
+
}
|
|
8448
8903
|
function RiFileCopyLine(props) {
|
|
8449
8904
|
return GenIcon({ "tag": "svg", "attr": { "viewBox": "0 0 24 24", "fill": "currentColor" }, "child": [{ "tag": "path", "attr": { "d": "M6.9998 6V3C6.9998 2.44772 7.44752 2 7.9998 2H19.9998C20.5521 2 20.9998 2.44772 20.9998 3V17C20.9998 17.5523 20.5521 18 19.9998 18H16.9998V20.9991C16.9998 21.5519 16.5499 22 15.993 22H4.00666C3.45059 22 3 21.5554 3 20.9991L3.0026 7.00087C3.0027 6.44811 3.45264 6 4.00942 6H6.9998ZM5.00242 8L5.00019 20H14.9998V8H5.00242ZM8.9998 6H16.9998V16H18.9998V4H8.9998V6Z" }, "child": [] }] })(props);
|
|
8450
8905
|
}
|
|
@@ -9348,9 +9803,9 @@ const Inset = React.forwardRef((props, forwardedRef) => {
|
|
|
9348
9803
|
return React.createElement("div", { ...insetProps, ref: forwardedRef, className: classNames("rt-Inset", className, withBreakpoints(side, "rt-r-side"), withBreakpoints(clip, "rt-r-clip"), withBreakpoints(p, "rt-r-p"), withBreakpoints(px, "rt-r-px"), withBreakpoints(py, "rt-r-py"), withBreakpoints(pt, "rt-r-pt"), withBreakpoints(pr, "rt-r-pr"), withBreakpoints(pb, "rt-r-pb"), withBreakpoints(pl, "rt-r-pl"), withMarginProps(marginProps)) });
|
|
9349
9804
|
});
|
|
9350
9805
|
Inset.displayName = "Inset";
|
|
9351
|
-
const sizes$
|
|
9806
|
+
const sizes$8 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
9352
9807
|
const headingPropDefs = {
|
|
9353
|
-
size: { type: "enum", values: sizes$
|
|
9808
|
+
size: { type: "enum", values: sizes$8, default: "6", responsive: true },
|
|
9354
9809
|
weight: { ...weightProp, default: "bold" },
|
|
9355
9810
|
align: alignProp,
|
|
9356
9811
|
trim: trimProp,
|
|
@@ -9363,9 +9818,9 @@ const Heading = React.forwardRef((props, forwardedRef) => {
|
|
|
9363
9818
|
return React.createElement($5e63c961fc1ce211$export$8c6ed5c666ac1360, { "data-accent-color": color, ...headingProps, ref: forwardedRef, className: classNames("rt-Heading", className, withBreakpoints(size, "rt-r-size"), withBreakpoints(weight, "rt-r-weight"), withBreakpoints(align, "rt-r-ta"), withBreakpoints(trim, "rt-r-lt"), { "rt-high-contrast": highContrast }, withMarginProps(marginProps)) }, asChild ? children : React.createElement(Tag, null, children));
|
|
9364
9819
|
});
|
|
9365
9820
|
Heading.displayName = "Heading";
|
|
9366
|
-
const sizes$
|
|
9821
|
+
const sizes$7 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
9367
9822
|
const textPropDefs = {
|
|
9368
|
-
size: { type: "enum", values: sizes$
|
|
9823
|
+
size: { type: "enum", values: sizes$7, default: void 0, responsive: true },
|
|
9369
9824
|
weight: weightProp,
|
|
9370
9825
|
align: alignProp,
|
|
9371
9826
|
trim: trimProp,
|
|
@@ -9378,6 +9833,21 @@ const Text = React.forwardRef((props, forwardedRef) => {
|
|
|
9378
9833
|
return React.createElement($5e63c961fc1ce211$export$8c6ed5c666ac1360, { "data-accent-color": color, ...textProps, ref: forwardedRef, className: classNames("rt-Text", className, withBreakpoints(size, "rt-r-size"), withBreakpoints(weight, "rt-r-weight"), withBreakpoints(align, "rt-r-ta"), withBreakpoints(trim, "rt-r-lt"), { "rt-high-contrast": highContrast }, withMarginProps(marginProps)) }, asChild ? children : React.createElement(Tag, null, children));
|
|
9379
9834
|
});
|
|
9380
9835
|
Text.displayName = "Text";
|
|
9836
|
+
const sizes$6 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
9837
|
+
const variants$4 = ["solid", "soft", "outline", "ghost"];
|
|
9838
|
+
const codePropDefs = {
|
|
9839
|
+
size: { type: "enum", values: sizes$6, default: void 0, responsive: true },
|
|
9840
|
+
variant: { type: "enum", values: variants$4, default: "soft" },
|
|
9841
|
+
weight: weightProp,
|
|
9842
|
+
color: colorProp,
|
|
9843
|
+
highContrast: highContrastProp
|
|
9844
|
+
};
|
|
9845
|
+
const Code = React.forwardRef((props, forwardedRef) => {
|
|
9846
|
+
const { rest: marginRest, ...marginProps } = extractMarginProps(props);
|
|
9847
|
+
const { className, size = codePropDefs.size.default, variant = codePropDefs.variant.default, weight = codePropDefs.weight.default, color = codePropDefs.color.default, highContrast = codePropDefs.highContrast.default, ...codeProps } = marginRest;
|
|
9848
|
+
return React.createElement("code", { "data-accent-color": color, ...codeProps, ref: forwardedRef, className: classNames("rt-Code", className, withBreakpoints(size, "rt-r-size"), `rt-variant-${variant}`, withBreakpoints(weight, "rt-r-weight"), { "rt-high-contrast": highContrast }, withMarginProps(marginProps)) });
|
|
9849
|
+
});
|
|
9850
|
+
Code.displayName = "Code";
|
|
9381
9851
|
const Em = React.forwardRef((props, forwardedRef) => React.createElement("em", { ...props, ref: forwardedRef, className: classNames("rt-Em", props.className) }));
|
|
9382
9852
|
Em.displayName = "Em";
|
|
9383
9853
|
const Strong = React.forwardRef((props, forwardedRef) => React.createElement("strong", { ...props, ref: forwardedRef, className: classNames("rt-Strong", props.className) }));
|
|
@@ -11768,7 +12238,7 @@ __publicField(StringOrTextField, "_validateMax", (path) => (value, allValues) =>
|
|
|
11768
12238
|
});
|
|
11769
12239
|
const clickableLinkContainer = "_clickableLinkContainer_1ace7_1";
|
|
11770
12240
|
const TextFieldInputCopy = "_TextFieldInputCopy_1ace7_5";
|
|
11771
|
-
const styles$
|
|
12241
|
+
const styles$b = {
|
|
11772
12242
|
clickableLinkContainer,
|
|
11773
12243
|
TextFieldInputCopy
|
|
11774
12244
|
};
|
|
@@ -11797,13 +12267,13 @@ const StringInput = memo((props) => {
|
|
|
11797
12267
|
placeholder: field.placeholder,
|
|
11798
12268
|
color
|
|
11799
12269
|
}
|
|
11800
|
-
) : /* @__PURE__ */ jsxs(TextField$1.Root, { className: styles$
|
|
12270
|
+
) : /* @__PURE__ */ jsxs(TextField$1.Root, { className: styles$b.clickableLinkContainer, children: [
|
|
11801
12271
|
/* @__PURE__ */ jsx(
|
|
11802
12272
|
"div",
|
|
11803
12273
|
{
|
|
11804
12274
|
className: classNames$1(
|
|
11805
12275
|
"rt-TextFieldInput rt-r-size-2 rt-variant-surface",
|
|
11806
|
-
styles$
|
|
12276
|
+
styles$b.TextFieldInputCopy
|
|
11807
12277
|
),
|
|
11808
12278
|
children: /* @__PURE__ */ jsx(
|
|
11809
12279
|
Linkify,
|
|
@@ -12375,8 +12845,7 @@ class BaseSelectField extends BaseField {
|
|
|
12375
12845
|
description: "List possible options for the user to select from.",
|
|
12376
12846
|
required: true,
|
|
12377
12847
|
identifier: `${path}options`,
|
|
12378
|
-
minimum_length: 2
|
|
12379
|
-
maximum_length: 20
|
|
12848
|
+
minimum_length: 2
|
|
12380
12849
|
}),
|
|
12381
12850
|
showDirectly: true
|
|
12382
12851
|
}
|
|
@@ -12495,6 +12964,158 @@ __publicField(_MultiSelectField, "fieldTypeName", "Multi-select");
|
|
|
12495
12964
|
__publicField(_MultiSelectField, "fieldTypeDescription", "Allows the user to select a multiple options from a list of options.");
|
|
12496
12965
|
__publicField(_MultiSelectField, "Icon", RiCheckboxLine);
|
|
12497
12966
|
let MultiSelectField = _MultiSelectField;
|
|
12967
|
+
const QrScannerWrapper = "_QrScannerWrapper_1puz3_1";
|
|
12968
|
+
const styles$a = {
|
|
12969
|
+
QrScannerWrapper
|
|
12970
|
+
};
|
|
12971
|
+
const QrInput = memo((props) => {
|
|
12972
|
+
const [{ inputId, labelId, label, helpText, size, severity, showInputOnly, field, fieldProps }, rest] = useFormikInput(props);
|
|
12973
|
+
const [showQrScanner, setShowQrScanner] = useState(false);
|
|
12974
|
+
const value = fieldProps.value;
|
|
12975
|
+
const handleQrScan = useCallback(
|
|
12976
|
+
(data) => {
|
|
12977
|
+
fieldProps.onChange({ target: { value: data } });
|
|
12978
|
+
setShowQrScanner(false);
|
|
12979
|
+
},
|
|
12980
|
+
[fieldProps]
|
|
12981
|
+
);
|
|
12982
|
+
const handleClearScanResult = useCallback(() => {
|
|
12983
|
+
fieldProps.onChange({ target: { value: "" } });
|
|
12984
|
+
}, [fieldProps]);
|
|
12985
|
+
const handleScanButtonClicked = useCallback(() => {
|
|
12986
|
+
setShowQrScanner(true);
|
|
12987
|
+
}, []);
|
|
12988
|
+
const handleQrScannerClose = useCallback(() => {
|
|
12989
|
+
setShowQrScanner(false);
|
|
12990
|
+
}, []);
|
|
12991
|
+
return /* @__PURE__ */ jsx(InputWithLabelAndHelpText, { helpText, severity, children: /* @__PURE__ */ jsxs(
|
|
12992
|
+
InputWithLabel,
|
|
12993
|
+
{
|
|
12994
|
+
size,
|
|
12995
|
+
severity,
|
|
12996
|
+
inputId,
|
|
12997
|
+
labelId,
|
|
12998
|
+
label: showInputOnly ? label : "",
|
|
12999
|
+
image: showInputOnly ? void 0 : field.image,
|
|
13000
|
+
flexProps: { direction: "column", justify: "start", align: "start", gap: "1" },
|
|
13001
|
+
children: [
|
|
13002
|
+
/* @__PURE__ */ jsx(
|
|
13003
|
+
Overlay,
|
|
13004
|
+
{
|
|
13005
|
+
open: showQrScanner,
|
|
13006
|
+
content: () => /* @__PURE__ */ jsx(QrScanner, { onQrScan: handleQrScan, onClose: handleQrScannerClose }),
|
|
13007
|
+
onOpenChange: setShowQrScanner
|
|
13008
|
+
}
|
|
13009
|
+
),
|
|
13010
|
+
/* @__PURE__ */ jsxs(Flex, { width: "max-content", gap: "1", align: "center", children: [
|
|
13011
|
+
/* @__PURE__ */ jsxs(Button, { ...rest, variant: "soft", onClick: handleScanButtonClicked, children: [
|
|
13012
|
+
/* @__PURE__ */ jsx(RiIcon, { icon: "RiQrCodeLine" }),
|
|
13013
|
+
"Scan"
|
|
13014
|
+
] }),
|
|
13015
|
+
value && /* @__PURE__ */ jsx(Text, { color: "jade", size: "1", children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiCheckLine", style: { verticalAlign: "bottom" } }) })
|
|
13016
|
+
] }),
|
|
13017
|
+
value && /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Flex, { width: "max-content", gap: "2", align: "center", children: [
|
|
13018
|
+
/* @__PURE__ */ jsx(Code, { color: "gray", highContrast: true, children: value }),
|
|
13019
|
+
/* @__PURE__ */ jsx(
|
|
13020
|
+
IconButton,
|
|
13021
|
+
{
|
|
13022
|
+
severity: "info",
|
|
13023
|
+
variant: "ghost",
|
|
13024
|
+
"aria-label": "delete",
|
|
13025
|
+
size: "small",
|
|
13026
|
+
onClick: handleClearScanResult,
|
|
13027
|
+
children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiCloseLine" })
|
|
13028
|
+
}
|
|
13029
|
+
)
|
|
13030
|
+
] }) })
|
|
13031
|
+
]
|
|
13032
|
+
}
|
|
13033
|
+
) });
|
|
13034
|
+
});
|
|
13035
|
+
QrInput.displayName = "QrInput";
|
|
13036
|
+
const QrScanner = memo((props) => {
|
|
13037
|
+
const { onQrScan, onClose } = props;
|
|
13038
|
+
const videoRef = useRef(null);
|
|
13039
|
+
const [isScannerLoading, setIsScannerLoading] = useState(false);
|
|
13040
|
+
useEffect(() => {
|
|
13041
|
+
if (!videoRef.current)
|
|
13042
|
+
return;
|
|
13043
|
+
const qrScanner = new QrScannerAPI(
|
|
13044
|
+
videoRef.current,
|
|
13045
|
+
(result) => {
|
|
13046
|
+
const data = result.data;
|
|
13047
|
+
onQrScan(data);
|
|
13048
|
+
qrScanner.destroy();
|
|
13049
|
+
},
|
|
13050
|
+
{
|
|
13051
|
+
highlightCodeOutline: true,
|
|
13052
|
+
highlightScanRegion: true,
|
|
13053
|
+
maxScansPerSecond: 1
|
|
13054
|
+
}
|
|
13055
|
+
);
|
|
13056
|
+
setIsScannerLoading(true);
|
|
13057
|
+
qrScanner.start().then(() => {
|
|
13058
|
+
setIsScannerLoading(false);
|
|
13059
|
+
}).catch(() => {
|
|
13060
|
+
setIsScannerLoading(false);
|
|
13061
|
+
});
|
|
13062
|
+
}, [onQrScan]);
|
|
13063
|
+
return /* @__PURE__ */ jsxs(
|
|
13064
|
+
Flex,
|
|
13065
|
+
{
|
|
13066
|
+
className: styles$a.QrScannerWrapper,
|
|
13067
|
+
width: "100%",
|
|
13068
|
+
height: "100%",
|
|
13069
|
+
direction: "column",
|
|
13070
|
+
gap: "2",
|
|
13071
|
+
justify: "center",
|
|
13072
|
+
position: "relative",
|
|
13073
|
+
children: [
|
|
13074
|
+
/* @__PURE__ */ jsx(Flex, { width: "100%", position: "absolute", top: "0", p: "2", children: /* @__PURE__ */ jsx(IconButton, { "aria-label": "close", variant: "soft", severity: "info", highContrast: true, onClick: onClose, children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiCloseLine" }) }) }),
|
|
13075
|
+
/* @__PURE__ */ jsxs(Box, { style: { maxWidth: "100%", maxHeight: "100%" }, position: "relative", children: [
|
|
13076
|
+
/* @__PURE__ */ jsx("video", { ref: videoRef, style: { width: "100%", height: "100%" } }),
|
|
13077
|
+
isScannerLoading && /* @__PURE__ */ jsx(
|
|
13078
|
+
Flex,
|
|
13079
|
+
{
|
|
13080
|
+
position: "absolute",
|
|
13081
|
+
inset: "0",
|
|
13082
|
+
style: { background: "var(--color-background)" },
|
|
13083
|
+
justify: "center",
|
|
13084
|
+
align: "center",
|
|
13085
|
+
children: /* @__PURE__ */ jsx(Spinner, {})
|
|
13086
|
+
}
|
|
13087
|
+
)
|
|
13088
|
+
] })
|
|
13089
|
+
]
|
|
13090
|
+
}
|
|
13091
|
+
);
|
|
13092
|
+
});
|
|
13093
|
+
QrScanner.displayName = "QrScanner";
|
|
13094
|
+
const emptyQrField = {
|
|
13095
|
+
...emptyBaseField,
|
|
13096
|
+
type: "qr"
|
|
13097
|
+
};
|
|
13098
|
+
const _QrField = class _QrField extends BaseField {
|
|
13099
|
+
constructor(options) {
|
|
13100
|
+
super({ ...options, type: "qr" });
|
|
13101
|
+
__publicField(this, "onlyValidateAfterTouched", false);
|
|
13102
|
+
}
|
|
13103
|
+
serialize() {
|
|
13104
|
+
return super._serialize();
|
|
13105
|
+
}
|
|
13106
|
+
static deserialize(data) {
|
|
13107
|
+
if (data.type !== "qr")
|
|
13108
|
+
throw new Error("Type mismatch.");
|
|
13109
|
+
return new _QrField(data);
|
|
13110
|
+
}
|
|
13111
|
+
getInput(props) {
|
|
13112
|
+
return /* @__PURE__ */ jsx(QrInput, { ...props, field: this });
|
|
13113
|
+
}
|
|
13114
|
+
};
|
|
13115
|
+
__publicField(_QrField, "fieldTypeName", "QR");
|
|
13116
|
+
__publicField(_QrField, "fieldTypeDescription", "Used for scanning/reading QR codes.");
|
|
13117
|
+
__publicField(_QrField, "Icon", RiQrCodeLine);
|
|
13118
|
+
let QrField = _QrField;
|
|
12498
13119
|
const FieldInputCloner = memo((props) => {
|
|
12499
13120
|
const { field, ...rest } = props;
|
|
12500
13121
|
const [{ value: identifier }] = useField(field.options.clonedFieldIdentifier);
|
|
@@ -13752,6 +14373,7 @@ const FieldTypeToClsMapping = {
|
|
|
13752
14373
|
text: TextField,
|
|
13753
14374
|
custom: CustomField,
|
|
13754
14375
|
upload: UploadField,
|
|
14376
|
+
qr: QrField,
|
|
13755
14377
|
// TODO: Underscore
|
|
13756
14378
|
"multi-string": MultiStringField,
|
|
13757
14379
|
"multi-select": MultiSelectField
|
|
@@ -13765,6 +14387,7 @@ const FieldTypeToEmptyFieldMapping = {
|
|
|
13765
14387
|
text: emptyTextField,
|
|
13766
14388
|
custom: emptyCustomField,
|
|
13767
14389
|
upload: emptyUploadField,
|
|
14390
|
+
qr: emptyQrField,
|
|
13768
14391
|
// TODO: Underscore
|
|
13769
14392
|
"multi-string": emptyMultiStringField,
|
|
13770
14393
|
"multi-select": emptyMultiSelectField
|
|
@@ -13852,7 +14475,7 @@ const FieldSectionLayout = memo((props) => {
|
|
|
13852
14475
|
return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "3", children: [
|
|
13853
14476
|
/* @__PURE__ */ jsxs(Flex$1, { direction: "column", children: [
|
|
13854
14477
|
/* @__PURE__ */ jsx(Heading, { as: "h3", size: "3", children: label }),
|
|
13855
|
-
/* @__PURE__ */ jsx(Text$1, { className: styles$
|
|
14478
|
+
/* @__PURE__ */ jsx(Text$1, { className: styles$c.description, children: description2 })
|
|
13856
14479
|
] }),
|
|
13857
14480
|
inputs
|
|
13858
14481
|
] }) });
|
|
@@ -14039,7 +14662,7 @@ const initialFormValues = (fields, values) => {
|
|
|
14039
14662
|
};
|
|
14040
14663
|
const useAttachImagesToFormRevisionFields = (revision) => {
|
|
14041
14664
|
const { sdk } = useSDK();
|
|
14042
|
-
const attachments = useAppSelector(
|
|
14665
|
+
const attachments = useAppSelector(selectAttachmentsOfFormRevision((revision == null ? void 0 : revision.offline_id) ?? ""));
|
|
14043
14666
|
return useMemo(() => {
|
|
14044
14667
|
if (!revision || !attachments)
|
|
14045
14668
|
return revision;
|
|
@@ -14095,7 +14718,7 @@ const FormRenderer = memo(
|
|
|
14095
14718
|
[schema.title]
|
|
14096
14719
|
);
|
|
14097
14720
|
const Description = useMemo(
|
|
14098
|
-
() => typeof schema.description === "string" ? /* @__PURE__ */ jsx(Text$1, { className: styles$
|
|
14721
|
+
() => typeof schema.description === "string" ? /* @__PURE__ */ jsx(Text$1, { className: styles$c.description, children: schema.description }) : schema.description,
|
|
14099
14722
|
[schema.description]
|
|
14100
14723
|
);
|
|
14101
14724
|
const inputs = useFieldInputs(schema.fields, { formId: formId2, disabled: readonly });
|
|
@@ -14111,7 +14734,7 @@ const FormRenderer = memo(
|
|
|
14111
14734
|
!hideDescription && Description
|
|
14112
14735
|
] }) }),
|
|
14113
14736
|
inputs,
|
|
14114
|
-
!readonly && /* @__PURE__ */ jsxs(Flex$1, { className: styles$
|
|
14737
|
+
!readonly && /* @__PURE__ */ jsxs(Flex$1, { className: styles$c.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
|
|
14115
14738
|
cancelText && /* @__PURE__ */ jsx(Button, { severity: "info", ...buttonProps, type: "button", onClick: onCancel, children: cancelText }),
|
|
14116
14739
|
/* @__PURE__ */ jsx(Button, { ...buttonProps, type: "submit", disabled: !formik.isValid, children: submitText })
|
|
14117
14740
|
] })
|
|
@@ -14136,7 +14759,7 @@ const FormSubmissionViewer = memo(
|
|
|
14136
14759
|
return formRevisionToSchema(revisionWithImages, { readonly: true });
|
|
14137
14760
|
}, [revisionWithImages]);
|
|
14138
14761
|
const submissionValuesWithAttachments = useMemo(() => {
|
|
14139
|
-
const attachments =
|
|
14762
|
+
const attachments = selectAttachmentsOfFormSubmission(submission.offline_id)(sdk.store.getState()) ?? [];
|
|
14140
14763
|
const downloadedAttachments = {};
|
|
14141
14764
|
for (const attachment of attachments) {
|
|
14142
14765
|
const promise = sdk.files.fetchFileFromUrl(attachment.file, attachment.file_sha1, attachment.file_name);
|
|
@@ -14186,8 +14809,8 @@ const FormBrowser = memo(
|
|
|
14186
14809
|
}
|
|
14187
14810
|
return ret;
|
|
14188
14811
|
}, [filter, maxResults, ownerFilter]);
|
|
14189
|
-
const userForms = useAppSelector(
|
|
14190
|
-
const userFormMapping = useAppSelector(
|
|
14812
|
+
const userForms = useAppSelector(selectFilteredForms(ownerFilterOptions)) ?? [];
|
|
14813
|
+
const userFormMapping = useAppSelector(selectFormMapping);
|
|
14191
14814
|
const attachableUserForms = userForms.filter((form) => !form.component_type);
|
|
14192
14815
|
const attachableUserFormMapping = Object.values(userFormMapping).filter(
|
|
14193
14816
|
(form) => !form.component_type
|
|
@@ -14220,7 +14843,7 @@ const FormBrowser = memo(
|
|
|
14220
14843
|
const handleChange = useCallback((e) => {
|
|
14221
14844
|
setFilter(e.currentTarget.value);
|
|
14222
14845
|
}, []);
|
|
14223
|
-
const numberOfForms = useAppSelector(
|
|
14846
|
+
const numberOfForms = useAppSelector(selectGeneralFormCount) || 0;
|
|
14224
14847
|
const numberOfHiddenForms = numberOfForms - attachableUserForms.length;
|
|
14225
14848
|
const overflowMessage = attachableUserForms.length == maxResults && numberOfHiddenForms > 0 ? `Only the first ${maxResults} results are shown (${numberOfHiddenForms} hidden)` : numberOfHiddenForms > 0 && `${numberOfHiddenForms} hidden forms`;
|
|
14226
14849
|
return /* @__PURE__ */ jsxs(Flex$1, { ref, direction: "column", gap: "2", children: [
|
|
@@ -14314,16 +14937,13 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
14314
14937
|
const { submission, onSubmissionClick, compact, labelType, rowDecorator } = props;
|
|
14315
14938
|
const currentUser = useAppSelector(selectCurrentUser);
|
|
14316
14939
|
const createdBy = useAppSelector(selectUser("created_by" in submission ? submission.created_by : currentUser.id));
|
|
14317
|
-
const dateToUse =
|
|
14318
|
-
const formattedDateTime =
|
|
14319
|
-
hour: "2-digit",
|
|
14320
|
-
minute: "2-digit"
|
|
14321
|
-
}) : getLocalDateString(dateToUse);
|
|
14940
|
+
const dateToUse = submission.submitted_at;
|
|
14941
|
+
const formattedDateTime = getLocalDateString(dateToUse);
|
|
14322
14942
|
const revision = useAppSelector(selectFormRevision(submission.form_revision));
|
|
14323
14943
|
if (!revision) {
|
|
14324
14944
|
throw new Error(`Could not find revision ${submission.form_revision} for submission ${submission.offline_id}.`);
|
|
14325
14945
|
}
|
|
14326
|
-
const latestRevisionNumber = (_a2 = useAppSelector(
|
|
14946
|
+
const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevisionOfForm(revision.form))) == null ? void 0 : _a2.revision;
|
|
14327
14947
|
const creatorProfileSrc = useFileSrc({
|
|
14328
14948
|
file: (createdBy == null ? void 0 : createdBy.profile.file) ?? null,
|
|
14329
14949
|
fileSha1: (createdBy == null ? void 0 : createdBy.profile.file_sha1) ?? null
|
|
@@ -14354,10 +14974,6 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
14354
14974
|
return row;
|
|
14355
14975
|
});
|
|
14356
14976
|
FormSubmissionBrowserEntry.displayName = "FormSubmissionBrowserEntry";
|
|
14357
|
-
const getCreatedAtOrSubmittedAtDate = (submission) => {
|
|
14358
|
-
const date = "created_at" in submission ? submission.created_at : submission.submitted_at;
|
|
14359
|
-
return new Date(date);
|
|
14360
|
-
};
|
|
14361
14977
|
const FormSubmissionBrowser = memo((props) => {
|
|
14362
14978
|
const {
|
|
14363
14979
|
formId: formId2,
|
|
@@ -14371,10 +14987,10 @@ const FormSubmissionBrowser = memo((props) => {
|
|
|
14371
14987
|
if (!!formId2 === !!propSubmissions) {
|
|
14372
14988
|
throw new Error("Either formId or submissions must be provided, but not both.");
|
|
14373
14989
|
}
|
|
14374
|
-
const submissions = useAppSelector(propSubmissions ? () => propSubmissions :
|
|
14990
|
+
const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectFormSubmissionsOfForm(formId2));
|
|
14375
14991
|
const sortedSubmissions = useMemo(
|
|
14376
14992
|
() => submissions == null ? void 0 : submissions.sort((a, b) => {
|
|
14377
|
-
return
|
|
14993
|
+
return a.submitted_at.localeCompare(b.submitted_at);
|
|
14378
14994
|
}),
|
|
14379
14995
|
[submissions]
|
|
14380
14996
|
);
|
|
@@ -15466,12 +16082,12 @@ const FormBuilder = memo(
|
|
|
15466
16082
|
});
|
|
15467
16083
|
const previewSchema = useMemo(() => formRevisionToSchema(formik.values), [formik.values]);
|
|
15468
16084
|
return /* @__PURE__ */ jsx(Tabs.Root, { ref, defaultValue: "edit", children: /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "2", children: [
|
|
15469
|
-
showTabs && /* @__PURE__ */ jsxs(Tabs.List, { className: classNames$1(styles$
|
|
15470
|
-
/* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$
|
|
16085
|
+
showTabs && /* @__PURE__ */ jsxs(Tabs.List, { className: classNames$1(styles$d.tabsList, tabsListClassName), children: [
|
|
16086
|
+
/* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$d.tabTrigger, value: "edit", children: /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "2", children: [
|
|
15471
16087
|
/* @__PURE__ */ jsx(RiIcon, { icon: "RiPencilLine" }),
|
|
15472
16088
|
"Edit"
|
|
15473
16089
|
] }) }),
|
|
15474
|
-
/* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$
|
|
16090
|
+
/* @__PURE__ */ jsx(Tabs.Trigger, { className: styles$d.tabTrigger, value: "preview", children: /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "2", children: [
|
|
15475
16091
|
/* @__PURE__ */ jsx(RiIcon, { icon: "RiEyeLine" }),
|
|
15476
16092
|
"Preview"
|
|
15477
16093
|
] }) })
|
|
@@ -15495,8 +16111,8 @@ const FormBuilder = memo(
|
|
|
15495
16111
|
render: ({ setValue, value, meta }) => /* @__PURE__ */ jsx(InputWithHelpText, { severity: "danger", helpText: meta.error ?? null, children: /* @__PURE__ */ jsx(
|
|
15496
16112
|
Input,
|
|
15497
16113
|
{
|
|
15498
|
-
className: classNames$1(styles$
|
|
15499
|
-
[styles$
|
|
16114
|
+
className: classNames$1(styles$d.title, {
|
|
16115
|
+
[styles$d.error]: meta.error
|
|
15500
16116
|
}),
|
|
15501
16117
|
placeholder: "Form title",
|
|
15502
16118
|
value,
|
|
@@ -15518,7 +16134,7 @@ const FormBuilder = memo(
|
|
|
15518
16134
|
render: ({ setValue, value }) => /* @__PURE__ */ jsx(
|
|
15519
16135
|
TextArea,
|
|
15520
16136
|
{
|
|
15521
|
-
className: styles$
|
|
16137
|
+
className: styles$d.description,
|
|
15522
16138
|
placeholder: "Explain the purpose of this form",
|
|
15523
16139
|
value,
|
|
15524
16140
|
onChange: (event) => {
|
|
@@ -15536,7 +16152,7 @@ const FormBuilder = memo(
|
|
|
15536
16152
|
/* @__PURE__ */ jsx(FieldsEditor, { fieldsOnly }),
|
|
15537
16153
|
/* @__PURE__ */ jsx(Text$1, { severity: "danger", size: "1", children: typeof formik.errors.fields === "string" && formik.errors.fields })
|
|
15538
16154
|
] }),
|
|
15539
|
-
/* @__PURE__ */ jsxs(Flex$1, { className: styles$
|
|
16155
|
+
/* @__PURE__ */ jsxs(Flex$1, { className: styles$d.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
|
|
15540
16156
|
onCancel && /* @__PURE__ */ jsx(Button, { type: "button", variant: "solid", severity: "info", onClick: onCancel, children: "Cancel" }),
|
|
15541
16157
|
/* @__PURE__ */ jsx(Button, { type: "submit", children: "Save form" })
|
|
15542
16158
|
] })
|
|
@@ -15571,6 +16187,9 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
15571
16187
|
NumberInput,
|
|
15572
16188
|
PatchField,
|
|
15573
16189
|
PatchFormProvider,
|
|
16190
|
+
QrField,
|
|
16191
|
+
QrInput,
|
|
16192
|
+
QrScanner,
|
|
15574
16193
|
SelectField,
|
|
15575
16194
|
SelectInput,
|
|
15576
16195
|
StringField,
|
|
@@ -15585,6 +16204,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
15585
16204
|
emptyMultiSelectField,
|
|
15586
16205
|
emptyMultiStringField,
|
|
15587
16206
|
emptyNumberField,
|
|
16207
|
+
emptyQrField,
|
|
15588
16208
|
emptySelectField,
|
|
15589
16209
|
emptyStringField,
|
|
15590
16210
|
emptyTextField,
|
|
@@ -15675,6 +16295,9 @@ export {
|
|
|
15675
16295
|
ProjectFileService,
|
|
15676
16296
|
ProjectService,
|
|
15677
16297
|
ProjectType,
|
|
16298
|
+
QrField,
|
|
16299
|
+
QrInput,
|
|
16300
|
+
QrScanner,
|
|
15678
16301
|
SDKContext,
|
|
15679
16302
|
SDKProvider,
|
|
15680
16303
|
SUPPORTED_IMAGE_FILE_TYPES,
|
|
@@ -15685,6 +16308,7 @@ export {
|
|
|
15685
16308
|
SpreadsheetViewer,
|
|
15686
16309
|
StringField,
|
|
15687
16310
|
StringInput,
|
|
16311
|
+
TeamService,
|
|
15688
16312
|
TextField,
|
|
15689
16313
|
TextInput,
|
|
15690
16314
|
UserFormService,
|
|
@@ -15692,6 +16316,7 @@ export {
|
|
|
15692
16316
|
VerificationCodeType,
|
|
15693
16317
|
WorkspaceService,
|
|
15694
16318
|
YELLOW,
|
|
16319
|
+
_selectLatestFormRevision,
|
|
15695
16320
|
_setLatestRetryTime,
|
|
15696
16321
|
acceptProjectInvite,
|
|
15697
16322
|
addActiveProjectFormSubmissionsCount,
|
|
@@ -15709,6 +16334,16 @@ export {
|
|
|
15709
16334
|
addDocuments,
|
|
15710
16335
|
addEmailDomain,
|
|
15711
16336
|
addFavouriteProjectId,
|
|
16337
|
+
addForm,
|
|
16338
|
+
addFormRevision,
|
|
16339
|
+
addFormRevisionAttachment,
|
|
16340
|
+
addFormRevisionAttachments,
|
|
16341
|
+
addFormRevisions,
|
|
16342
|
+
addFormSubmission,
|
|
16343
|
+
addFormSubmissionAttachment,
|
|
16344
|
+
addFormSubmissionAttachments,
|
|
16345
|
+
addFormSubmissions,
|
|
16346
|
+
addForms,
|
|
15712
16347
|
addIssue,
|
|
15713
16348
|
addIssueAttachment,
|
|
15714
16349
|
addIssueAttachments,
|
|
@@ -15728,14 +16363,8 @@ export {
|
|
|
15728
16363
|
addStageCompletion,
|
|
15729
16364
|
addStageCompletions,
|
|
15730
16365
|
addStages,
|
|
16366
|
+
addTeam,
|
|
15731
16367
|
addToRecentIssues,
|
|
15732
|
-
addUserForm,
|
|
15733
|
-
addUserFormRevision,
|
|
15734
|
-
addUserFormRevisionAttachment,
|
|
15735
|
-
addUserFormRevisions,
|
|
15736
|
-
addUserFormSubmissionAttachment,
|
|
15737
|
-
addUserFormSubmissions,
|
|
15738
|
-
addUserForms,
|
|
15739
16368
|
addUsers,
|
|
15740
16369
|
addWorkspace,
|
|
15741
16370
|
areArraysEqual,
|
|
@@ -15756,6 +16385,7 @@ export {
|
|
|
15756
16385
|
componentStageSlice,
|
|
15757
16386
|
componentTypeReducer,
|
|
15758
16387
|
componentTypeSlice,
|
|
16388
|
+
constructUploadedFilePayloads,
|
|
15759
16389
|
coordinatesAreEqual,
|
|
15760
16390
|
coordinatesToLiteral,
|
|
15761
16391
|
coordinatesToPointGeometry,
|
|
@@ -15766,12 +16396,17 @@ export {
|
|
|
15766
16396
|
defaultBadgeColor,
|
|
15767
16397
|
defaultStore,
|
|
15768
16398
|
deleteComponentType,
|
|
16399
|
+
deleteForm,
|
|
16400
|
+
deleteFormRevision,
|
|
16401
|
+
deleteFormRevisionAttachment,
|
|
16402
|
+
deleteFormRevisionAttachments,
|
|
16403
|
+
deleteFormRevisions,
|
|
16404
|
+
deleteFormSubmission,
|
|
16405
|
+
deleteFormSubmissionAttachment,
|
|
16406
|
+
deleteFormSubmissionAttachments,
|
|
16407
|
+
deleteFormSubmissions,
|
|
15769
16408
|
deleteProject,
|
|
15770
|
-
|
|
15771
|
-
deleteUserFormRevision,
|
|
15772
|
-
deleteUserFormRevisions,
|
|
15773
|
-
deleteUserFormSubmission,
|
|
15774
|
-
deleteUserFormSubmissions,
|
|
16409
|
+
deleteTeam,
|
|
15775
16410
|
dequeue,
|
|
15776
16411
|
deserialize,
|
|
15777
16412
|
deserializeField,
|
|
@@ -15789,6 +16424,7 @@ export {
|
|
|
15789
16424
|
emptyMultiSelectField,
|
|
15790
16425
|
emptyMultiStringField,
|
|
15791
16426
|
emptyNumberField,
|
|
16427
|
+
emptyQrField,
|
|
15792
16428
|
emptySelectField,
|
|
15793
16429
|
emptyStringField,
|
|
15794
16430
|
emptyTextField,
|
|
@@ -15800,7 +16436,13 @@ export {
|
|
|
15800
16436
|
fileSlice,
|
|
15801
16437
|
fileToBlob,
|
|
15802
16438
|
flipCoordinates,
|
|
16439
|
+
formReducer,
|
|
16440
|
+
formRevisionReducer,
|
|
15803
16441
|
formRevisionToSchema,
|
|
16442
|
+
formRevisionsSlice,
|
|
16443
|
+
formSlice,
|
|
16444
|
+
formSubmissionReducer,
|
|
16445
|
+
formSubmissionSlice,
|
|
15804
16446
|
index as forms,
|
|
15805
16447
|
fullComponentMarkerSize,
|
|
15806
16448
|
generateBadgeColors,
|
|
@@ -15928,6 +16570,8 @@ export {
|
|
|
15928
16570
|
selectAttachmentsOfComponentTypeByType,
|
|
15929
16571
|
selectAttachmentsOfDocument,
|
|
15930
16572
|
selectAttachmentsOfDocumentByType,
|
|
16573
|
+
selectAttachmentsOfFormRevision,
|
|
16574
|
+
selectAttachmentsOfFormSubmission,
|
|
15931
16575
|
selectAttachmentsOfIssue,
|
|
15932
16576
|
selectAttachmentsOfIssueByType,
|
|
15933
16577
|
selectAttachmentsOfProject,
|
|
@@ -15945,11 +16589,9 @@ export {
|
|
|
15945
16589
|
selectComponent,
|
|
15946
16590
|
selectComponentAttachment,
|
|
15947
16591
|
selectComponentAttachmentMapping,
|
|
15948
|
-
selectComponentSubmissionMapping,
|
|
15949
16592
|
selectComponentType,
|
|
15950
16593
|
selectComponentTypeAttachment,
|
|
15951
16594
|
selectComponentTypeAttachmentMapping,
|
|
15952
|
-
selectComponentTypeForm,
|
|
15953
16595
|
selectComponentTypeFromComponent,
|
|
15954
16596
|
selectComponentTypeFromComponents,
|
|
15955
16597
|
selectComponentTypeStagesMapping,
|
|
@@ -15979,8 +16621,24 @@ export {
|
|
|
15979
16621
|
selectExpandedSections,
|
|
15980
16622
|
selectFavouriteProjects,
|
|
15981
16623
|
selectFileAttachmentsOfIssue,
|
|
15982
|
-
|
|
16624
|
+
selectFilteredForms,
|
|
16625
|
+
selectForm,
|
|
16626
|
+
selectFormMapping,
|
|
16627
|
+
selectFormOfComponentType,
|
|
15983
16628
|
selectFormRevision,
|
|
16629
|
+
selectFormRevisionMapping,
|
|
16630
|
+
selectFormRevisions,
|
|
16631
|
+
selectFormRevisionsOfForm,
|
|
16632
|
+
selectFormSubmission,
|
|
16633
|
+
selectFormSubmissionAttachmentsMapping,
|
|
16634
|
+
selectFormSubmissions,
|
|
16635
|
+
selectFormSubmissionsByComponents,
|
|
16636
|
+
selectFormSubmissionsMapping,
|
|
16637
|
+
selectFormSubmissionsOfComponent,
|
|
16638
|
+
selectFormSubmissionsOfForm,
|
|
16639
|
+
selectFormSubmissionsOfIssue,
|
|
16640
|
+
selectFormsCount,
|
|
16641
|
+
selectGeneralFormCount,
|
|
15984
16642
|
selectHiddenCategoryCount,
|
|
15985
16643
|
selectHiddenComponentTypeIds,
|
|
15986
16644
|
selectIsFetchingInitialData,
|
|
@@ -15995,10 +16653,10 @@ export {
|
|
|
15995
16653
|
selectIssueUpdateMapping,
|
|
15996
16654
|
selectIssueUpdatesOfIssue,
|
|
15997
16655
|
selectIssues,
|
|
15998
|
-
|
|
16656
|
+
selectLatestFormRevisionByForm,
|
|
16657
|
+
selectLatestFormRevisionOfForm,
|
|
16658
|
+
selectLatestFormRevisionsOfComponentTypes,
|
|
15999
16659
|
selectLatestRetryTime,
|
|
16000
|
-
selectLatestRevisionByFormId,
|
|
16001
|
-
selectLatestRevisionsFromComponentTypeIds,
|
|
16002
16660
|
selectLicense,
|
|
16003
16661
|
selectLicenseForProject,
|
|
16004
16662
|
selectLicenses,
|
|
@@ -16007,8 +16665,6 @@ export {
|
|
|
16007
16665
|
selectMapStyle,
|
|
16008
16666
|
selectNumberOfComponentTypesMatchingCaseInsensitiveName,
|
|
16009
16667
|
selectNumberOfComponentsOfComponentType,
|
|
16010
|
-
selectNumberOfGeneralUserForms,
|
|
16011
|
-
selectNumberOfUserForms,
|
|
16012
16668
|
selectOrganization,
|
|
16013
16669
|
selectOrganizationAccess,
|
|
16014
16670
|
selectOrganizationAccessForUser,
|
|
@@ -16036,8 +16692,6 @@ export {
|
|
|
16036
16692
|
selectRecentIssuesAsSearchResults,
|
|
16037
16693
|
selectRecentProjects,
|
|
16038
16694
|
selectRehydrated,
|
|
16039
|
-
selectRevisionAttachments,
|
|
16040
|
-
selectRevisionsForForm,
|
|
16041
16695
|
selectRootDocuments,
|
|
16042
16696
|
selectShowTooltips,
|
|
16043
16697
|
selectSortedEmailDomains,
|
|
@@ -16052,16 +16706,15 @@ export {
|
|
|
16052
16706
|
selectStagesFromComponentType,
|
|
16053
16707
|
selectStagesFromComponentTypeIds,
|
|
16054
16708
|
selectStagesFromStageIds,
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16058
|
-
|
|
16709
|
+
selectTeam,
|
|
16710
|
+
selectTeams,
|
|
16711
|
+
selectTeamsMapping,
|
|
16712
|
+
selectTeamsOfOrganization,
|
|
16713
|
+
selectTeamsOfUser,
|
|
16059
16714
|
selectUploadUrl,
|
|
16060
16715
|
selectUsedColors,
|
|
16061
16716
|
selectUser,
|
|
16062
|
-
|
|
16063
|
-
selectUserFormMapping,
|
|
16064
|
-
selectUserFormSubmission,
|
|
16717
|
+
selectUserFormRevisionAttachmentsMapping,
|
|
16065
16718
|
selectUsersAsMapping,
|
|
16066
16719
|
selectVisibleStatuses,
|
|
16067
16720
|
selectVisibleUserIds,
|
|
@@ -16088,6 +16741,13 @@ export {
|
|
|
16088
16741
|
setEnableClustering,
|
|
16089
16742
|
setEnableDuplicateIssues,
|
|
16090
16743
|
setEnablePlacementMode,
|
|
16744
|
+
setFormRevision,
|
|
16745
|
+
setFormRevisionAttachments,
|
|
16746
|
+
setFormRevisions,
|
|
16747
|
+
setFormSubmission,
|
|
16748
|
+
setFormSubmissionAttachments,
|
|
16749
|
+
setFormSubmissions,
|
|
16750
|
+
setForms,
|
|
16091
16751
|
setIsFetchingInitialData,
|
|
16092
16752
|
setIsImportingProjectFile,
|
|
16093
16753
|
setIsLoading,
|
|
@@ -16109,12 +16769,11 @@ export {
|
|
|
16109
16769
|
setSectionExpanded,
|
|
16110
16770
|
setShowTooltips,
|
|
16111
16771
|
setStageCompletions,
|
|
16772
|
+
setTeam,
|
|
16773
|
+
setTeams,
|
|
16112
16774
|
setTokens,
|
|
16113
16775
|
setTourStep,
|
|
16114
16776
|
setUploadUrl,
|
|
16115
|
-
setUserFormRevisionAttachments,
|
|
16116
|
-
setUserFormSubmissionAttachments,
|
|
16117
|
-
setUserFormSubmissions,
|
|
16118
16777
|
setUsers,
|
|
16119
16778
|
setVisibleStatuses,
|
|
16120
16779
|
setVisibleUserIds,
|
|
@@ -16125,6 +16784,8 @@ export {
|
|
|
16125
16784
|
slugify,
|
|
16126
16785
|
spacesToDashesLower,
|
|
16127
16786
|
successColor,
|
|
16787
|
+
teamReducer,
|
|
16788
|
+
teamSlice,
|
|
16128
16789
|
toFileNameSafeString,
|
|
16129
16790
|
toOfflineIdRecord,
|
|
16130
16791
|
toggleComponentTypeVisibility,
|
|
@@ -16139,15 +16800,18 @@ export {
|
|
|
16139
16800
|
updateComponentTypeAttachment,
|
|
16140
16801
|
updateDocumentAttachment,
|
|
16141
16802
|
updateDocuments,
|
|
16803
|
+
updateFormSubmission,
|
|
16804
|
+
updateFormSubmissionAttachments,
|
|
16805
|
+
updateFormSubmissions,
|
|
16142
16806
|
updateIssue,
|
|
16143
16807
|
updateIssueAttachment,
|
|
16144
16808
|
updateLicense,
|
|
16145
16809
|
updateOrCreateProject,
|
|
16146
|
-
updateOrCreateUserFormSubmission,
|
|
16147
16810
|
updateOrganizationAccess,
|
|
16148
16811
|
updateProjectAccess,
|
|
16149
16812
|
updateProjectAttachment,
|
|
16150
16813
|
updateStages,
|
|
16814
|
+
updateTeam,
|
|
16151
16815
|
useAppDispatch,
|
|
16152
16816
|
useAppSelector,
|
|
16153
16817
|
useFieldInput,
|
|
@@ -16157,8 +16821,6 @@ export {
|
|
|
16157
16821
|
useFormikInput,
|
|
16158
16822
|
useMemoCompare,
|
|
16159
16823
|
useSDK,
|
|
16160
|
-
userFormReducer,
|
|
16161
|
-
userFormSlice,
|
|
16162
16824
|
userReducer,
|
|
16163
16825
|
userSlice,
|
|
16164
16826
|
valueIsFile,
|