@overmap-ai/core 1.0.51-add-submitted-at-to-form-revisions.0 → 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 +1122 -459
- package/dist/overmap-core.js.map +1 -1
- package/dist/overmap-core.umd.cjs +1123 -461
- 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 = {};
|
|
@@ -3781,60 +3980,24 @@ const selectComponentSubmissionMapping = createSelector(
|
|
|
3781
3980
|
return componentSubmissionMapping;
|
|
3782
3981
|
}
|
|
3783
3982
|
);
|
|
3784
|
-
const
|
|
3785
|
-
return state.
|
|
3786
|
-
};
|
|
3787
|
-
const
|
|
3788
|
-
createSelector(
|
|
3789
|
-
[selectUserFormMapping, (_state, componentTypeId) => componentTypeId],
|
|
3790
|
-
(userForms, componentTypeId) => {
|
|
3791
|
-
return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
|
|
3792
|
-
}
|
|
3793
|
-
)
|
|
3794
|
-
);
|
|
3795
|
-
const selectLatestRevisionsFromComponentTypeIds = restructureCreateSelectorWithArgs(
|
|
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
|
});
|
|
@@ -6824,13 +7045,14 @@ class UserFormService extends BaseApiService {
|
|
|
6824
7045
|
};
|
|
6825
7046
|
const currentUser = state.userReducer.currentUser;
|
|
6826
7047
|
const activeWorkspaceId = state.workspaceReducer.activeWorkspaceId;
|
|
7048
|
+
const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
6827
7049
|
const offlineFormPayload = offline({});
|
|
6828
|
-
const offlineRevisionPayload = offline(initialRevision);
|
|
7050
|
+
const offlineRevisionPayload = offline({ ...initialRevision, submitted_at: submittedAt });
|
|
6829
7051
|
const retForm = {
|
|
6830
7052
|
...offlineFormPayload,
|
|
6831
7053
|
index_workspace: activeWorkspaceId,
|
|
6832
7054
|
favorite: true,
|
|
6833
|
-
submitted_at:
|
|
7055
|
+
submitted_at: submittedAt,
|
|
6834
7056
|
created_by: currentUser.id,
|
|
6835
7057
|
...componentTypeId && { component_type: componentTypeId },
|
|
6836
7058
|
...ownerAttrs
|
|
@@ -6841,11 +7063,11 @@ class UserFormService extends BaseApiService {
|
|
|
6841
7063
|
created_by: currentUser.id,
|
|
6842
7064
|
form: retForm.offline_id,
|
|
6843
7065
|
revision: 0,
|
|
6844
|
-
submitted_at:
|
|
7066
|
+
submitted_at: submittedAt
|
|
6845
7067
|
};
|
|
6846
7068
|
const { store } = this.client;
|
|
6847
|
-
store.dispatch(
|
|
6848
|
-
store.dispatch(
|
|
7069
|
+
store.dispatch(addForm(retForm));
|
|
7070
|
+
store.dispatch(addFormRevision(retRevision));
|
|
6849
7071
|
const formPromise = this.enqueueRequest({
|
|
6850
7072
|
description: "Create form",
|
|
6851
7073
|
method: HttpMethod.POST,
|
|
@@ -6863,8 +7085,8 @@ class UserFormService extends BaseApiService {
|
|
|
6863
7085
|
});
|
|
6864
7086
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevisionPayload.offline_id);
|
|
6865
7087
|
void formPromise.catch((e) => {
|
|
6866
|
-
store.dispatch(
|
|
6867
|
-
store.dispatch(
|
|
7088
|
+
store.dispatch(deleteForm(retForm.offline_id));
|
|
7089
|
+
store.dispatch(deleteFormRevision(retRevision.offline_id));
|
|
6868
7090
|
throw e;
|
|
6869
7091
|
});
|
|
6870
7092
|
const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
|
|
@@ -6907,7 +7129,7 @@ class UserFormService extends BaseApiService {
|
|
|
6907
7129
|
form: formId2,
|
|
6908
7130
|
submitted_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
6909
7131
|
};
|
|
6910
|
-
store.dispatch(
|
|
7132
|
+
store.dispatch(addFormRevision(fullRevision));
|
|
6911
7133
|
const promise = this.enqueueRequest({
|
|
6912
7134
|
description: "Create form revision",
|
|
6913
7135
|
method: HttpMethod.PATCH,
|
|
@@ -6921,9 +7143,9 @@ class UserFormService extends BaseApiService {
|
|
|
6921
7143
|
});
|
|
6922
7144
|
const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
|
|
6923
7145
|
void promise.then((result) => {
|
|
6924
|
-
store.dispatch(
|
|
7146
|
+
store.dispatch(setFormRevision(result));
|
|
6925
7147
|
}).catch(() => {
|
|
6926
|
-
store.dispatch(
|
|
7148
|
+
store.dispatch(deleteFormRevision(fullRevision.offline_id));
|
|
6927
7149
|
});
|
|
6928
7150
|
const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
|
|
6929
7151
|
return [fullRevision, settledPromise];
|
|
@@ -6965,19 +7187,19 @@ class UserFormService extends BaseApiService {
|
|
|
6965
7187
|
async delete(formId2) {
|
|
6966
7188
|
const { store } = this.client;
|
|
6967
7189
|
const state = store.getState();
|
|
6968
|
-
const userForm =
|
|
7190
|
+
const userForm = selectForm(formId2)(state);
|
|
6969
7191
|
if (!userForm) {
|
|
6970
7192
|
throw new Error("Expected userForm to exist");
|
|
6971
7193
|
}
|
|
6972
|
-
const userFormSubmissions =
|
|
7194
|
+
const userFormSubmissions = selectFormSubmissionsOfForm(formId2)(state);
|
|
6973
7195
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6974
|
-
store.dispatch(
|
|
7196
|
+
store.dispatch(deleteFormSubmissions(userFormSubmissions.map(({ offline_id }) => offline_id)));
|
|
6975
7197
|
}
|
|
6976
|
-
const userFormRevisions =
|
|
7198
|
+
const userFormRevisions = selectFormRevisionsOfForm(formId2)(state);
|
|
6977
7199
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6978
|
-
store.dispatch(
|
|
7200
|
+
store.dispatch(deleteFormRevisions(userFormRevisions.map(({ offline_id }) => offline_id)));
|
|
6979
7201
|
}
|
|
6980
|
-
store.dispatch(
|
|
7202
|
+
store.dispatch(deleteForm(formId2));
|
|
6981
7203
|
try {
|
|
6982
7204
|
return await this.enqueueRequest({
|
|
6983
7205
|
description: "Delete form",
|
|
@@ -6987,12 +7209,12 @@ class UserFormService extends BaseApiService {
|
|
|
6987
7209
|
blocks: []
|
|
6988
7210
|
});
|
|
6989
7211
|
} catch (e) {
|
|
6990
|
-
store.dispatch(
|
|
7212
|
+
store.dispatch(addForm(userForm));
|
|
6991
7213
|
if (userFormRevisions && userFormRevisions.length > 0) {
|
|
6992
|
-
store.dispatch(
|
|
7214
|
+
store.dispatch(addFormRevisions(userFormRevisions));
|
|
6993
7215
|
}
|
|
6994
7216
|
if (userFormSubmissions && userFormSubmissions.length > 0) {
|
|
6995
|
-
store.dispatch(
|
|
7217
|
+
store.dispatch(addFormSubmissions(userFormSubmissions));
|
|
6996
7218
|
}
|
|
6997
7219
|
throw e;
|
|
6998
7220
|
}
|
|
@@ -7006,16 +7228,15 @@ class UserFormService extends BaseApiService {
|
|
|
7006
7228
|
blockers: [],
|
|
7007
7229
|
blocks: []
|
|
7008
7230
|
});
|
|
7009
|
-
store.dispatch(
|
|
7010
|
-
store.dispatch(
|
|
7011
|
-
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)));
|
|
7012
7234
|
}
|
|
7013
7235
|
}
|
|
7014
7236
|
const isArrayOfFiles = (value) => {
|
|
7015
7237
|
return Array.isArray(value) && value[0] instanceof File;
|
|
7016
7238
|
};
|
|
7017
|
-
const separateFilesFromValues = (
|
|
7018
|
-
const { values } = payload;
|
|
7239
|
+
const separateFilesFromValues = (values) => {
|
|
7019
7240
|
const files = {};
|
|
7020
7241
|
const newValues = {};
|
|
7021
7242
|
for (const key in values) {
|
|
@@ -7030,17 +7251,13 @@ const separateFilesFromValues = (payload) => {
|
|
|
7030
7251
|
newValues[key] = value;
|
|
7031
7252
|
}
|
|
7032
7253
|
}
|
|
7033
|
-
|
|
7034
|
-
...payload,
|
|
7035
|
-
values: newValues
|
|
7036
|
-
};
|
|
7037
|
-
return { payloadWithoutFiles, files };
|
|
7254
|
+
return { values: newValues, files };
|
|
7038
7255
|
};
|
|
7039
7256
|
class UserFormSubmissionService extends BaseApiService {
|
|
7040
7257
|
constructor() {
|
|
7041
7258
|
super(...arguments);
|
|
7042
7259
|
// Attach files to submission, after uploading them to S3
|
|
7043
|
-
__publicField(this, "getAttachFilesPromises", (files,
|
|
7260
|
+
__publicField(this, "getAttachFilesPromises", (files, submission) => {
|
|
7044
7261
|
const { store } = this.client;
|
|
7045
7262
|
return Object.entries(files).map(async ([key, fileArray]) => {
|
|
7046
7263
|
const attachResults = [];
|
|
@@ -7050,24 +7267,27 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7050
7267
|
const [fileProps] = await this.client.files.uploadFileToS3(sha1);
|
|
7051
7268
|
const submissionAttachmentPayload = offline({
|
|
7052
7269
|
...fileProps,
|
|
7053
|
-
submission:
|
|
7270
|
+
submission: submission.offline_id,
|
|
7054
7271
|
field_identifier: key
|
|
7055
7272
|
});
|
|
7056
7273
|
const attach = await this.enqueueRequest({
|
|
7057
7274
|
description: "Attach file to form submission",
|
|
7058
7275
|
method: HttpMethod.POST,
|
|
7059
|
-
url: `/forms/submission/${
|
|
7276
|
+
url: `/forms/submission/${submission.offline_id}/attachments/`,
|
|
7060
7277
|
payload: submissionAttachmentPayload,
|
|
7061
|
-
blockers: [
|
|
7062
|
-
|
|
7063
|
-
|
|
7278
|
+
blockers: [
|
|
7279
|
+
submission.component,
|
|
7280
|
+
submission.component_stage,
|
|
7281
|
+
submission.issue,
|
|
7282
|
+
submission.form_revision
|
|
7283
|
+
].filter((x) => x !== void 0),
|
|
7064
7284
|
blocks: [submissionAttachmentPayload.offline_id]
|
|
7065
7285
|
});
|
|
7066
7286
|
const offlinePayload = {
|
|
7067
7287
|
...submissionAttachmentPayload,
|
|
7068
7288
|
file: URL.createObjectURL(file)
|
|
7069
7289
|
};
|
|
7070
|
-
store.dispatch(
|
|
7290
|
+
store.dispatch(addFormSubmissionAttachment(offlinePayload));
|
|
7071
7291
|
attachResults.push(attach);
|
|
7072
7292
|
}
|
|
7073
7293
|
return attachResults;
|
|
@@ -7081,71 +7301,168 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7081
7301
|
if (!activeProjectId) {
|
|
7082
7302
|
throw new Error("Expected an active project");
|
|
7083
7303
|
}
|
|
7084
|
-
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
|
+
};
|
|
7085
7311
|
const promise = this.enqueueRequest({
|
|
7086
7312
|
description: "Respond to form",
|
|
7087
7313
|
method: HttpMethod.POST,
|
|
7088
7314
|
url: `/forms/revisions/${payload.form_revision}/respond/`,
|
|
7089
|
-
payload: { ...
|
|
7315
|
+
payload: { ...offlineSubmission, project: activeProjectId },
|
|
7090
7316
|
blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
|
|
7091
7317
|
(x) => x !== void 0
|
|
7092
7318
|
),
|
|
7093
7319
|
blocks: [payload.offline_id]
|
|
7094
7320
|
});
|
|
7095
|
-
const attachFilesPromises = this.getAttachFilesPromises(files,
|
|
7096
|
-
|
|
7097
|
-
const fullOfflineResult = {
|
|
7098
|
-
...payload,
|
|
7099
|
-
created_by: state.userReducer.currentUser.id,
|
|
7100
|
-
created_at: now,
|
|
7101
|
-
updated_at: now
|
|
7102
|
-
};
|
|
7103
|
-
const offlineResultWithoutFiles = {
|
|
7104
|
-
...fullOfflineResult,
|
|
7105
|
-
...payloadWithoutFiles
|
|
7106
|
-
};
|
|
7107
|
-
store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
|
|
7321
|
+
const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
|
|
7322
|
+
store.dispatch(addFormSubmission(offlineSubmission));
|
|
7108
7323
|
void promise.then((result) => {
|
|
7109
7324
|
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
7110
|
-
store.dispatch(
|
|
7325
|
+
store.dispatch(setFormSubmission(result));
|
|
7111
7326
|
return result;
|
|
7112
7327
|
}).catch(() => {
|
|
7113
|
-
store.dispatch(
|
|
7328
|
+
store.dispatch(deleteFormSubmission(payload.offline_id));
|
|
7114
7329
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
7115
7330
|
});
|
|
7116
7331
|
const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
7117
|
-
return [
|
|
7332
|
+
return [offlineSubmission, settledPromise];
|
|
7118
7333
|
}
|
|
7119
|
-
|
|
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;
|
|
7120
7338
|
const { store } = this.client;
|
|
7121
|
-
const
|
|
7122
|
-
|
|
7123
|
-
|
|
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
|
+
};
|
|
7124
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);
|
|
7125
7434
|
const attachFilesPromises = this.getAttachFilesPromises(files, submission);
|
|
7126
|
-
const
|
|
7127
|
-
...
|
|
7128
|
-
|
|
7435
|
+
const offlineSubmission = {
|
|
7436
|
+
...submission,
|
|
7437
|
+
values
|
|
7129
7438
|
};
|
|
7130
|
-
store.
|
|
7439
|
+
const submissionToBeUpdated = store.getState().formSubmissionReducer.formSubmissions[submission.offline_id];
|
|
7440
|
+
store.dispatch(updateFormSubmission(offlineSubmission));
|
|
7131
7441
|
const promise = this.enqueueRequest({
|
|
7132
7442
|
description: "Patch form submission",
|
|
7133
7443
|
method: HttpMethod.PATCH,
|
|
7134
7444
|
url: `/forms/submissions/${submission.offline_id}/`,
|
|
7135
|
-
payload:
|
|
7136
|
-
blockers: [
|
|
7445
|
+
payload: offlineSubmission,
|
|
7446
|
+
blockers: [offlineSubmission.issue, offlineSubmission.component, offlineSubmission.component_stage].filter(
|
|
7137
7447
|
(x) => x !== void 0
|
|
7138
7448
|
),
|
|
7139
|
-
blocks: [
|
|
7449
|
+
blocks: [offlineSubmission.offline_id]
|
|
7450
|
+
});
|
|
7451
|
+
promise.then((createdSubmission) => {
|
|
7452
|
+
store.dispatch(setFormSubmission(createdSubmission));
|
|
7453
|
+
}).catch(() => {
|
|
7454
|
+
store.dispatch(setFormSubmission(submissionToBeUpdated));
|
|
7140
7455
|
});
|
|
7141
|
-
return Promise.all([promise, ...attachFilesPromises]).then(() => promise);
|
|
7456
|
+
return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
|
|
7142
7457
|
}
|
|
7143
7458
|
async delete(submissionId) {
|
|
7144
7459
|
const { store } = this.client;
|
|
7145
7460
|
const state = store.getState();
|
|
7146
|
-
const submission = state.
|
|
7147
|
-
|
|
7461
|
+
const submission = state.formSubmissionReducer.formSubmissions[submissionId];
|
|
7462
|
+
const submissionAttachments = selectAttachmentsOfFormSubmission(submissionId)(state);
|
|
7463
|
+
store.dispatch(deleteFormSubmission(submissionId));
|
|
7148
7464
|
store.dispatch(addActiveProjectFormSubmissionsCount(-1));
|
|
7465
|
+
store.dispatch(deleteFormSubmissionAttachments(submissionAttachments.map((x) => x.offline_id)));
|
|
7149
7466
|
try {
|
|
7150
7467
|
return await this.enqueueRequest({
|
|
7151
7468
|
description: "Delete user form submissions",
|
|
@@ -7155,10 +7472,9 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7155
7472
|
blocks: []
|
|
7156
7473
|
});
|
|
7157
7474
|
} catch (e) {
|
|
7158
|
-
|
|
7159
|
-
|
|
7160
|
-
|
|
7161
|
-
}
|
|
7475
|
+
store.dispatch(addActiveProjectFormSubmissionsCount(1));
|
|
7476
|
+
store.dispatch(addFormSubmission(submission));
|
|
7477
|
+
store.dispatch(addFormSubmissionAttachments(submissionAttachments));
|
|
7162
7478
|
throw e;
|
|
7163
7479
|
}
|
|
7164
7480
|
}
|
|
@@ -7172,7 +7488,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7172
7488
|
blockers: [],
|
|
7173
7489
|
blocks: []
|
|
7174
7490
|
});
|
|
7175
|
-
store.dispatch(
|
|
7491
|
+
store.dispatch(setFormSubmissions(submissions));
|
|
7176
7492
|
const attachments = await this.enqueueRequest({
|
|
7177
7493
|
description: "Fetch form attachments",
|
|
7178
7494
|
method: HttpMethod.GET,
|
|
@@ -7180,7 +7496,7 @@ class UserFormSubmissionService extends BaseApiService {
|
|
|
7180
7496
|
blockers: [],
|
|
7181
7497
|
blocks: []
|
|
7182
7498
|
});
|
|
7183
|
-
store.dispatch(
|
|
7499
|
+
store.dispatch(setFormSubmissionAttachments(attachments));
|
|
7184
7500
|
}
|
|
7185
7501
|
}
|
|
7186
7502
|
class WorkspaceService extends BaseApiService {
|
|
@@ -7904,6 +8220,142 @@ class AgentService extends BaseApiService {
|
|
|
7904
8220
|
});
|
|
7905
8221
|
}
|
|
7906
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
|
+
}
|
|
7907
8359
|
class OvermapSDK {
|
|
7908
8360
|
constructor(apiUrl, store) {
|
|
7909
8361
|
__publicField(this, "API_URL");
|
|
@@ -7933,6 +8385,7 @@ class OvermapSDK {
|
|
|
7933
8385
|
__publicField(this, "emailDomains", new EmailDomainsService(this));
|
|
7934
8386
|
__publicField(this, "licenses", new LicenseService(this));
|
|
7935
8387
|
__publicField(this, "documents", new DocumentService(this));
|
|
8388
|
+
__publicField(this, "teams", new TeamService(this));
|
|
7936
8389
|
this.API_URL = apiUrl;
|
|
7937
8390
|
this.store = store;
|
|
7938
8391
|
}
|
|
@@ -7974,7 +8427,7 @@ const tabTrigger = "_tabTrigger_1w0fq_69";
|
|
|
7974
8427
|
const patchfieldBorder = "_patchfieldBorder_1w0fq_73";
|
|
7975
8428
|
const title = "_title_1w0fq_73";
|
|
7976
8429
|
const error = "_error_1w0fq_89";
|
|
7977
|
-
const styles$
|
|
8430
|
+
const styles$d = {
|
|
7978
8431
|
description: description$2,
|
|
7979
8432
|
floatingButtonContainer: floatingButtonContainer$2,
|
|
7980
8433
|
FullScreenImageContainer: FullScreenImageContainer$2,
|
|
@@ -8095,7 +8548,7 @@ const fileName$1 = "_fileName_10o76_31";
|
|
|
8095
8548
|
const longIconButton$1 = "_longIconButton_10o76_36";
|
|
8096
8549
|
const previewImage$1 = "_previewImage_10o76_42";
|
|
8097
8550
|
const FullScreenImage$1 = "_FullScreenImage_10o76_12";
|
|
8098
|
-
const styles$
|
|
8551
|
+
const styles$c = {
|
|
8099
8552
|
description: description$1,
|
|
8100
8553
|
floatingButtonContainer: floatingButtonContainer$1,
|
|
8101
8554
|
FullScreenImageContainer: FullScreenImageContainer$1,
|
|
@@ -8119,7 +8572,7 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8119
8572
|
/* @__PURE__ */ jsx(
|
|
8120
8573
|
"button",
|
|
8121
8574
|
{
|
|
8122
|
-
className: styles$
|
|
8575
|
+
className: styles$c.FullScreenImageContainer,
|
|
8123
8576
|
type: "button",
|
|
8124
8577
|
onClick: () => {
|
|
8125
8578
|
setShowPreview(false);
|
|
@@ -8127,7 +8580,7 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8127
8580
|
children: /* @__PURE__ */ jsx(
|
|
8128
8581
|
"img",
|
|
8129
8582
|
{
|
|
8130
|
-
className: styles$
|
|
8583
|
+
className: styles$c.FullScreenImage,
|
|
8131
8584
|
src: url,
|
|
8132
8585
|
alt: name,
|
|
8133
8586
|
onClick: (e) => {
|
|
@@ -8137,11 +8590,11 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8137
8590
|
)
|
|
8138
8591
|
}
|
|
8139
8592
|
),
|
|
8140
|
-
/* @__PURE__ */ jsxs(Flex$1, { className: styles$
|
|
8593
|
+
/* @__PURE__ */ jsxs(Flex$1, { className: styles$c.TopBarContainer, align: "center", children: [
|
|
8141
8594
|
/* @__PURE__ */ jsx(
|
|
8142
8595
|
IconButton,
|
|
8143
8596
|
{
|
|
8144
|
-
className: styles$
|
|
8597
|
+
className: styles$c.longIconButton,
|
|
8145
8598
|
variant: "soft",
|
|
8146
8599
|
"aria-label": "Exit preview",
|
|
8147
8600
|
onClick: () => {
|
|
@@ -8150,11 +8603,11 @@ const FullScreenImagePreview = memo((props) => {
|
|
|
8150
8603
|
children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiArrowLeftLine" })
|
|
8151
8604
|
}
|
|
8152
8605
|
),
|
|
8153
|
-
/* @__PURE__ */ jsx(Text$1, { className: styles$
|
|
8606
|
+
/* @__PURE__ */ jsx(Text$1, { className: styles$c.fileName, children: name }),
|
|
8154
8607
|
/* @__PURE__ */ jsx(
|
|
8155
8608
|
IconButton,
|
|
8156
8609
|
{
|
|
8157
|
-
className: styles$
|
|
8610
|
+
className: styles$c.longIconButton,
|
|
8158
8611
|
variant: "soft",
|
|
8159
8612
|
"aria-label": `Download ${name}`,
|
|
8160
8613
|
onClick: handleDownload,
|
|
@@ -8182,7 +8635,7 @@ const InputWithLabel = (props) => {
|
|
|
8182
8635
|
/* @__PURE__ */ jsx(
|
|
8183
8636
|
"img",
|
|
8184
8637
|
{
|
|
8185
|
-
className: styles$
|
|
8638
|
+
className: styles$c.previewImage,
|
|
8186
8639
|
src: resolvedImageURL,
|
|
8187
8640
|
alt: resolvedImage.name,
|
|
8188
8641
|
onClick: () => {
|
|
@@ -8210,7 +8663,7 @@ const InputWithHelpText = (props) => {
|
|
|
8210
8663
|
const { helpText, children, severity } = props;
|
|
8211
8664
|
return /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "1", children: [
|
|
8212
8665
|
children,
|
|
8213
|
-
/* @__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 }) })
|
|
8214
8667
|
] });
|
|
8215
8668
|
};
|
|
8216
8669
|
const InputWithLabelAndHelpText = (props) => {
|
|
@@ -8444,6 +8897,9 @@ function RiArrowUpLine(props) {
|
|
|
8444
8897
|
function RiCalendarLine(props) {
|
|
8445
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);
|
|
8446
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
|
+
}
|
|
8447
8903
|
function RiFileCopyLine(props) {
|
|
8448
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);
|
|
8449
8905
|
}
|
|
@@ -9347,9 +9803,9 @@ const Inset = React.forwardRef((props, forwardedRef) => {
|
|
|
9347
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)) });
|
|
9348
9804
|
});
|
|
9349
9805
|
Inset.displayName = "Inset";
|
|
9350
|
-
const sizes$
|
|
9806
|
+
const sizes$8 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
9351
9807
|
const headingPropDefs = {
|
|
9352
|
-
size: { type: "enum", values: sizes$
|
|
9808
|
+
size: { type: "enum", values: sizes$8, default: "6", responsive: true },
|
|
9353
9809
|
weight: { ...weightProp, default: "bold" },
|
|
9354
9810
|
align: alignProp,
|
|
9355
9811
|
trim: trimProp,
|
|
@@ -9362,9 +9818,9 @@ const Heading = React.forwardRef((props, forwardedRef) => {
|
|
|
9362
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));
|
|
9363
9819
|
});
|
|
9364
9820
|
Heading.displayName = "Heading";
|
|
9365
|
-
const sizes$
|
|
9821
|
+
const sizes$7 = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
|
|
9366
9822
|
const textPropDefs = {
|
|
9367
|
-
size: { type: "enum", values: sizes$
|
|
9823
|
+
size: { type: "enum", values: sizes$7, default: void 0, responsive: true },
|
|
9368
9824
|
weight: weightProp,
|
|
9369
9825
|
align: alignProp,
|
|
9370
9826
|
trim: trimProp,
|
|
@@ -9377,6 +9833,21 @@ const Text = React.forwardRef((props, forwardedRef) => {
|
|
|
9377
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));
|
|
9378
9834
|
});
|
|
9379
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";
|
|
9380
9851
|
const Em = React.forwardRef((props, forwardedRef) => React.createElement("em", { ...props, ref: forwardedRef, className: classNames("rt-Em", props.className) }));
|
|
9381
9852
|
Em.displayName = "Em";
|
|
9382
9853
|
const Strong = React.forwardRef((props, forwardedRef) => React.createElement("strong", { ...props, ref: forwardedRef, className: classNames("rt-Strong", props.className) }));
|
|
@@ -11767,7 +12238,7 @@ __publicField(StringOrTextField, "_validateMax", (path) => (value, allValues) =>
|
|
|
11767
12238
|
});
|
|
11768
12239
|
const clickableLinkContainer = "_clickableLinkContainer_1ace7_1";
|
|
11769
12240
|
const TextFieldInputCopy = "_TextFieldInputCopy_1ace7_5";
|
|
11770
|
-
const styles$
|
|
12241
|
+
const styles$b = {
|
|
11771
12242
|
clickableLinkContainer,
|
|
11772
12243
|
TextFieldInputCopy
|
|
11773
12244
|
};
|
|
@@ -11796,13 +12267,13 @@ const StringInput = memo((props) => {
|
|
|
11796
12267
|
placeholder: field.placeholder,
|
|
11797
12268
|
color
|
|
11798
12269
|
}
|
|
11799
|
-
) : /* @__PURE__ */ jsxs(TextField$1.Root, { className: styles$
|
|
12270
|
+
) : /* @__PURE__ */ jsxs(TextField$1.Root, { className: styles$b.clickableLinkContainer, children: [
|
|
11800
12271
|
/* @__PURE__ */ jsx(
|
|
11801
12272
|
"div",
|
|
11802
12273
|
{
|
|
11803
12274
|
className: classNames$1(
|
|
11804
12275
|
"rt-TextFieldInput rt-r-size-2 rt-variant-surface",
|
|
11805
|
-
styles$
|
|
12276
|
+
styles$b.TextFieldInputCopy
|
|
11806
12277
|
),
|
|
11807
12278
|
children: /* @__PURE__ */ jsx(
|
|
11808
12279
|
Linkify,
|
|
@@ -12374,8 +12845,7 @@ class BaseSelectField extends BaseField {
|
|
|
12374
12845
|
description: "List possible options for the user to select from.",
|
|
12375
12846
|
required: true,
|
|
12376
12847
|
identifier: `${path}options`,
|
|
12377
|
-
minimum_length: 2
|
|
12378
|
-
maximum_length: 20
|
|
12848
|
+
minimum_length: 2
|
|
12379
12849
|
}),
|
|
12380
12850
|
showDirectly: true
|
|
12381
12851
|
}
|
|
@@ -12494,6 +12964,158 @@ __publicField(_MultiSelectField, "fieldTypeName", "Multi-select");
|
|
|
12494
12964
|
__publicField(_MultiSelectField, "fieldTypeDescription", "Allows the user to select a multiple options from a list of options.");
|
|
12495
12965
|
__publicField(_MultiSelectField, "Icon", RiCheckboxLine);
|
|
12496
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;
|
|
12497
13119
|
const FieldInputCloner = memo((props) => {
|
|
12498
13120
|
const { field, ...rest } = props;
|
|
12499
13121
|
const [{ value: identifier }] = useField(field.options.clonedFieldIdentifier);
|
|
@@ -13751,6 +14373,7 @@ const FieldTypeToClsMapping = {
|
|
|
13751
14373
|
text: TextField,
|
|
13752
14374
|
custom: CustomField,
|
|
13753
14375
|
upload: UploadField,
|
|
14376
|
+
qr: QrField,
|
|
13754
14377
|
// TODO: Underscore
|
|
13755
14378
|
"multi-string": MultiStringField,
|
|
13756
14379
|
"multi-select": MultiSelectField
|
|
@@ -13764,6 +14387,7 @@ const FieldTypeToEmptyFieldMapping = {
|
|
|
13764
14387
|
text: emptyTextField,
|
|
13765
14388
|
custom: emptyCustomField,
|
|
13766
14389
|
upload: emptyUploadField,
|
|
14390
|
+
qr: emptyQrField,
|
|
13767
14391
|
// TODO: Underscore
|
|
13768
14392
|
"multi-string": emptyMultiStringField,
|
|
13769
14393
|
"multi-select": emptyMultiSelectField
|
|
@@ -13851,7 +14475,7 @@ const FieldSectionLayout = memo((props) => {
|
|
|
13851
14475
|
return /* @__PURE__ */ jsx(Card, { children: /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "3", children: [
|
|
13852
14476
|
/* @__PURE__ */ jsxs(Flex$1, { direction: "column", children: [
|
|
13853
14477
|
/* @__PURE__ */ jsx(Heading, { as: "h3", size: "3", children: label }),
|
|
13854
|
-
/* @__PURE__ */ jsx(Text$1, { className: styles$
|
|
14478
|
+
/* @__PURE__ */ jsx(Text$1, { className: styles$c.description, children: description2 })
|
|
13855
14479
|
] }),
|
|
13856
14480
|
inputs
|
|
13857
14481
|
] }) });
|
|
@@ -14038,7 +14662,7 @@ const initialFormValues = (fields, values) => {
|
|
|
14038
14662
|
};
|
|
14039
14663
|
const useAttachImagesToFormRevisionFields = (revision) => {
|
|
14040
14664
|
const { sdk } = useSDK();
|
|
14041
|
-
const attachments = useAppSelector(
|
|
14665
|
+
const attachments = useAppSelector(selectAttachmentsOfFormRevision((revision == null ? void 0 : revision.offline_id) ?? ""));
|
|
14042
14666
|
return useMemo(() => {
|
|
14043
14667
|
if (!revision || !attachments)
|
|
14044
14668
|
return revision;
|
|
@@ -14094,7 +14718,7 @@ const FormRenderer = memo(
|
|
|
14094
14718
|
[schema.title]
|
|
14095
14719
|
);
|
|
14096
14720
|
const Description = useMemo(
|
|
14097
|
-
() => 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,
|
|
14098
14722
|
[schema.description]
|
|
14099
14723
|
);
|
|
14100
14724
|
const inputs = useFieldInputs(schema.fields, { formId: formId2, disabled: readonly });
|
|
@@ -14110,7 +14734,7 @@ const FormRenderer = memo(
|
|
|
14110
14734
|
!hideDescription && Description
|
|
14111
14735
|
] }) }),
|
|
14112
14736
|
inputs,
|
|
14113
|
-
!readonly && /* @__PURE__ */ jsxs(Flex$1, { className: styles$
|
|
14737
|
+
!readonly && /* @__PURE__ */ jsxs(Flex$1, { className: styles$c.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
|
|
14114
14738
|
cancelText && /* @__PURE__ */ jsx(Button, { severity: "info", ...buttonProps, type: "button", onClick: onCancel, children: cancelText }),
|
|
14115
14739
|
/* @__PURE__ */ jsx(Button, { ...buttonProps, type: "submit", disabled: !formik.isValid, children: submitText })
|
|
14116
14740
|
] })
|
|
@@ -14135,7 +14759,7 @@ const FormSubmissionViewer = memo(
|
|
|
14135
14759
|
return formRevisionToSchema(revisionWithImages, { readonly: true });
|
|
14136
14760
|
}, [revisionWithImages]);
|
|
14137
14761
|
const submissionValuesWithAttachments = useMemo(() => {
|
|
14138
|
-
const attachments =
|
|
14762
|
+
const attachments = selectAttachmentsOfFormSubmission(submission.offline_id)(sdk.store.getState()) ?? [];
|
|
14139
14763
|
const downloadedAttachments = {};
|
|
14140
14764
|
for (const attachment of attachments) {
|
|
14141
14765
|
const promise = sdk.files.fetchFileFromUrl(attachment.file, attachment.file_sha1, attachment.file_name);
|
|
@@ -14185,8 +14809,8 @@ const FormBrowser = memo(
|
|
|
14185
14809
|
}
|
|
14186
14810
|
return ret;
|
|
14187
14811
|
}, [filter, maxResults, ownerFilter]);
|
|
14188
|
-
const userForms = useAppSelector(
|
|
14189
|
-
const userFormMapping = useAppSelector(
|
|
14812
|
+
const userForms = useAppSelector(selectFilteredForms(ownerFilterOptions)) ?? [];
|
|
14813
|
+
const userFormMapping = useAppSelector(selectFormMapping);
|
|
14190
14814
|
const attachableUserForms = userForms.filter((form) => !form.component_type);
|
|
14191
14815
|
const attachableUserFormMapping = Object.values(userFormMapping).filter(
|
|
14192
14816
|
(form) => !form.component_type
|
|
@@ -14219,7 +14843,7 @@ const FormBrowser = memo(
|
|
|
14219
14843
|
const handleChange = useCallback((e) => {
|
|
14220
14844
|
setFilter(e.currentTarget.value);
|
|
14221
14845
|
}, []);
|
|
14222
|
-
const numberOfForms = useAppSelector(
|
|
14846
|
+
const numberOfForms = useAppSelector(selectGeneralFormCount) || 0;
|
|
14223
14847
|
const numberOfHiddenForms = numberOfForms - attachableUserForms.length;
|
|
14224
14848
|
const overflowMessage = attachableUserForms.length == maxResults && numberOfHiddenForms > 0 ? `Only the first ${maxResults} results are shown (${numberOfHiddenForms} hidden)` : numberOfHiddenForms > 0 && `${numberOfHiddenForms} hidden forms`;
|
|
14225
14849
|
return /* @__PURE__ */ jsxs(Flex$1, { ref, direction: "column", gap: "2", children: [
|
|
@@ -14313,16 +14937,13 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
14313
14937
|
const { submission, onSubmissionClick, compact, labelType, rowDecorator } = props;
|
|
14314
14938
|
const currentUser = useAppSelector(selectCurrentUser);
|
|
14315
14939
|
const createdBy = useAppSelector(selectUser("created_by" in submission ? submission.created_by : currentUser.id));
|
|
14316
|
-
const dateToUse =
|
|
14317
|
-
const formattedDateTime =
|
|
14318
|
-
hour: "2-digit",
|
|
14319
|
-
minute: "2-digit"
|
|
14320
|
-
}) : getLocalDateString(dateToUse);
|
|
14940
|
+
const dateToUse = submission.submitted_at;
|
|
14941
|
+
const formattedDateTime = getLocalDateString(dateToUse);
|
|
14321
14942
|
const revision = useAppSelector(selectFormRevision(submission.form_revision));
|
|
14322
14943
|
if (!revision) {
|
|
14323
14944
|
throw new Error(`Could not find revision ${submission.form_revision} for submission ${submission.offline_id}.`);
|
|
14324
14945
|
}
|
|
14325
|
-
const latestRevisionNumber = (_a2 = useAppSelector(
|
|
14946
|
+
const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevisionOfForm(revision.form))) == null ? void 0 : _a2.revision;
|
|
14326
14947
|
const creatorProfileSrc = useFileSrc({
|
|
14327
14948
|
file: (createdBy == null ? void 0 : createdBy.profile.file) ?? null,
|
|
14328
14949
|
fileSha1: (createdBy == null ? void 0 : createdBy.profile.file_sha1) ?? null
|
|
@@ -14353,10 +14974,6 @@ const FormSubmissionBrowserEntry = memo((props) => {
|
|
|
14353
14974
|
return row;
|
|
14354
14975
|
});
|
|
14355
14976
|
FormSubmissionBrowserEntry.displayName = "FormSubmissionBrowserEntry";
|
|
14356
|
-
const getCreatedAtOrSubmittedAtDate = (submission) => {
|
|
14357
|
-
const date = "created_at" in submission ? submission.created_at : submission.submitted_at;
|
|
14358
|
-
return new Date(date);
|
|
14359
|
-
};
|
|
14360
14977
|
const FormSubmissionBrowser = memo((props) => {
|
|
14361
14978
|
const {
|
|
14362
14979
|
formId: formId2,
|
|
@@ -14370,10 +14987,10 @@ const FormSubmissionBrowser = memo((props) => {
|
|
|
14370
14987
|
if (!!formId2 === !!propSubmissions) {
|
|
14371
14988
|
throw new Error("Either formId or submissions must be provided, but not both.");
|
|
14372
14989
|
}
|
|
14373
|
-
const submissions = useAppSelector(propSubmissions ? () => propSubmissions :
|
|
14990
|
+
const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectFormSubmissionsOfForm(formId2));
|
|
14374
14991
|
const sortedSubmissions = useMemo(
|
|
14375
14992
|
() => submissions == null ? void 0 : submissions.sort((a, b) => {
|
|
14376
|
-
return
|
|
14993
|
+
return a.submitted_at.localeCompare(b.submitted_at);
|
|
14377
14994
|
}),
|
|
14378
14995
|
[submissions]
|
|
14379
14996
|
);
|
|
@@ -15465,12 +16082,12 @@ const FormBuilder = memo(
|
|
|
15465
16082
|
});
|
|
15466
16083
|
const previewSchema = useMemo(() => formRevisionToSchema(formik.values), [formik.values]);
|
|
15467
16084
|
return /* @__PURE__ */ jsx(Tabs.Root, { ref, defaultValue: "edit", children: /* @__PURE__ */ jsxs(Flex$1, { direction: "column", gap: "2", children: [
|
|
15468
|
-
showTabs && /* @__PURE__ */ jsxs(Tabs.List, { className: classNames$1(styles$
|
|
15469
|
-
/* @__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: [
|
|
15470
16087
|
/* @__PURE__ */ jsx(RiIcon, { icon: "RiPencilLine" }),
|
|
15471
16088
|
"Edit"
|
|
15472
16089
|
] }) }),
|
|
15473
|
-
/* @__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: [
|
|
15474
16091
|
/* @__PURE__ */ jsx(RiIcon, { icon: "RiEyeLine" }),
|
|
15475
16092
|
"Preview"
|
|
15476
16093
|
] }) })
|
|
@@ -15494,8 +16111,8 @@ const FormBuilder = memo(
|
|
|
15494
16111
|
render: ({ setValue, value, meta }) => /* @__PURE__ */ jsx(InputWithHelpText, { severity: "danger", helpText: meta.error ?? null, children: /* @__PURE__ */ jsx(
|
|
15495
16112
|
Input,
|
|
15496
16113
|
{
|
|
15497
|
-
className: classNames$1(styles$
|
|
15498
|
-
[styles$
|
|
16114
|
+
className: classNames$1(styles$d.title, {
|
|
16115
|
+
[styles$d.error]: meta.error
|
|
15499
16116
|
}),
|
|
15500
16117
|
placeholder: "Form title",
|
|
15501
16118
|
value,
|
|
@@ -15517,7 +16134,7 @@ const FormBuilder = memo(
|
|
|
15517
16134
|
render: ({ setValue, value }) => /* @__PURE__ */ jsx(
|
|
15518
16135
|
TextArea,
|
|
15519
16136
|
{
|
|
15520
|
-
className: styles$
|
|
16137
|
+
className: styles$d.description,
|
|
15521
16138
|
placeholder: "Explain the purpose of this form",
|
|
15522
16139
|
value,
|
|
15523
16140
|
onChange: (event) => {
|
|
@@ -15535,7 +16152,7 @@ const FormBuilder = memo(
|
|
|
15535
16152
|
/* @__PURE__ */ jsx(FieldsEditor, { fieldsOnly }),
|
|
15536
16153
|
/* @__PURE__ */ jsx(Text$1, { severity: "danger", size: "1", children: typeof formik.errors.fields === "string" && formik.errors.fields })
|
|
15537
16154
|
] }),
|
|
15538
|
-
/* @__PURE__ */ jsxs(Flex$1, { className: styles$
|
|
16155
|
+
/* @__PURE__ */ jsxs(Flex$1, { className: styles$d.floatingButtonContainer, align: "center", justify: "end", gap: "2", children: [
|
|
15539
16156
|
onCancel && /* @__PURE__ */ jsx(Button, { type: "button", variant: "solid", severity: "info", onClick: onCancel, children: "Cancel" }),
|
|
15540
16157
|
/* @__PURE__ */ jsx(Button, { type: "submit", children: "Save form" })
|
|
15541
16158
|
] })
|
|
@@ -15570,6 +16187,9 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
15570
16187
|
NumberInput,
|
|
15571
16188
|
PatchField,
|
|
15572
16189
|
PatchFormProvider,
|
|
16190
|
+
QrField,
|
|
16191
|
+
QrInput,
|
|
16192
|
+
QrScanner,
|
|
15573
16193
|
SelectField,
|
|
15574
16194
|
SelectInput,
|
|
15575
16195
|
StringField,
|
|
@@ -15584,6 +16204,7 @@ const index = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
|
|
|
15584
16204
|
emptyMultiSelectField,
|
|
15585
16205
|
emptyMultiStringField,
|
|
15586
16206
|
emptyNumberField,
|
|
16207
|
+
emptyQrField,
|
|
15587
16208
|
emptySelectField,
|
|
15588
16209
|
emptyStringField,
|
|
15589
16210
|
emptyTextField,
|
|
@@ -15674,6 +16295,9 @@ export {
|
|
|
15674
16295
|
ProjectFileService,
|
|
15675
16296
|
ProjectService,
|
|
15676
16297
|
ProjectType,
|
|
16298
|
+
QrField,
|
|
16299
|
+
QrInput,
|
|
16300
|
+
QrScanner,
|
|
15677
16301
|
SDKContext,
|
|
15678
16302
|
SDKProvider,
|
|
15679
16303
|
SUPPORTED_IMAGE_FILE_TYPES,
|
|
@@ -15684,6 +16308,7 @@ export {
|
|
|
15684
16308
|
SpreadsheetViewer,
|
|
15685
16309
|
StringField,
|
|
15686
16310
|
StringInput,
|
|
16311
|
+
TeamService,
|
|
15687
16312
|
TextField,
|
|
15688
16313
|
TextInput,
|
|
15689
16314
|
UserFormService,
|
|
@@ -15691,6 +16316,7 @@ export {
|
|
|
15691
16316
|
VerificationCodeType,
|
|
15692
16317
|
WorkspaceService,
|
|
15693
16318
|
YELLOW,
|
|
16319
|
+
_selectLatestFormRevision,
|
|
15694
16320
|
_setLatestRetryTime,
|
|
15695
16321
|
acceptProjectInvite,
|
|
15696
16322
|
addActiveProjectFormSubmissionsCount,
|
|
@@ -15708,6 +16334,16 @@ export {
|
|
|
15708
16334
|
addDocuments,
|
|
15709
16335
|
addEmailDomain,
|
|
15710
16336
|
addFavouriteProjectId,
|
|
16337
|
+
addForm,
|
|
16338
|
+
addFormRevision,
|
|
16339
|
+
addFormRevisionAttachment,
|
|
16340
|
+
addFormRevisionAttachments,
|
|
16341
|
+
addFormRevisions,
|
|
16342
|
+
addFormSubmission,
|
|
16343
|
+
addFormSubmissionAttachment,
|
|
16344
|
+
addFormSubmissionAttachments,
|
|
16345
|
+
addFormSubmissions,
|
|
16346
|
+
addForms,
|
|
15711
16347
|
addIssue,
|
|
15712
16348
|
addIssueAttachment,
|
|
15713
16349
|
addIssueAttachments,
|
|
@@ -15727,14 +16363,8 @@ export {
|
|
|
15727
16363
|
addStageCompletion,
|
|
15728
16364
|
addStageCompletions,
|
|
15729
16365
|
addStages,
|
|
16366
|
+
addTeam,
|
|
15730
16367
|
addToRecentIssues,
|
|
15731
|
-
addUserForm,
|
|
15732
|
-
addUserFormRevision,
|
|
15733
|
-
addUserFormRevisionAttachment,
|
|
15734
|
-
addUserFormRevisions,
|
|
15735
|
-
addUserFormSubmissionAttachment,
|
|
15736
|
-
addUserFormSubmissions,
|
|
15737
|
-
addUserForms,
|
|
15738
16368
|
addUsers,
|
|
15739
16369
|
addWorkspace,
|
|
15740
16370
|
areArraysEqual,
|
|
@@ -15755,6 +16385,7 @@ export {
|
|
|
15755
16385
|
componentStageSlice,
|
|
15756
16386
|
componentTypeReducer,
|
|
15757
16387
|
componentTypeSlice,
|
|
16388
|
+
constructUploadedFilePayloads,
|
|
15758
16389
|
coordinatesAreEqual,
|
|
15759
16390
|
coordinatesToLiteral,
|
|
15760
16391
|
coordinatesToPointGeometry,
|
|
@@ -15765,12 +16396,17 @@ export {
|
|
|
15765
16396
|
defaultBadgeColor,
|
|
15766
16397
|
defaultStore,
|
|
15767
16398
|
deleteComponentType,
|
|
16399
|
+
deleteForm,
|
|
16400
|
+
deleteFormRevision,
|
|
16401
|
+
deleteFormRevisionAttachment,
|
|
16402
|
+
deleteFormRevisionAttachments,
|
|
16403
|
+
deleteFormRevisions,
|
|
16404
|
+
deleteFormSubmission,
|
|
16405
|
+
deleteFormSubmissionAttachment,
|
|
16406
|
+
deleteFormSubmissionAttachments,
|
|
16407
|
+
deleteFormSubmissions,
|
|
15768
16408
|
deleteProject,
|
|
15769
|
-
|
|
15770
|
-
deleteUserFormRevision,
|
|
15771
|
-
deleteUserFormRevisions,
|
|
15772
|
-
deleteUserFormSubmission,
|
|
15773
|
-
deleteUserFormSubmissions,
|
|
16409
|
+
deleteTeam,
|
|
15774
16410
|
dequeue,
|
|
15775
16411
|
deserialize,
|
|
15776
16412
|
deserializeField,
|
|
@@ -15788,6 +16424,7 @@ export {
|
|
|
15788
16424
|
emptyMultiSelectField,
|
|
15789
16425
|
emptyMultiStringField,
|
|
15790
16426
|
emptyNumberField,
|
|
16427
|
+
emptyQrField,
|
|
15791
16428
|
emptySelectField,
|
|
15792
16429
|
emptyStringField,
|
|
15793
16430
|
emptyTextField,
|
|
@@ -15799,7 +16436,13 @@ export {
|
|
|
15799
16436
|
fileSlice,
|
|
15800
16437
|
fileToBlob,
|
|
15801
16438
|
flipCoordinates,
|
|
16439
|
+
formReducer,
|
|
16440
|
+
formRevisionReducer,
|
|
15802
16441
|
formRevisionToSchema,
|
|
16442
|
+
formRevisionsSlice,
|
|
16443
|
+
formSlice,
|
|
16444
|
+
formSubmissionReducer,
|
|
16445
|
+
formSubmissionSlice,
|
|
15803
16446
|
index as forms,
|
|
15804
16447
|
fullComponentMarkerSize,
|
|
15805
16448
|
generateBadgeColors,
|
|
@@ -15927,6 +16570,8 @@ export {
|
|
|
15927
16570
|
selectAttachmentsOfComponentTypeByType,
|
|
15928
16571
|
selectAttachmentsOfDocument,
|
|
15929
16572
|
selectAttachmentsOfDocumentByType,
|
|
16573
|
+
selectAttachmentsOfFormRevision,
|
|
16574
|
+
selectAttachmentsOfFormSubmission,
|
|
15930
16575
|
selectAttachmentsOfIssue,
|
|
15931
16576
|
selectAttachmentsOfIssueByType,
|
|
15932
16577
|
selectAttachmentsOfProject,
|
|
@@ -15944,11 +16589,9 @@ export {
|
|
|
15944
16589
|
selectComponent,
|
|
15945
16590
|
selectComponentAttachment,
|
|
15946
16591
|
selectComponentAttachmentMapping,
|
|
15947
|
-
selectComponentSubmissionMapping,
|
|
15948
16592
|
selectComponentType,
|
|
15949
16593
|
selectComponentTypeAttachment,
|
|
15950
16594
|
selectComponentTypeAttachmentMapping,
|
|
15951
|
-
selectComponentTypeForm,
|
|
15952
16595
|
selectComponentTypeFromComponent,
|
|
15953
16596
|
selectComponentTypeFromComponents,
|
|
15954
16597
|
selectComponentTypeStagesMapping,
|
|
@@ -15978,8 +16621,24 @@ export {
|
|
|
15978
16621
|
selectExpandedSections,
|
|
15979
16622
|
selectFavouriteProjects,
|
|
15980
16623
|
selectFileAttachmentsOfIssue,
|
|
15981
|
-
|
|
16624
|
+
selectFilteredForms,
|
|
16625
|
+
selectForm,
|
|
16626
|
+
selectFormMapping,
|
|
16627
|
+
selectFormOfComponentType,
|
|
15982
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,
|
|
15983
16642
|
selectHiddenCategoryCount,
|
|
15984
16643
|
selectHiddenComponentTypeIds,
|
|
15985
16644
|
selectIsFetchingInitialData,
|
|
@@ -15994,10 +16653,10 @@ export {
|
|
|
15994
16653
|
selectIssueUpdateMapping,
|
|
15995
16654
|
selectIssueUpdatesOfIssue,
|
|
15996
16655
|
selectIssues,
|
|
15997
|
-
|
|
16656
|
+
selectLatestFormRevisionByForm,
|
|
16657
|
+
selectLatestFormRevisionOfForm,
|
|
16658
|
+
selectLatestFormRevisionsOfComponentTypes,
|
|
15998
16659
|
selectLatestRetryTime,
|
|
15999
|
-
selectLatestRevisionByFormId,
|
|
16000
|
-
selectLatestRevisionsFromComponentTypeIds,
|
|
16001
16660
|
selectLicense,
|
|
16002
16661
|
selectLicenseForProject,
|
|
16003
16662
|
selectLicenses,
|
|
@@ -16006,8 +16665,6 @@ export {
|
|
|
16006
16665
|
selectMapStyle,
|
|
16007
16666
|
selectNumberOfComponentTypesMatchingCaseInsensitiveName,
|
|
16008
16667
|
selectNumberOfComponentsOfComponentType,
|
|
16009
|
-
selectNumberOfGeneralUserForms,
|
|
16010
|
-
selectNumberOfUserForms,
|
|
16011
16668
|
selectOrganization,
|
|
16012
16669
|
selectOrganizationAccess,
|
|
16013
16670
|
selectOrganizationAccessForUser,
|
|
@@ -16035,8 +16692,6 @@ export {
|
|
|
16035
16692
|
selectRecentIssuesAsSearchResults,
|
|
16036
16693
|
selectRecentProjects,
|
|
16037
16694
|
selectRehydrated,
|
|
16038
|
-
selectRevisionAttachments,
|
|
16039
|
-
selectRevisionsForForm,
|
|
16040
16695
|
selectRootDocuments,
|
|
16041
16696
|
selectShowTooltips,
|
|
16042
16697
|
selectSortedEmailDomains,
|
|
@@ -16051,16 +16706,15 @@ export {
|
|
|
16051
16706
|
selectStagesFromComponentType,
|
|
16052
16707
|
selectStagesFromComponentTypeIds,
|
|
16053
16708
|
selectStagesFromStageIds,
|
|
16054
|
-
|
|
16055
|
-
|
|
16056
|
-
|
|
16057
|
-
|
|
16709
|
+
selectTeam,
|
|
16710
|
+
selectTeams,
|
|
16711
|
+
selectTeamsMapping,
|
|
16712
|
+
selectTeamsOfOrganization,
|
|
16713
|
+
selectTeamsOfUser,
|
|
16058
16714
|
selectUploadUrl,
|
|
16059
16715
|
selectUsedColors,
|
|
16060
16716
|
selectUser,
|
|
16061
|
-
|
|
16062
|
-
selectUserFormMapping,
|
|
16063
|
-
selectUserFormSubmission,
|
|
16717
|
+
selectUserFormRevisionAttachmentsMapping,
|
|
16064
16718
|
selectUsersAsMapping,
|
|
16065
16719
|
selectVisibleStatuses,
|
|
16066
16720
|
selectVisibleUserIds,
|
|
@@ -16087,6 +16741,13 @@ export {
|
|
|
16087
16741
|
setEnableClustering,
|
|
16088
16742
|
setEnableDuplicateIssues,
|
|
16089
16743
|
setEnablePlacementMode,
|
|
16744
|
+
setFormRevision,
|
|
16745
|
+
setFormRevisionAttachments,
|
|
16746
|
+
setFormRevisions,
|
|
16747
|
+
setFormSubmission,
|
|
16748
|
+
setFormSubmissionAttachments,
|
|
16749
|
+
setFormSubmissions,
|
|
16750
|
+
setForms,
|
|
16090
16751
|
setIsFetchingInitialData,
|
|
16091
16752
|
setIsImportingProjectFile,
|
|
16092
16753
|
setIsLoading,
|
|
@@ -16108,12 +16769,11 @@ export {
|
|
|
16108
16769
|
setSectionExpanded,
|
|
16109
16770
|
setShowTooltips,
|
|
16110
16771
|
setStageCompletions,
|
|
16772
|
+
setTeam,
|
|
16773
|
+
setTeams,
|
|
16111
16774
|
setTokens,
|
|
16112
16775
|
setTourStep,
|
|
16113
16776
|
setUploadUrl,
|
|
16114
|
-
setUserFormRevisionAttachments,
|
|
16115
|
-
setUserFormSubmissionAttachments,
|
|
16116
|
-
setUserFormSubmissions,
|
|
16117
16777
|
setUsers,
|
|
16118
16778
|
setVisibleStatuses,
|
|
16119
16779
|
setVisibleUserIds,
|
|
@@ -16124,6 +16784,8 @@ export {
|
|
|
16124
16784
|
slugify,
|
|
16125
16785
|
spacesToDashesLower,
|
|
16126
16786
|
successColor,
|
|
16787
|
+
teamReducer,
|
|
16788
|
+
teamSlice,
|
|
16127
16789
|
toFileNameSafeString,
|
|
16128
16790
|
toOfflineIdRecord,
|
|
16129
16791
|
toggleComponentTypeVisibility,
|
|
@@ -16138,15 +16800,18 @@ export {
|
|
|
16138
16800
|
updateComponentTypeAttachment,
|
|
16139
16801
|
updateDocumentAttachment,
|
|
16140
16802
|
updateDocuments,
|
|
16803
|
+
updateFormSubmission,
|
|
16804
|
+
updateFormSubmissionAttachments,
|
|
16805
|
+
updateFormSubmissions,
|
|
16141
16806
|
updateIssue,
|
|
16142
16807
|
updateIssueAttachment,
|
|
16143
16808
|
updateLicense,
|
|
16144
16809
|
updateOrCreateProject,
|
|
16145
|
-
updateOrCreateUserFormSubmission,
|
|
16146
16810
|
updateOrganizationAccess,
|
|
16147
16811
|
updateProjectAccess,
|
|
16148
16812
|
updateProjectAttachment,
|
|
16149
16813
|
updateStages,
|
|
16814
|
+
updateTeam,
|
|
16150
16815
|
useAppDispatch,
|
|
16151
16816
|
useAppSelector,
|
|
16152
16817
|
useFieldInput,
|
|
@@ -16156,8 +16821,6 @@ export {
|
|
|
16156
16821
|
useFormikInput,
|
|
16157
16822
|
useMemoCompare,
|
|
16158
16823
|
useSDK,
|
|
16159
|
-
userFormReducer,
|
|
16160
|
-
userFormSlice,
|
|
16161
16824
|
userReducer,
|
|
16162
16825
|
userSlice,
|
|
16163
16826
|
valueIsFile,
|