@overmap-ai/core 1.0.50-bulk-form-submission.2 → 1.0.50-document-attachments.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.
@@ -631,15 +631,15 @@ const wrapMigration = (migrator) => (state) => {
631
631
  };
632
632
  const migrations = [initialVersioning, signOut, signOut, createOutboxState];
633
633
  const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
634
- const initialState$p = {
634
+ const initialState$n = {
635
635
  accessToken: "",
636
636
  refreshToken: "",
637
637
  isLoggedIn: false
638
638
  };
639
639
  const authSlice = createSlice({
640
640
  name: "auth",
641
- initialState: initialState$p,
642
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$p)),
641
+ initialState: initialState$n,
642
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
643
643
  reducers: {
644
644
  setTokens: (state, action) => {
645
645
  state.accessToken = action.payload.accessToken;
@@ -804,19 +804,6 @@ function downloadInMemoryFile(filename, text) {
804
804
  element.click();
805
805
  document.body.removeChild(element);
806
806
  }
807
- const constructUploadedFilePayloads = async (files) => {
808
- const filePayloads = {};
809
- for (const file of files) {
810
- const sha1 = await hashFile(file);
811
- filePayloads[sha1] = {
812
- sha1,
813
- extension: file.name.split(".").pop() || "",
814
- file_type: file.type,
815
- size: file.size
816
- };
817
- }
818
- return Object.values(filePayloads);
819
- };
820
807
  const fileToBlob = async (dataUrl) => {
821
808
  return (await fetch(dataUrl)).blob();
822
809
  };
@@ -1383,7 +1370,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
1383
1370
  return getLocalDateString(date);
1384
1371
  return relative.format(days, "days");
1385
1372
  });
1386
- const initialState$o = {
1373
+ const initialState$m = {
1387
1374
  categories: {},
1388
1375
  usedCategoryColors: [],
1389
1376
  categoryVisibility: {
@@ -1393,8 +1380,8 @@ const initialState$o = {
1393
1380
  };
1394
1381
  const categorySlice = createSlice({
1395
1382
  name: "categories",
1396
- initialState: initialState$o,
1397
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$o)),
1383
+ initialState: initialState$m,
1384
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1398
1385
  reducers: {
1399
1386
  setCategories: (state, action) => {
1400
1387
  if (!Array.isArray(action.payload))
@@ -1551,15 +1538,6 @@ function updateAttachment(state, action) {
1551
1538
  throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
1552
1539
  }
1553
1540
  }
1554
- function updateAttachments(state, action) {
1555
- for (const attachment of action.payload) {
1556
- if (attachment.offline_id in state.attachments) {
1557
- state.attachments[attachment.offline_id] = attachment;
1558
- } else {
1559
- throw new Error(`Attachment ${attachment.offline_id} does not exist.`);
1560
- }
1561
- }
1562
- }
1563
1541
  function removeAttachment(state, action) {
1564
1542
  if (action.payload in state.attachments) {
1565
1543
  delete state.attachments[action.payload];
@@ -1572,14 +1550,14 @@ function removeAttachments(state, action) {
1572
1550
  delete state.attachments[attachmentId];
1573
1551
  }
1574
1552
  }
1575
- const initialState$n = {
1553
+ const initialState$l = {
1576
1554
  components: {},
1577
1555
  attachments: {}
1578
1556
  };
1579
1557
  const componentSlice = createSlice({
1580
1558
  name: "components",
1581
- initialState: initialState$n,
1582
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
1559
+ initialState: initialState$l,
1560
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1583
1561
  reducers: {
1584
1562
  addComponent: (state, action) => {
1585
1563
  state.components[action.payload.offline_id] = action.payload;
@@ -1692,9 +1670,6 @@ const selectAllComponentAttachments = createSelector(
1692
1670
  [selectComponentAttachmentMapping],
1693
1671
  (mapping) => Object.values(mapping)
1694
1672
  );
1695
- const selectComponentAttachment = (attachmentId) => (state) => {
1696
- return state.componentReducer.attachments[attachmentId];
1697
- };
1698
1673
  const selectAttachmentsOfComponent = restructureCreateSelectorWithArgs(
1699
1674
  createSelector(
1700
1675
  [selectAllComponentAttachments, (_state, componentId) => componentId],
@@ -1735,13 +1710,13 @@ const {
1735
1710
  removeAllComponentsOfType
1736
1711
  } = componentSlice.actions;
1737
1712
  const componentReducer = componentSlice.reducer;
1738
- const initialState$m = {
1713
+ const initialState$k = {
1739
1714
  completionsByComponentId: {}
1740
1715
  };
1741
1716
  const componentStageCompletionSlice = createSlice({
1742
1717
  name: "componentStageCompletions",
1743
- initialState: initialState$m,
1744
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1718
+ initialState: initialState$k,
1719
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1745
1720
  reducers: {
1746
1721
  addStageCompletion: (state, action) => {
1747
1722
  let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
@@ -1792,13 +1767,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
1792
1767
  return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
1793
1768
  };
1794
1769
  const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
1795
- const initialState$l = {
1770
+ const initialState$j = {
1796
1771
  stages: {}
1797
1772
  };
1798
1773
  const componentStageSlice = createSlice({
1799
1774
  name: "componentStages",
1800
- initialState: initialState$l,
1801
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1775
+ initialState: initialState$j,
1776
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1802
1777
  reducers: {
1803
1778
  addStages: (state, action) => {
1804
1779
  Object.assign(state.stages, toOfflineIdRecord(action.payload));
@@ -1908,15 +1883,15 @@ const selectStageFormIdsFromStageIds = restructureCreateSelectorWithArgs(
1908
1883
  );
1909
1884
  const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
1910
1885
  const componentStageReducer = componentStageSlice.reducer;
1911
- const initialState$k = {
1886
+ const initialState$i = {
1912
1887
  componentTypes: {},
1913
1888
  hiddenComponentTypeIds: {},
1914
1889
  attachments: {}
1915
1890
  };
1916
1891
  const componentTypeSlice = createSlice({
1917
1892
  name: "componentTypes",
1918
- initialState: initialState$k,
1919
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1893
+ initialState: initialState$i,
1894
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1920
1895
  reducers: {
1921
1896
  addComponentType: (state, action) => {
1922
1897
  state.componentTypes[action.payload.offline_id] = action.payload;
@@ -1984,9 +1959,6 @@ const selectAllComponentTypeAttachments = createSelector(
1984
1959
  [selectComponentTypeAttachmentMapping],
1985
1960
  (mapping) => Object.values(mapping)
1986
1961
  );
1987
- const selectComponentTypeAttachment = (attachmentId) => (state) => {
1988
- return state.componentTypeReducer.attachments[attachmentId];
1989
- };
1990
1962
  const selectAttachmentsOfComponentType = restructureCreateSelectorWithArgs(
1991
1963
  createSelector(
1992
1964
  [selectAllComponentTypeAttachments, (_state, componentTypeId) => componentTypeId],
@@ -2027,13 +1999,13 @@ const {
2027
1999
  deleteComponentType
2028
2000
  } = componentTypeSlice.actions;
2029
2001
  const componentTypeReducer = componentTypeSlice.reducer;
2030
- const initialState$j = {
2002
+ const initialState$h = {
2031
2003
  workspaces: {},
2032
2004
  activeWorkspaceId: null
2033
2005
  };
2034
2006
  const workspaceSlice = createSlice({
2035
2007
  name: "workspace",
2036
- initialState: initialState$j,
2008
+ initialState: initialState$h,
2037
2009
  // The `reducers` field lets us define reducers and generate associated actions
2038
2010
  reducers: {
2039
2011
  setWorkspaces: (state, action) => {
@@ -2090,7 +2062,7 @@ const selectPermittedWorkspaceIds = createSelector(
2090
2062
  );
2091
2063
  const workspaceReducer = workspaceSlice.reducer;
2092
2064
  const maxRecentIssues = 10;
2093
- const initialState$i = {
2065
+ const initialState$g = {
2094
2066
  issues: {},
2095
2067
  attachments: {},
2096
2068
  comments: {},
@@ -2102,9 +2074,9 @@ const initialState$i = {
2102
2074
  };
2103
2075
  const issueSlice = createSlice({
2104
2076
  name: "issues",
2105
- initialState: initialState$i,
2077
+ initialState: initialState$g,
2106
2078
  extraReducers: (builder) => builder.addCase("RESET", (state) => {
2107
- Object.assign(state, initialState$i);
2079
+ Object.assign(state, initialState$g);
2108
2080
  }),
2109
2081
  reducers: {
2110
2082
  setIssues: (state, action) => {
@@ -2159,7 +2131,6 @@ const issueSlice = createSlice({
2159
2131
  }
2160
2132
  },
2161
2133
  updateIssueAttachment: updateAttachment,
2162
- updateIssueAttachments: updateAttachments,
2163
2134
  removeIssue: (state, action) => {
2164
2135
  if (action.payload in state.issues) {
2165
2136
  delete state.issues[action.payload];
@@ -2168,7 +2139,6 @@ const issueSlice = createSlice({
2168
2139
  }
2169
2140
  },
2170
2141
  removeIssueAttachment: removeAttachment,
2171
- removeIssueAttachments: removeAttachments,
2172
2142
  removeIssueUpdate: (state, action) => {
2173
2143
  if (action.payload in state.updates) {
2174
2144
  delete state.updates[action.payload];
@@ -2278,7 +2248,6 @@ const {
2278
2248
  addToRecentIssues,
2279
2249
  cleanRecentIssues,
2280
2250
  removeIssueAttachment,
2281
- removeIssueAttachments,
2282
2251
  removeAttachmentsOfIssue,
2283
2252
  removeIssue,
2284
2253
  removeIssueUpdate,
@@ -2292,7 +2261,6 @@ const {
2292
2261
  setVisibleStatuses,
2293
2262
  setVisibleUserIds,
2294
2263
  updateIssueAttachment,
2295
- updateIssueAttachments,
2296
2264
  updateIssue,
2297
2265
  // Commments
2298
2266
  addIssueComment,
@@ -2385,9 +2353,6 @@ const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(
2385
2353
  }
2386
2354
  )
2387
2355
  );
2388
- const selectIssueAttachment = (attachmentId) => (root) => {
2389
- return root.issueReducer.attachments[attachmentId];
2390
- };
2391
2356
  const selectAttachmentsOfIssueByType = restructureCreateSelectorWithArgs(
2392
2357
  createSelector(
2393
2358
  [selectIssueAttachments, (_state, issueId) => issueId],
@@ -2516,15 +2481,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
2516
2481
  }
2517
2482
  );
2518
2483
  const issueReducer = issueSlice.reducer;
2519
- const initialState$h = {
2484
+ const initialState$f = {
2520
2485
  s3Urls: {}
2521
2486
  };
2522
2487
  const msPerHour = 1e3 * 60 * 60;
2523
2488
  const msPerWeek = msPerHour * 24 * 7;
2524
2489
  const fileSlice = createSlice({
2525
2490
  name: "file",
2526
- initialState: initialState$h,
2527
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
2491
+ initialState: initialState$f,
2492
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2528
2493
  reducers: {
2529
2494
  setUploadUrl: (state, action) => {
2530
2495
  const { url, fields, sha1 } = action.payload;
@@ -2551,7 +2516,7 @@ const selectUploadUrl = (sha1) => (state) => {
2551
2516
  return url;
2552
2517
  };
2553
2518
  const fileReducer = fileSlice.reducer;
2554
- const initialState$g = {
2519
+ const initialState$e = {
2555
2520
  // TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
2556
2521
  mapStyle: MapStyle.SATELLITE,
2557
2522
  showTooltips: false,
@@ -2559,8 +2524,8 @@ const initialState$g = {
2559
2524
  };
2560
2525
  const mapSlice = createSlice({
2561
2526
  name: "map",
2562
- initialState: initialState$g,
2563
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
2527
+ initialState: initialState$e,
2528
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2564
2529
  reducers: {
2565
2530
  setMapStyle: (state, action) => {
2566
2531
  state.mapStyle = action.payload;
@@ -2629,7 +2594,7 @@ var LicenseStatus = /* @__PURE__ */ ((LicenseStatus2) => {
2629
2594
  LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
2630
2595
  return LicenseStatus2;
2631
2596
  })(LicenseStatus || {});
2632
- const initialState$f = {
2597
+ const initialState$d = {
2633
2598
  users: {},
2634
2599
  currentUser: {
2635
2600
  id: 0,
@@ -2640,8 +2605,8 @@ const initialState$f = {
2640
2605
  };
2641
2606
  const userSlice = createSlice({
2642
2607
  name: "users",
2643
- initialState: initialState$f,
2644
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2608
+ initialState: initialState$d,
2609
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2645
2610
  reducers: {
2646
2611
  setUsers: (state, action) => {
2647
2612
  const usersMapping = {};
@@ -2703,13 +2668,13 @@ const selectUser = (userId) => (state) => {
2703
2668
  const selectUsersAsMapping = (state) => state.userReducer.users;
2704
2669
  const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
2705
2670
  const userReducer = userSlice.reducer;
2706
- const initialState$e = {
2671
+ const initialState$c = {
2707
2672
  organizationAccesses: {}
2708
2673
  };
2709
2674
  const organizationAccessSlice = createSlice({
2710
2675
  name: "organizationAccess",
2711
- initialState: initialState$e,
2712
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2676
+ initialState: initialState$c,
2677
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2713
2678
  reducers: {
2714
2679
  setOrganizationAccesses: (state, action) => {
2715
2680
  if (!Array.isArray(action.payload))
@@ -2772,13 +2737,13 @@ const selectOrganizationAccessUserMapping = (state) => {
2772
2737
  return organizationAccesses;
2773
2738
  };
2774
2739
  const organizationAccessReducer = organizationAccessSlice.reducer;
2775
- const initialState$d = {
2740
+ const initialState$b = {
2776
2741
  licenses: {}
2777
2742
  };
2778
2743
  const licenseSlice = createSlice({
2779
2744
  name: "license",
2780
- initialState: initialState$d,
2781
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2745
+ initialState: initialState$b,
2746
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2782
2747
  reducers: {
2783
2748
  setLicenses: (state, action) => {
2784
2749
  if (!Array.isArray(action.payload))
@@ -2823,13 +2788,13 @@ const selectLicensesForProjectsMapping = createSelector(
2823
2788
  (licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
2824
2789
  );
2825
2790
  const licenseReducer = licenseSlice.reducer;
2826
- const initialState$c = {
2791
+ const initialState$a = {
2827
2792
  projectAccesses: {}
2828
2793
  };
2829
2794
  const projectAccessSlice = createSlice({
2830
2795
  name: "projectAccess",
2831
- initialState: initialState$c,
2832
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2796
+ initialState: initialState$a,
2797
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2833
2798
  reducers: {
2834
2799
  setProjectAccesses: (state, action) => {
2835
2800
  if (!Array.isArray(action.payload))
@@ -2897,7 +2862,7 @@ const selectProjectAccessUserMapping = (state) => {
2897
2862
  return projectAccesses;
2898
2863
  };
2899
2864
  const projectAccessReducer = projectAccessSlice.reducer;
2900
- const initialState$b = {
2865
+ const initialState$9 = {
2901
2866
  projects: {},
2902
2867
  activeProjectId: null,
2903
2868
  recentProjectIds: [],
@@ -2907,7 +2872,7 @@ const initialState$b = {
2907
2872
  };
2908
2873
  const projectSlice = createSlice({
2909
2874
  name: "projects",
2910
- initialState: initialState$b,
2875
+ initialState: initialState$9,
2911
2876
  reducers: {
2912
2877
  setProjects: (state, action) => {
2913
2878
  const projectsMap = {};
@@ -3094,14 +3059,14 @@ const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(
3094
3059
  }
3095
3060
  )
3096
3061
  );
3097
- const initialState$a = {
3062
+ const initialState$8 = {
3098
3063
  organizations: {},
3099
3064
  activeOrganizationId: null
3100
3065
  };
3101
3066
  const organizationSlice = createSlice({
3102
3067
  name: "organizations",
3103
- initialState: initialState$a,
3104
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
3068
+ initialState: initialState$8,
3069
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3105
3070
  reducers: {
3106
3071
  setOrganizations: (state, action) => {
3107
3072
  for (const org of action.payload) {
@@ -3220,14 +3185,14 @@ const createOfflineAction = (request2, baseUrl) => {
3220
3185
  }
3221
3186
  };
3222
3187
  };
3223
- const initialState$9 = {
3188
+ const initialState$7 = {
3224
3189
  deletedRequests: [],
3225
3190
  latestRetryTime: 0
3226
3191
  };
3227
3192
  const outboxSlice = createSlice({
3228
3193
  name: "outbox",
3229
- initialState: initialState$9,
3230
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
3194
+ initialState: initialState$7,
3195
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
3231
3196
  reducers: {
3232
3197
  // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
3233
3198
  // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
@@ -3259,7 +3224,7 @@ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
3259
3224
  const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
3260
3225
  const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
3261
3226
  const outboxReducer = outboxSlice.reducer;
3262
- const initialState$8 = {
3227
+ const initialState$6 = {
3263
3228
  projectFiles: {},
3264
3229
  activeProjectFileId: null,
3265
3230
  isImportingProjectFile: false,
@@ -3267,8 +3232,8 @@ const initialState$8 = {
3267
3232
  };
3268
3233
  const projectFileSlice = createSlice({
3269
3234
  name: "projectFiles",
3270
- initialState: initialState$8,
3271
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3235
+ initialState: initialState$6,
3236
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
3272
3237
  reducers: {
3273
3238
  addOrReplaceProjectFiles: (state, action) => {
3274
3239
  for (let fileObj of action.payload) {
@@ -3369,12 +3334,12 @@ const selectProjectFiles = createSelector(
3369
3334
  const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
3370
3335
  const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
3371
3336
  const projectFileReducer = projectFileSlice.reducer;
3372
- const initialState$7 = {
3337
+ const initialState$5 = {
3373
3338
  isRehydrated: false
3374
3339
  };
3375
3340
  const rehydratedSlice = createSlice({
3376
3341
  name: "rehydrated",
3377
- initialState: initialState$7,
3342
+ initialState: initialState$5,
3378
3343
  // The `reducers` field lets us define reducers and generate associated actions
3379
3344
  reducers: {
3380
3345
  setRehydrated: (state, action) => {
@@ -3384,7 +3349,7 @@ const rehydratedSlice = createSlice({
3384
3349
  });
3385
3350
  const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
3386
3351
  const rehydratedReducer = rehydratedSlice.reducer;
3387
- const initialState$6 = {
3352
+ const initialState$4 = {
3388
3353
  useIssueTemplate: false,
3389
3354
  placementMode: false,
3390
3355
  enableClustering: false,
@@ -3401,8 +3366,8 @@ const initialState$6 = {
3401
3366
  };
3402
3367
  const settingSlice = createSlice({
3403
3368
  name: "settings",
3404
- initialState: initialState$6,
3405
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
3369
+ initialState: initialState$4,
3370
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3406
3371
  reducers: {
3407
3372
  setEnableDuplicateIssues: (state, action) => {
3408
3373
  state.useIssueTemplate = action.payload;
@@ -3448,248 +3413,146 @@ const selectAppearance = (state) => state.settingReducer.appearance;
3448
3413
  const settingReducer = settingSlice.reducer;
3449
3414
  const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
3450
3415
  const selectIsLoading = (state) => state.settingReducer.isLoading;
3451
- const LATEST_FORM_REVISION_CACHE = {};
3452
- function considerCachingFormRevision(formRevision, formId2, preferPending = false) {
3416
+ const LATEST_REVISION_CACHE = {};
3417
+ function considerCachingRevision(revision, formId2, preferPending = false) {
3453
3418
  var _a2;
3454
- if (!formRevision) {
3419
+ if (!revision) {
3455
3420
  if (!formId2) {
3456
- throw new Error("If form revision is null, formId is required.");
3421
+ throw new Error("If revision is null, formId is required.");
3457
3422
  }
3458
- const currentLatestFormRevision = getLatestFormRevisionFromCache(formId2);
3459
- if (currentLatestFormRevision)
3423
+ const currentLatestRevision = getLatestRevisionFromCache(formId2);
3424
+ if (currentLatestRevision)
3460
3425
  return;
3461
- LATEST_FORM_REVISION_CACHE[formId2] = null;
3426
+ LATEST_REVISION_CACHE[formId2] = null;
3462
3427
  return;
3463
3428
  }
3464
- if (formRevision.revision === "Pending") {
3429
+ if (revision.revision === "Pending") {
3465
3430
  if (preferPending) {
3466
- LATEST_FORM_REVISION_CACHE[formRevision.form] = formRevision;
3431
+ LATEST_REVISION_CACHE[revision.form] = revision;
3467
3432
  }
3468
3433
  return;
3469
3434
  }
3470
- const cachedFormRevision = (_a2 = LATEST_FORM_REVISION_CACHE[formRevision.form]) == null ? void 0 : _a2.revision;
3471
- if (formRevision.revision > (typeof cachedFormRevision === "number" ? cachedFormRevision : -1)) {
3472
- LATEST_FORM_REVISION_CACHE[formRevision.form] = formRevision;
3435
+ const cachedRevision = (_a2 = LATEST_REVISION_CACHE[revision.form]) == null ? void 0 : _a2.revision;
3436
+ if (revision.revision > (typeof cachedRevision === "number" ? cachedRevision : -1)) {
3437
+ LATEST_REVISION_CACHE[revision.form] = revision;
3473
3438
  }
3474
3439
  }
3475
- function getLatestFormRevisionFromCache(formId2) {
3476
- return LATEST_FORM_REVISION_CACHE[formId2];
3440
+ function getLatestRevisionFromCache(formId2) {
3441
+ return LATEST_REVISION_CACHE[formId2];
3477
3442
  }
3478
- const initialState$5 = {
3479
- formRevisions: {},
3480
- attachments: {}
3481
- };
3482
- const formRevisionsSlice = createSlice({
3483
- name: "formRevisions",
3484
- initialState: initialState$5,
3485
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$5)),
3443
+ const initialState$3 = {
3444
+ userForms: {},
3445
+ revisions: {},
3446
+ submissions: {},
3447
+ submissionAttachments: {},
3448
+ revisionAttachments: {}
3449
+ };
3450
+ const userFormSlice = createSlice({
3451
+ name: "userForms",
3452
+ initialState: initialState$3,
3453
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
3486
3454
  reducers: {
3487
- // revision related actions
3488
- setFormRevision: (state, action) => {
3489
- state.formRevisions[action.payload.offline_id] = action.payload;
3490
- considerCachingFormRevision(action.payload);
3455
+ setUserForms: (state, action) => {
3456
+ state.userForms = {};
3457
+ action.payload.forEach((userForm) => {
3458
+ state.userForms[userForm.offline_id] = userForm;
3459
+ });
3491
3460
  },
3492
- setFormRevisions: (state, action) => {
3493
- state.formRevisions = {};
3494
- for (const revision of action.payload) {
3495
- state.formRevisions[revision.offline_id] = revision;
3496
- considerCachingFormRevision(revision);
3497
- }
3461
+ addUserForm: (state, action) => {
3462
+ state.userForms[action.payload.offline_id] = action.payload;
3498
3463
  },
3499
- addFormRevision: (state, action) => {
3500
- if (state.formRevisions[action.payload.offline_id] !== void 0) {
3501
- throw new Error(`Revision with offline_id ${action.payload.offline_id} already exists`);
3502
- }
3503
- state.formRevisions[action.payload.offline_id] = action.payload;
3504
- considerCachingFormRevision(action.payload);
3464
+ addUserForms: (state, action) => {
3465
+ action.payload.forEach((userForm) => {
3466
+ state.userForms[userForm.offline_id] = userForm;
3467
+ });
3505
3468
  },
3506
- // TODO: @Audiopolis / Magnus - do we want to standardize using PayloadAction?
3507
- addFormRevisions: (state, action) => {
3508
- for (const userFormRevision of action.payload) {
3509
- if (state.formRevisions[userFormRevision.offline_id] !== void 0) {
3510
- throw new Error(`Revision with offline_id ${userFormRevision.offline_id} already exists`);
3511
- }
3512
- }
3513
- for (const userFormRevision of action.payload) {
3514
- state.formRevisions[userFormRevision.offline_id] = userFormRevision;
3515
- considerCachingFormRevision(userFormRevision);
3516
- }
3469
+ addUserFormRevisions: (state, action) => {
3470
+ action.payload.forEach((userFormRevision) => {
3471
+ state.revisions[userFormRevision.offline_id] = userFormRevision;
3472
+ considerCachingRevision(userFormRevision);
3473
+ });
3517
3474
  },
3518
- // UserFormRevisions do not get updated
3519
- deleteFormRevision: (state, action) => {
3520
- if (state.formRevisions[action.payload] === void 0) {
3521
- throw new Error(`Revision with offline_id ${action.payload} does not exist`);
3522
- }
3523
- delete state.formRevisions[action.payload];
3524
- delete LATEST_FORM_REVISION_CACHE[action.payload];
3475
+ addUserFormRevision: (state, action) => {
3476
+ state.revisions[action.payload.offline_id] = action.payload;
3477
+ considerCachingRevision(action.payload);
3525
3478
  },
3526
- deleteFormRevisions: (state, action) => {
3527
- for (const offlineId of action.payload) {
3528
- if (state.formRevisions[offlineId] === void 0) {
3529
- throw new Error(`Revision with offline_id ${offlineId} does not exist`);
3530
- }
3531
- }
3532
- for (const offlineId of action.payload) {
3533
- delete state.formRevisions[offlineId];
3534
- delete LATEST_FORM_REVISION_CACHE[offlineId];
3479
+ deleteUserFormRevision: (state, action) => {
3480
+ delete state.revisions[action.payload];
3481
+ delete LATEST_REVISION_CACHE[action.payload];
3482
+ },
3483
+ deleteUserFormRevisions: (state, action) => {
3484
+ for (const userFormRevision of action.payload) {
3485
+ delete state.revisions[userFormRevision.offline_id];
3486
+ delete LATEST_REVISION_CACHE[userFormRevision.offline_id];
3535
3487
  }
3536
3488
  },
3537
- // attachment related actions
3538
- setFormRevisionAttachments: (state, action) => {
3539
- state.attachments = {};
3540
- for (const attachment of action.payload) {
3541
- state.attachments[attachment.offline_id] = attachment;
3489
+ updateOrCreateUserFormSubmission: (state, action) => {
3490
+ state.submissions[action.payload.offline_id] = action.payload;
3491
+ },
3492
+ addUserFormSubmissionAttachment: (state, action) => {
3493
+ const submissionId = action.payload.submission;
3494
+ const submissionAttachments = state.submissionAttachments[submissionId];
3495
+ if (submissionAttachments) {
3496
+ submissionAttachments.push(action.payload);
3497
+ } else {
3498
+ state.submissionAttachments[submissionId] = [action.payload];
3542
3499
  }
3543
3500
  },
3544
- addFormRevisionAttachment: (state, action) => {
3545
- if (state.attachments[action.payload.offline_id] !== void 0) {
3546
- throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
3501
+ addUserFormRevisionAttachment: (state, action) => {
3502
+ const revisionId = action.payload.revision;
3503
+ const revisionAttachments = state.revisionAttachments[revisionId];
3504
+ if (revisionAttachments) {
3505
+ revisionAttachments.push(action.payload);
3506
+ } else {
3507
+ state.revisionAttachments[revisionId] = [action.payload];
3547
3508
  }
3548
- state.attachments[action.payload.offline_id] = action.payload;
3549
3509
  },
3550
- addFormRevisionAttachments: (state, action) => {
3510
+ setUserFormSubmissionAttachments: (state, action) => {
3511
+ state.submissionAttachments = {};
3551
3512
  for (const attachment of action.payload) {
3552
- if (state.attachments[attachment.offline_id] !== void 0) {
3553
- throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
3513
+ const submissionId = attachment.submission;
3514
+ const submissionAttachments = state.submissionAttachments[submissionId];
3515
+ if (submissionAttachments) {
3516
+ submissionAttachments.push(attachment);
3517
+ } else {
3518
+ state.submissionAttachments[submissionId] = [attachment];
3554
3519
  }
3555
3520
  }
3521
+ },
3522
+ setUserFormRevisionAttachments: (state, action) => {
3523
+ state.revisionAttachments = {};
3556
3524
  for (const attachment of action.payload) {
3557
- state.attachments[attachment.offline_id] = attachment;
3525
+ const revisionId = attachment.revision;
3526
+ const revisionAttachments = state.revisionAttachments[revisionId];
3527
+ if (revisionAttachments) {
3528
+ revisionAttachments.push(attachment);
3529
+ } else {
3530
+ state.revisionAttachments[revisionId] = [attachment];
3531
+ }
3558
3532
  }
3559
3533
  },
3560
- deleteFormRevisionAttachment: (state, action) => {
3561
- if (state.attachments[action.payload] === void 0) {
3562
- throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
3563
- }
3564
- delete state.attachments[action.payload];
3534
+ deleteUserFormSubmission: (state, action) => {
3535
+ delete state.submissions[action.payload];
3565
3536
  },
3566
- deleteFormRevisionAttachments: (state, action) => {
3567
- for (const offlineId of action.payload) {
3568
- if (state.attachments[offlineId] === void 0) {
3569
- throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
3570
- }
3571
- }
3572
- for (const offlineId of action.payload) {
3573
- delete state.attachments[offlineId];
3574
- }
3575
- }
3576
- }
3577
- });
3578
- const {
3579
- setFormRevision,
3580
- setFormRevisions,
3581
- addFormRevision,
3582
- addFormRevisions,
3583
- deleteFormRevision,
3584
- deleteFormRevisions,
3585
- setFormRevisionAttachments,
3586
- addFormRevisionAttachment,
3587
- addFormRevisionAttachments,
3588
- deleteFormRevisionAttachment,
3589
- deleteFormRevisionAttachments
3590
- } = formRevisionsSlice.actions;
3591
- const selectFormRevisionMapping = (state) => state.formRevisionReducer.formRevisions;
3592
- const selectFormRevisions = createSelector(
3593
- [selectFormRevisionMapping],
3594
- (formRevisions) => Object.values(formRevisions)
3595
- );
3596
- const selectFormRevision = (formRevisionId) => (state) => {
3597
- return state.formRevisionReducer.formRevisions[formRevisionId];
3598
- };
3599
- const _selectLatestFormRevision = (formRevisions, formId2) => {
3600
- let ret = null;
3601
- for (const candidate of Object.values(formRevisions)) {
3602
- if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
3603
- ret = candidate;
3604
- }
3605
- }
3606
- if (!ret) {
3607
- throw new Error("No form revision found for form " + formId2);
3608
- }
3609
- return ret;
3610
- };
3611
- const selectLatestFormRevisionOfForm = restructureCreateSelectorWithArgs(
3612
- createSelector([selectFormRevisionMapping, (_state, formId2) => formId2], (revisions, formId2) => {
3613
- if (!formId2) {
3614
- throw new Error("formId is required");
3615
- }
3616
- return _selectLatestFormRevision(revisions, formId2);
3617
- })
3618
- );
3619
- const selectFormRevisionsOfForm = restructureCreateSelectorWithArgs(
3620
- createSelector([selectFormRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
3621
- return revisions.filter((revision) => {
3622
- return revision.form === formId2;
3623
- });
3624
- })
3625
- );
3626
- const selectLatestFormRevisionsOfComponentTypes = restructureCreateSelectorWithArgs(
3627
- createSelector(
3628
- [
3629
- (state) => state.formReducer.forms,
3630
- selectFormRevisionMapping,
3631
- (_state, componentTypeIds) => componentTypeIds
3632
- ],
3633
- (userForms, revisions, componentTypeIds) => {
3634
- const componentTypeIdsSet = new Set(componentTypeIds);
3635
- const ret = {};
3636
- for (const form of Object.values(userForms)) {
3637
- if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
3638
- ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
3639
- }
3537
+ deleteUserFormSubmissions: (state, action) => {
3538
+ for (const userFormSubmission of action.payload) {
3539
+ delete state.submissions[userFormSubmission.offline_id];
3640
3540
  }
3641
- return ret;
3642
- }
3643
- )
3644
- );
3645
- const selectLatestFormRevisionByForm = createSelector([selectFormRevisionMapping], (revisions) => {
3646
- const latestRevisions = {};
3647
- for (const revision of Object.values(revisions)) {
3648
- const formId2 = revision.form;
3649
- const currentLatestRevision = latestRevisions[formId2];
3650
- if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
3651
- latestRevisions[formId2] = revision;
3652
- }
3653
- }
3654
- return latestRevisions;
3655
- });
3656
- const selectUserFormRevisionAttachmentsMapping = (state) => {
3657
- return state.formRevisionReducer.attachments;
3658
- };
3659
- const selectAttachmentsOfFormRevision = restructureCreateSelectorWithArgs(
3660
- createSelector(
3661
- [selectUserFormRevisionAttachmentsMapping, (_state, revisionId) => revisionId],
3662
- (attachments, revisionId) => {
3663
- return Object.values(attachments).filter((attachment) => attachment.revision === revisionId);
3664
- }
3665
- )
3666
- );
3667
- const formRevisionReducer = formRevisionsSlice.reducer;
3668
- const initialState$4 = {
3669
- forms: {}
3670
- };
3671
- const formSlice = createSlice({
3672
- name: "forms",
3673
- initialState: initialState$4,
3674
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3675
- reducers: {
3676
- setForms: (state, action) => {
3677
- state.forms = {};
3678
- action.payload.forEach((userForm) => {
3679
- state.forms[userForm.offline_id] = userForm;
3680
- });
3681
3541
  },
3682
- addForm: (state, action) => {
3683
- state.forms[action.payload.offline_id] = action.payload;
3542
+ addUserFormSubmissions: (state, action) => {
3543
+ for (const submission of action.payload) {
3544
+ state.submissions[submission.offline_id] = submission;
3545
+ }
3684
3546
  },
3685
- addForms: (state, action) => {
3686
- action.payload.forEach((userForm) => {
3687
- state.forms[userForm.offline_id] = userForm;
3547
+ setUserFormSubmissions: (state, action) => {
3548
+ state.submissions = {};
3549
+ action.payload.forEach((submission) => {
3550
+ state.submissions[submission.offline_id] = submission;
3688
3551
  });
3689
3552
  },
3690
3553
  favoriteForm: (state, action) => {
3691
3554
  const { formId: formId2 } = action.payload;
3692
- const form = state.forms[formId2];
3555
+ const form = state.userForms[formId2];
3693
3556
  if (!form) {
3694
3557
  throw new Error("No form exists with the id " + formId2);
3695
3558
  }
@@ -3697,23 +3560,48 @@ const formSlice = createSlice({
3697
3560
  },
3698
3561
  unfavoriteForm: (state, action) => {
3699
3562
  const { formId: formId2 } = action.payload;
3700
- const form = state.forms[formId2];
3563
+ const form = state.userForms[formId2];
3701
3564
  if (!form) {
3702
3565
  throw new Error("No form exists with the id " + formId2);
3703
3566
  }
3704
3567
  form.favorite = false;
3705
3568
  },
3706
- deleteForm: (state, action) => {
3707
- delete state.forms[action.payload];
3569
+ deleteUserForm: (state, action) => {
3570
+ delete state.userForms[action.payload];
3708
3571
  }
3709
3572
  }
3710
3573
  });
3711
- const { setForms, addForm, addForms, favoriteForm, unfavoriteForm, deleteForm } = formSlice.actions;
3712
- const selectFilteredForms = restructureCreateSelectorWithArgs(
3574
+ const {
3575
+ addUserForm,
3576
+ addUserForms,
3577
+ addUserFormRevisions,
3578
+ updateOrCreateUserFormSubmission,
3579
+ addUserFormSubmissions,
3580
+ deleteUserFormSubmission,
3581
+ deleteUserFormSubmissions,
3582
+ favoriteForm,
3583
+ unfavoriteForm,
3584
+ deleteUserForm,
3585
+ deleteUserFormRevision,
3586
+ deleteUserFormRevisions,
3587
+ setUserFormSubmissions,
3588
+ addUserFormRevision,
3589
+ addUserFormSubmissionAttachment,
3590
+ addUserFormRevisionAttachment,
3591
+ setUserFormSubmissionAttachments,
3592
+ setUserFormRevisionAttachments
3593
+ } = userFormSlice.actions;
3594
+ const selectSubmissionAttachments = (submissionId) => (state) => {
3595
+ return state.userFormReducer.submissionAttachments[submissionId] || [];
3596
+ };
3597
+ const selectRevisionAttachments = (revisionId) => (state) => {
3598
+ return state.userFormReducer.revisionAttachments[revisionId] || [];
3599
+ };
3600
+ const selectFilteredUserForms = restructureCreateSelectorWithArgs(
3713
3601
  createSelector(
3714
3602
  [
3715
- (state) => state.formReducer.forms,
3716
- (state) => state.formRevisionReducer.formRevisions,
3603
+ (state) => state.userFormReducer.userForms,
3604
+ (state) => state.userFormReducer.revisions,
3717
3605
  (_state, search) => search
3718
3606
  ],
3719
3607
  (userForms, revisions, search) => {
@@ -3747,188 +3635,63 @@ const selectFilteredForms = restructureCreateSelectorWithArgs(
3747
3635
  { memoizeOptions: { equalityCheck: shallowEqual$1 } }
3748
3636
  )
3749
3637
  );
3750
- const selectForm = (formId2) => (state) => {
3751
- return state.formReducer.forms[formId2];
3638
+ const selectFormRevision = (revisionId) => (state) => {
3639
+ return state.userFormReducer.revisions[revisionId];
3752
3640
  };
3753
- const selectFormMapping = (state) => {
3754
- return state.formReducer.forms;
3641
+ const _selectLatestFormRevision = (revisions, formId2) => {
3642
+ let ret = null;
3643
+ for (const candidate of Object.values(revisions)) {
3644
+ if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
3645
+ ret = candidate;
3646
+ }
3647
+ }
3648
+ if (!ret) {
3649
+ throw new Error("No revision found for form " + formId2);
3650
+ }
3651
+ return ret;
3755
3652
  };
3756
- const selectFormOfComponentType = restructureCreateSelectorWithArgs(
3653
+ const selectLatestFormRevision = restructureCreateSelectorWithArgs(
3757
3654
  createSelector(
3758
- [selectFormMapping, (_state, componentTypeId) => componentTypeId],
3759
- (userForms, componentTypeId) => {
3760
- return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
3655
+ [(state) => state.userFormReducer.revisions, (_state, formId2) => formId2],
3656
+ (revisions, formId2) => {
3657
+ if (!formId2) {
3658
+ throw new Error("formId is required");
3659
+ }
3660
+ return _selectLatestFormRevision(revisions, formId2);
3761
3661
  }
3762
3662
  )
3763
3663
  );
3764
- const selectFormsCount = createSelector([selectFormMapping], (userForms) => {
3765
- return Object.keys(userForms).length;
3766
- });
3767
- const selectGeneralFormCount = createSelector([selectFormMapping], (userForms) => {
3768
- return Object.values(userForms).filter((form) => !form.component_type).length;
3769
- });
3770
- const formReducer = formSlice.reducer;
3771
- const initialState$3 = {
3772
- formSubmissions: {},
3773
- attachments: {}
3774
- };
3775
- const formSubmissionSlice = createSlice({
3776
- name: "formSubmissions",
3777
- initialState: initialState$3,
3778
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
3779
- reducers: {
3780
- setFormSubmission: (state, action) => {
3781
- state.formSubmissions[action.payload.offline_id] = action.payload;
3782
- },
3783
- setFormSubmissions: (state, action) => {
3784
- state.formSubmissions = {};
3785
- for (const submission of action.payload) {
3786
- state.formSubmissions[submission.offline_id] = submission;
3787
- }
3788
- },
3789
- addFormSubmission: (state, action) => {
3790
- if (state.formSubmissions[action.payload.offline_id] !== void 0) {
3791
- throw new Error(`Submission with offline_id ${action.payload.offline_id} already exists`);
3792
- }
3793
- state.formSubmissions[action.payload.offline_id] = action.payload;
3794
- },
3795
- addFormSubmissions: (state, action) => {
3796
- for (const submission of action.payload) {
3797
- if (state.formSubmissions[submission.offline_id] !== void 0) {
3798
- throw new Error(`Submission with offline_id ${submission.offline_id} already exists`);
3799
- }
3800
- }
3801
- for (const submission of action.payload) {
3802
- state.formSubmissions[submission.offline_id] = submission;
3803
- }
3804
- },
3805
- updateFormSubmission: (state, action) => {
3806
- if (state.formSubmissions[action.payload.offline_id] === void 0) {
3807
- throw new Error(`Submission with offline_id ${action.payload.offline_id} does not exist`);
3808
- }
3809
- state.formSubmissions[action.payload.offline_id] = action.payload;
3810
- },
3811
- updateFormSubmissions: (state, action) => {
3812
- for (const submission of action.payload) {
3813
- if (state.formSubmissions[submission.offline_id] === void 0) {
3814
- throw new Error(`Submission with offline_id ${submission.offline_id} does not exist`);
3815
- }
3816
- }
3817
- for (const submission of action.payload) {
3818
- state.formSubmissions[submission.offline_id] = submission;
3819
- }
3820
- },
3821
- deleteFormSubmission: (state, action) => {
3822
- if (state.formSubmissions[action.payload] === void 0) {
3823
- throw new Error(`Submission with offline_id ${action.payload} does not exist`);
3824
- }
3825
- delete state.formSubmissions[action.payload];
3826
- },
3827
- deleteFormSubmissions: (state, action) => {
3828
- for (const offlineId of action.payload) {
3829
- if (state.formSubmissions[offlineId] === void 0) {
3830
- throw new Error(`Submission with offline_id ${offlineId} does not exist`);
3831
- }
3832
- delete state.formSubmissions[offlineId];
3833
- }
3834
- for (const offlineId of action.payload) {
3835
- delete state.formSubmissions[offlineId];
3836
- }
3837
- },
3838
- // Attachments
3839
- addFormSubmissionAttachment: (state, action) => {
3840
- if (state.attachments[action.payload.offline_id] !== void 0) {
3841
- throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
3842
- }
3843
- state.attachments[action.payload.offline_id] = action.payload;
3844
- },
3845
- addFormSubmissionAttachments: (state, action) => {
3846
- for (const attachment of action.payload) {
3847
- if (state.attachments[attachment.offline_id] !== void 0) {
3848
- throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
3849
- }
3850
- }
3851
- for (const attachment of action.payload) {
3852
- state.attachments[attachment.offline_id] = attachment;
3853
- }
3854
- },
3855
- // We only need a multi set for attachments because they are not updated, only added and deleted
3856
- setFormSubmissionAttachments: (state, action) => {
3857
- state.attachments = {};
3858
- for (const attachment of action.payload) {
3859
- state.attachments[attachment.offline_id] = attachment;
3860
- }
3861
- },
3862
- updateFormSubmissionAttachments: (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} does not exist`);
3866
- }
3867
- }
3868
- for (const attachment of action.payload) {
3869
- state.attachments[attachment.offline_id] = attachment;
3870
- }
3871
- },
3872
- // The delete actions for UserFormSubmissionAttachments are not used in the app, but are included for completeness
3873
- // Could be used if editing a submission is ever supported, will be applicable for supporting tip tap content in submissions
3874
- deleteFormSubmissionAttachment: (state, action) => {
3875
- if (state.attachments[action.payload] === void 0) {
3876
- throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
3877
- }
3878
- delete state.attachments[action.payload];
3879
- },
3880
- deleteFormSubmissionAttachments: (state, action) => {
3881
- for (const offlineId of action.payload) {
3882
- if (state.attachments[offlineId] === void 0) {
3883
- throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
3884
- }
3885
- delete state.attachments[offlineId];
3886
- }
3887
- }
3888
- }
3889
- });
3890
- const {
3891
- setFormSubmission,
3892
- setFormSubmissions,
3893
- addFormSubmission,
3894
- addFormSubmissions,
3895
- updateFormSubmission,
3896
- updateFormSubmissions,
3897
- deleteFormSubmission,
3898
- deleteFormSubmissions,
3899
- addFormSubmissionAttachment,
3900
- addFormSubmissionAttachments,
3901
- setFormSubmissionAttachments,
3902
- updateFormSubmissionAttachments,
3903
- deleteFormSubmissionAttachment,
3904
- deleteFormSubmissionAttachments
3905
- } = formSubmissionSlice.actions;
3906
- const selectFormSubmissionsMapping = (state) => {
3907
- return state.formSubmissionReducer.formSubmissions;
3908
- };
3909
- const selectFormSubmissions = createSelector(
3910
- [selectFormSubmissionsMapping],
3911
- (submissions) => {
3912
- return Object.values(submissions);
3913
- }
3664
+ const selectUserForm = (formId2) => (state) => {
3665
+ return state.userFormReducer.userForms[formId2];
3666
+ };
3667
+ const selectSubmissionMapping = (state) => state.userFormReducer.submissions;
3668
+ const selectUserFormSubmission = (submissionId) => (state) => {
3669
+ return state.userFormReducer.submissions[submissionId];
3670
+ };
3671
+ const selectSubmissions = createSelector([selectSubmissionMapping], (submissions) => Object.values(submissions));
3672
+ const selectRevisionMapping = (state) => state.userFormReducer.revisions;
3673
+ const selectRevisions = createSelector([selectRevisionMapping], (revisions) => Object.values(revisions));
3674
+ const selectRevisionsForForm = restructureCreateSelectorWithArgs(
3675
+ createSelector([selectRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
3676
+ return revisions.filter((revision) => {
3677
+ return revision.form === formId2;
3678
+ });
3679
+ })
3914
3680
  );
3915
- const selectFormSubmission = (submissionId) => (state) => {
3916
- return state.formSubmissionReducer.formSubmissions[submissionId];
3917
- };
3918
- const selectFormSubmissionsOfForm = restructureCreateSelectorWithArgs(
3681
+ const selectSubmissionsForForm = restructureCreateSelectorWithArgs(
3919
3682
  createSelector(
3920
- [selectFormSubmissions, selectFormRevisionMapping, (_state, formId2) => formId2],
3683
+ [selectSubmissions, selectRevisionMapping, (_state, formId2) => formId2],
3921
3684
  (submissions, revisionMapping, formId2) => {
3922
- return submissions.filter((submission) => {
3685
+ return Object.values(submissions).filter((submission) => {
3923
3686
  const revision = revisionMapping[submission.form_revision];
3924
3687
  return (revision == null ? void 0 : revision.form) === formId2;
3925
3688
  });
3926
3689
  }
3927
3690
  )
3928
3691
  );
3929
- const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(
3692
+ const selectSubmissionsForIssue = restructureCreateSelectorWithArgs(
3930
3693
  createSelector(
3931
- [selectFormSubmissions, (_state, issueId) => issueId],
3694
+ [(state) => state.userFormReducer.submissions, (_state, issueId) => issueId],
3932
3695
  (submissions, issueId) => {
3933
3696
  return Object.values(submissions).filter((submission) => {
3934
3697
  return submission.issue === issueId;
@@ -3936,9 +3699,9 @@ const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(
3936
3699
  }
3937
3700
  )
3938
3701
  );
3939
- const selectFormSubmissionsOfComponent = restructureCreateSelectorWithArgs(
3702
+ const selectSubmissionsForComponent = restructureCreateSelectorWithArgs(
3940
3703
  createSelector(
3941
- [selectFormSubmissions, (_state, componentId) => componentId],
3704
+ [selectSubmissions, (_state, componentId) => componentId],
3942
3705
  (submissions, componentId) => {
3943
3706
  return submissions.filter((submission) => {
3944
3707
  return submission.component === componentId;
@@ -3946,8 +3709,8 @@ const selectFormSubmissionsOfComponent = restructureCreateSelectorWithArgs(
3946
3709
  }
3947
3710
  )
3948
3711
  );
3949
- const selectFormSubmissionsByComponents = createSelector(
3950
- [selectFormSubmissionsMapping, selectComponentsMapping],
3712
+ const selectComponentSubmissionMapping = createSelector(
3713
+ [selectSubmissionMapping, selectComponentsMapping],
3951
3714
  (submissions, components) => {
3952
3715
  var _a2;
3953
3716
  const componentSubmissionMapping = {};
@@ -3963,18 +3726,54 @@ const selectFormSubmissionsByComponents = createSelector(
3963
3726
  return componentSubmissionMapping;
3964
3727
  }
3965
3728
  );
3966
- const selectFormSubmissionAttachmentsMapping = (state) => {
3967
- return state.formSubmissionReducer.attachments;
3729
+ const selectUserFormMapping = (state) => {
3730
+ return state.userFormReducer.userForms;
3968
3731
  };
3969
- const selectAttachmentsOfFormSubmission = restructureCreateSelectorWithArgs(
3732
+ const selectComponentTypeForm = restructureCreateSelectorWithArgs(
3733
+ createSelector(
3734
+ [selectUserFormMapping, (_state, componentTypeId) => componentTypeId],
3735
+ (userForms, componentTypeId) => {
3736
+ return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
3737
+ }
3738
+ )
3739
+ );
3740
+ const selectLatestRevisionsFromComponentTypeIds = restructureCreateSelectorWithArgs(
3970
3741
  createSelector(
3971
- [selectFormSubmissionAttachmentsMapping, (_state, submissionId) => submissionId],
3972
- (attachmentsMapping, submissionId) => {
3973
- return Object.values(attachmentsMapping).filter((attachment) => attachment.submission === submissionId);
3742
+ [
3743
+ selectUserFormMapping,
3744
+ selectRevisionMapping,
3745
+ (_state, componentTypeIds) => componentTypeIds
3746
+ ],
3747
+ (userForms, revisions, componentTypeIds) => {
3748
+ const componentTypeIdsSet = new Set(componentTypeIds);
3749
+ const ret = {};
3750
+ for (const form of Object.values(userForms)) {
3751
+ if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
3752
+ ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
3753
+ }
3754
+ }
3755
+ return ret;
3974
3756
  }
3975
3757
  )
3976
3758
  );
3977
- const formSubmissionReducer = formSubmissionSlice.reducer;
3759
+ const selectLatestRevisionByFormId = createSelector([selectRevisionMapping], (revisions) => {
3760
+ const latestRevisions = {};
3761
+ for (const revision of Object.values(revisions)) {
3762
+ const formId2 = revision.form;
3763
+ const currentLatestRevision = latestRevisions[formId2];
3764
+ if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
3765
+ latestRevisions[formId2] = revision;
3766
+ }
3767
+ }
3768
+ return latestRevisions;
3769
+ });
3770
+ const selectNumberOfUserForms = createSelector([selectUserFormMapping], (userForms) => {
3771
+ return Object.keys(userForms).length;
3772
+ });
3773
+ const selectNumberOfGeneralUserForms = createSelector([selectUserFormMapping], (userForms) => {
3774
+ return Object.values(userForms).filter((form) => !form.component_type).length;
3775
+ });
3776
+ const userFormReducer = userFormSlice.reducer;
3978
3777
  const initialState$2 = {
3979
3778
  emailDomains: {}
3980
3779
  };
@@ -4202,9 +4001,6 @@ const selectAllDocumentAttachments = createSelector(
4202
4001
  [selectDocumentAttachmentMapping],
4203
4002
  (mapping) => Object.values(mapping)
4204
4003
  );
4205
- const selectDocumentAttachment = (attachmentId) => (state) => {
4206
- return state.documentsReducer.attachments[attachmentId];
4207
- };
4208
4004
  const selectAttachmentsOfDocument = restructureCreateSelectorWithArgs(
4209
4005
  createSelector(
4210
4006
  [selectAllDocumentAttachments, (_state, documentId) => documentId],
@@ -4272,9 +4068,7 @@ const overmapReducers = {
4272
4068
  projectFileReducer,
4273
4069
  rehydratedReducer,
4274
4070
  settingReducer,
4275
- formReducer,
4276
- formRevisionReducer,
4277
- formSubmissionReducer,
4071
+ userFormReducer,
4278
4072
  userReducer,
4279
4073
  workspaceReducer,
4280
4074
  emailDomainsReducer,
@@ -4327,7 +4121,9 @@ function handleWorkspaceRemoval(draft, action) {
4327
4121
  throw new Error(`Failed to update index_workspace of issue ${issue.offline_id} to main workspace`);
4328
4122
  }
4329
4123
  }
4330
- const indexedForms = Object.values(draft.formReducer.forms).filter((form) => form.index_workspace === workspaceId);
4124
+ const indexedForms = Object.values(draft.userFormReducer.userForms).filter(
4125
+ (form) => form.index_workspace === workspaceId
4126
+ );
4331
4127
  for (const form of indexedForms) {
4332
4128
  form.index_workspace = mainWorkspace.offline_id;
4333
4129
  }
@@ -4805,23 +4601,6 @@ class BaseApiService {
4805
4601
  }
4806
4602
  }
4807
4603
  class AttachmentService extends BaseApiService {
4808
- processPresignedUrls(presignedUrls) {
4809
- for (const [sha1, presignedUrl] of Object.entries(presignedUrls)) {
4810
- console.debug(sha1, presignedUrl);
4811
- void this.enqueueRequest({
4812
- url: presignedUrl.url,
4813
- description: "Upload file to S3",
4814
- method: HttpMethod.POST,
4815
- isExternalUrl: true,
4816
- isAuthNeeded: false,
4817
- attachmentHash: sha1,
4818
- // TODO: can we use the sha1 as the blocker?
4819
- blockers: [`s3-${presignedUrl.fields.key}`],
4820
- blocks: [sha1],
4821
- s3url: presignedUrl
4822
- });
4823
- }
4824
- }
4825
4604
  fetchAll(projectId) {
4826
4605
  const promise = this.enqueueRequest({
4827
4606
  description: "Fetch attachments",
@@ -4848,7 +4627,6 @@ class AttachmentService extends BaseApiService {
4848
4627
  }
4849
4628
  const offlineAttachment = {
4850
4629
  ...attachmentPayload,
4851
- // TODO: just handle creating the objectURL in here, then the front end doesn't need to worry about it
4852
4630
  file: attachmentPayload.file.objectURL,
4853
4631
  file_name: attachmentPayload.file.name,
4854
4632
  file_type: attachmentPayload.file.type,
@@ -4882,7 +4660,6 @@ class AttachmentService extends BaseApiService {
4882
4660
  }
4883
4661
  const offlineAttachment = {
4884
4662
  ...attachmentPayload,
4885
- // TODO: just handle creating the objectURL in here, then the front end doesn't need to worry about it
4886
4663
  file: attachmentPayload.file.objectURL,
4887
4664
  file_name: attachmentPayload.file.name,
4888
4665
  file_type: attachmentPayload.file.type,
@@ -4916,7 +4693,6 @@ class AttachmentService extends BaseApiService {
4916
4693
  }
4917
4694
  const offlineAttachment = {
4918
4695
  ...attachmentPayload,
4919
- // TODO: just handle creating the objectURL in here, then the front end doesn't need to worry about it
4920
4696
  file: attachmentPayload.file.objectURL,
4921
4697
  file_name: attachmentPayload.file.name,
4922
4698
  file_type: attachmentPayload.file.type,
@@ -4982,54 +4758,26 @@ class AttachmentService extends BaseApiService {
4982
4758
  /** the outer Promise is needed to await the hashing of each file, which is required before offline use. If wanting to
4983
4759
  * attach promise handlers to the request to add the attachment in the backend, apply it on the promise returned from the
4984
4760
  * OptimisticModelResult. */
4985
- // note the method is only marked as async since files needs to be hashed
4986
- async attachFilesToIssue(files, issueId) {
4987
- const { store } = this.client;
4988
- const offlineAttachments = [];
4989
- const attachmentsPayload = [];
4990
- const currentUser = store.getState().userReducer.currentUser;
4991
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
4992
- for (const file of files) {
4993
- const attachment = offline({
4994
- file: URL.createObjectURL(file),
4995
- file_name: file.name,
4996
- file_type: file.type,
4997
- file_sha1: await hashFile(file),
4998
- description: "",
4999
- submitted_at: submittedAt,
5000
- created_by: currentUser.id,
5001
- issue: issueId
5002
- });
5003
- attachmentsPayload.push({
5004
- offline_id: attachment.offline_id,
5005
- name: attachment.file_name,
5006
- sha1: attachment.file_sha1,
5007
- description: attachment.description,
5008
- created_by: attachment.created_by,
5009
- issue_id: attachment.issue
5010
- });
5011
- offlineAttachments.push(attachment);
5012
- }
5013
- store.dispatch(addIssueAttachments(offlineAttachments));
5014
- const promise = this.enqueueRequest({
5015
- description: "Attach files to issue",
5016
- method: HttpMethod.POST,
5017
- url: `/issues/${issueId}/attach/`,
5018
- payload: {
5019
- submitted_at: submittedAt,
5020
- attachments: attachmentsPayload,
5021
- files: await constructUploadedFilePayloads(files)
5022
- },
5023
- blocks: offlineAttachments.map((attachment) => attachment.offline_id),
5024
- blockers: offlineAttachments.map((attachment) => attachment.file_sha1)
5025
- });
5026
- promise.then(({ attachments, presigned_urls }) => {
5027
- store.dispatch(updateIssueAttachments(attachments));
5028
- this.processPresignedUrls(presigned_urls);
5029
- }).catch(() => {
5030
- store.dispatch(removeIssueAttachments(offlineAttachments.map((attachment) => attachment.offline_id)));
4761
+ attachFilesToIssue(filesToSubmit, issueId) {
4762
+ return filesToSubmit.map((file) => {
4763
+ if (!(file instanceof File)) {
4764
+ throw new Error("Expected a File instance.");
4765
+ }
4766
+ const photoAttachmentPromise = async (file2) => {
4767
+ const hash = await hashFile(file2);
4768
+ const attachment = offline({
4769
+ file: file2,
4770
+ file_name: file2.name,
4771
+ file_type: file2.type,
4772
+ issue: issueId,
4773
+ file_sha1: hash,
4774
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4775
+ created_by: this.client.store.getState().userReducer.currentUser.id
4776
+ });
4777
+ return this.addIssueAttachment(attachment);
4778
+ };
4779
+ return photoAttachmentPromise(file);
5031
4780
  });
5032
- return [offlineAttachments, promise.then(({ attachments }) => attachments)];
5033
4781
  }
5034
4782
  attachFilesToComponent(filesToSubmit, componentId) {
5035
4783
  return filesToSubmit.map((file) => {
@@ -7012,7 +6760,7 @@ class UserFormService extends BaseApiService {
7012
6760
  ...revisionAttachmentPayload,
7013
6761
  file: URL.createObjectURL(image)
7014
6762
  };
7015
- store.dispatch(addFormRevisionAttachment(offlinePayload));
6763
+ store.dispatch(addUserFormRevisionAttachment(offlinePayload));
7016
6764
  return attach;
7017
6765
  });
7018
6766
  });
@@ -7046,8 +6794,8 @@ class UserFormService extends BaseApiService {
7046
6794
  revision: 0
7047
6795
  };
7048
6796
  const { store } = this.client;
7049
- store.dispatch(addForm(retForm));
7050
- store.dispatch(addFormRevision(retRevision));
6797
+ store.dispatch(addUserForm(retForm));
6798
+ store.dispatch(addUserFormRevision(retRevision));
7051
6799
  const formPromise = this.enqueueRequest({
7052
6800
  description: "Create form",
7053
6801
  method: HttpMethod.POST,
@@ -7065,8 +6813,8 @@ class UserFormService extends BaseApiService {
7065
6813
  });
7066
6814
  const attachImagesPromises = this.getAttachImagePromises(images, offlineRevisionPayload.offline_id);
7067
6815
  void formPromise.catch((e) => {
7068
- store.dispatch(deleteForm(retForm.offline_id));
7069
- store.dispatch(deleteFormRevision(retRevision.offline_id));
6816
+ store.dispatch(deleteUserForm(retForm.offline_id));
6817
+ store.dispatch(deleteUserFormRevision(retRevision.offline_id));
7070
6818
  throw e;
7071
6819
  });
7072
6820
  const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
@@ -7108,7 +6856,7 @@ class UserFormService extends BaseApiService {
7108
6856
  revision: "Pending",
7109
6857
  form: formId2
7110
6858
  };
7111
- store.dispatch(addFormRevision(fullRevision));
6859
+ store.dispatch(addUserFormRevision(fullRevision));
7112
6860
  const promise = this.enqueueRequest({
7113
6861
  description: "Create form revision",
7114
6862
  method: HttpMethod.PATCH,
@@ -7122,9 +6870,9 @@ class UserFormService extends BaseApiService {
7122
6870
  });
7123
6871
  const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
7124
6872
  void promise.then((result) => {
7125
- store.dispatch(setFormRevision(result));
6873
+ store.dispatch(addUserFormRevision(result));
7126
6874
  }).catch(() => {
7127
- store.dispatch(deleteFormRevision(fullRevision.offline_id));
6875
+ store.dispatch(deleteUserFormRevision(fullRevision.offline_id));
7128
6876
  });
7129
6877
  const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
7130
6878
  return [fullRevision, settledPromise];
@@ -7166,19 +6914,19 @@ class UserFormService extends BaseApiService {
7166
6914
  async delete(formId2) {
7167
6915
  const { store } = this.client;
7168
6916
  const state = store.getState();
7169
- const userForm = selectForm(formId2)(state);
6917
+ const userForm = selectUserForm(formId2)(state);
7170
6918
  if (!userForm) {
7171
6919
  throw new Error("Expected userForm to exist");
7172
6920
  }
7173
- const userFormSubmissions = selectFormSubmissionsOfForm(formId2)(state);
6921
+ const userFormSubmissions = selectSubmissionsForForm(formId2)(state);
7174
6922
  if (userFormSubmissions && userFormSubmissions.length > 0) {
7175
- store.dispatch(deleteFormSubmissions(userFormSubmissions.map(({ offline_id }) => offline_id)));
6923
+ store.dispatch(deleteUserFormSubmissions(userFormSubmissions));
7176
6924
  }
7177
- const userFormRevisions = selectFormRevisionsOfForm(formId2)(state);
6925
+ const userFormRevisions = selectRevisionsForForm(formId2)(state);
7178
6926
  if (userFormRevisions && userFormRevisions.length > 0) {
7179
- store.dispatch(deleteFormRevisions(userFormRevisions.map(({ offline_id }) => offline_id)));
6927
+ store.dispatch(deleteUserFormRevisions(userFormRevisions));
7180
6928
  }
7181
- store.dispatch(deleteForm(formId2));
6929
+ store.dispatch(deleteUserForm(formId2));
7182
6930
  try {
7183
6931
  return await this.enqueueRequest({
7184
6932
  description: "Delete form",
@@ -7188,12 +6936,12 @@ class UserFormService extends BaseApiService {
7188
6936
  blocks: []
7189
6937
  });
7190
6938
  } catch (e) {
7191
- store.dispatch(addForm(userForm));
6939
+ store.dispatch(addUserForm(userForm));
7192
6940
  if (userFormRevisions && userFormRevisions.length > 0) {
7193
- store.dispatch(addFormRevisions(userFormRevisions));
6941
+ store.dispatch(addUserFormRevisions(userFormRevisions));
7194
6942
  }
7195
6943
  if (userFormSubmissions && userFormSubmissions.length > 0) {
7196
- store.dispatch(addFormSubmissions(userFormSubmissions));
6944
+ store.dispatch(addUserFormSubmissions(userFormSubmissions));
7197
6945
  }
7198
6946
  throw e;
7199
6947
  }
@@ -7207,15 +6955,16 @@ class UserFormService extends BaseApiService {
7207
6955
  blockers: [],
7208
6956
  blocks: []
7209
6957
  });
7210
- store.dispatch(setForms(Object.values(result.forms)));
7211
- store.dispatch(setFormRevisions(Object.values(result.revisions)));
7212
- store.dispatch(setFormRevisionAttachments(Object.values(result.attachments)));
6958
+ store.dispatch(addUserForms(Object.values(result.forms)));
6959
+ store.dispatch(addUserFormRevisions(Object.values(result.revisions)));
6960
+ store.dispatch(setUserFormRevisionAttachments(Object.values(result.attachments)));
7213
6961
  }
7214
6962
  }
7215
6963
  const isArrayOfFiles = (value) => {
7216
6964
  return Array.isArray(value) && value[0] instanceof File;
7217
6965
  };
7218
- const separateFilesFromValues = (values) => {
6966
+ const separateFilesFromValues = (payload) => {
6967
+ const { values } = payload;
7219
6968
  const files = {};
7220
6969
  const newValues = {};
7221
6970
  for (const key in values) {
@@ -7230,13 +6979,17 @@ const separateFilesFromValues = (values) => {
7230
6979
  newValues[key] = value;
7231
6980
  }
7232
6981
  }
7233
- return { values: newValues, files };
6982
+ const payloadWithoutFiles = {
6983
+ ...payload,
6984
+ values: newValues
6985
+ };
6986
+ return { payloadWithoutFiles, files };
7234
6987
  };
7235
6988
  class UserFormSubmissionService extends BaseApiService {
7236
6989
  constructor() {
7237
6990
  super(...arguments);
7238
6991
  // Attach files to submission, after uploading them to S3
7239
- __publicField(this, "getAttachFilesPromises", (files, submission) => {
6992
+ __publicField(this, "getAttachFilesPromises", (files, payload) => {
7240
6993
  const { store } = this.client;
7241
6994
  return Object.entries(files).map(async ([key, fileArray]) => {
7242
6995
  const attachResults = [];
@@ -7246,27 +6999,24 @@ class UserFormSubmissionService extends BaseApiService {
7246
6999
  const [fileProps] = await this.client.files.uploadFileToS3(sha1);
7247
7000
  const submissionAttachmentPayload = offline({
7248
7001
  ...fileProps,
7249
- submission: submission.offline_id,
7002
+ submission: payload.offline_id,
7250
7003
  field_identifier: key
7251
7004
  });
7252
7005
  const attach = await this.enqueueRequest({
7253
7006
  description: "Attach file to form submission",
7254
7007
  method: HttpMethod.POST,
7255
- url: `/forms/submission/${submission.offline_id}/attachments/`,
7008
+ url: `/forms/submission/${payload.offline_id}/attachments/`,
7256
7009
  payload: submissionAttachmentPayload,
7257
- blockers: [
7258
- submission.component,
7259
- submission.component_stage,
7260
- submission.issue,
7261
- submission.form_revision
7262
- ].filter((x) => x !== void 0),
7010
+ blockers: [payload.component, payload.component_stage, payload.issue, payload.form_revision].filter(
7011
+ (x) => x !== void 0
7012
+ ),
7263
7013
  blocks: [submissionAttachmentPayload.offline_id]
7264
7014
  });
7265
7015
  const offlinePayload = {
7266
7016
  ...submissionAttachmentPayload,
7267
7017
  file: URL.createObjectURL(file)
7268
7018
  };
7269
- store.dispatch(addFormSubmissionAttachment(offlinePayload));
7019
+ store.dispatch(addUserFormSubmissionAttachment(offlinePayload));
7270
7020
  attachResults.push(attach);
7271
7021
  }
7272
7022
  return attachResults;
@@ -7280,165 +7030,70 @@ class UserFormSubmissionService extends BaseApiService {
7280
7030
  if (!activeProjectId) {
7281
7031
  throw new Error("Expected an active project");
7282
7032
  }
7283
- const { values, files } = separateFilesFromValues(payload.values);
7284
- const offlineSubmission = {
7285
- ...payload,
7286
- values,
7287
- created_by: state.userReducer.currentUser.id,
7288
- submitted_at: (/* @__PURE__ */ new Date()).toISOString()
7289
- };
7033
+ const { payloadWithoutFiles, files } = separateFilesFromValues(payload);
7290
7034
  const promise = this.enqueueRequest({
7291
7035
  description: "Respond to form",
7292
7036
  method: HttpMethod.POST,
7293
7037
  url: `/forms/revisions/${payload.form_revision}/respond/`,
7294
- payload: { ...offlineSubmission, project: activeProjectId },
7038
+ payload: { ...payloadWithoutFiles, project: activeProjectId },
7295
7039
  blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
7296
7040
  (x) => x !== void 0
7297
7041
  ),
7298
7042
  blocks: [payload.offline_id]
7299
7043
  });
7300
- const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
7301
- store.dispatch(addFormSubmission(offlineSubmission));
7044
+ const attachFilesPromises = this.getAttachFilesPromises(files, payload);
7045
+ const now = (/* @__PURE__ */ new Date()).toISOString();
7046
+ const fullOfflineResult = {
7047
+ ...payload,
7048
+ created_by: state.userReducer.currentUser.id,
7049
+ created_at: now,
7050
+ updated_at: now
7051
+ };
7052
+ const offlineResultWithoutFiles = {
7053
+ ...fullOfflineResult,
7054
+ ...payloadWithoutFiles
7055
+ };
7056
+ store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
7302
7057
  void promise.then((result) => {
7303
7058
  store.dispatch(addActiveProjectFormSubmissionsCount(1));
7304
- store.dispatch(setFormSubmission(result));
7059
+ store.dispatch(updateOrCreateUserFormSubmission(result));
7305
7060
  return result;
7306
7061
  }).catch(() => {
7307
- store.dispatch(deleteFormSubmission(payload.offline_id));
7062
+ store.dispatch(deleteUserFormSubmission(payload.offline_id));
7308
7063
  store.dispatch(addActiveProjectFormSubmissionsCount(-1));
7309
7064
  });
7310
7065
  const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
7311
- return [offlineSubmission, settledPromise];
7312
- }
7313
- // Note currently the bulkAdd method is specific to form submissions for components
7314
- // TODO: adapt the support bulk adding to any model type
7315
- async bulkAdd(args) {
7316
- const { form_revision, values: argsValues, componentOfflineIds } = args;
7317
- const { store } = this.client;
7318
- const offlineSubmissions = [];
7319
- const offlineAttachments = [];
7320
- const submissionOfflineIds = [];
7321
- const submissionsPayload = [];
7322
- const attachmentsPayload = [];
7323
- const { values, files } = separateFilesFromValues(argsValues);
7324
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
7325
- const createdBy = store.getState().userReducer.currentUser.id;
7326
- for (const component_id of componentOfflineIds) {
7327
- const submission = offline({
7328
- form_revision,
7329
- values,
7330
- created_by: createdBy,
7331
- submitted_at: submittedAt,
7332
- component: component_id
7333
- });
7334
- submissionOfflineIds.push(submission.offline_id);
7335
- submissionsPayload.push({ offline_id: submission.offline_id, component_id });
7336
- offlineSubmissions.push(submission);
7337
- for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
7338
- for (const file of fileArray) {
7339
- const sha1 = await hashFile(file);
7340
- await this.client.files.addCache(file, sha1);
7341
- const offlineAttachment = offline({
7342
- file_name: file.name,
7343
- file_sha1: sha1,
7344
- file: URL.createObjectURL(file),
7345
- submission: submission.offline_id,
7346
- field_identifier: fieldIdentifier
7347
- });
7348
- offlineAttachments.push(offlineAttachment);
7349
- attachmentsPayload.push({
7350
- offline_id: offlineAttachment.offline_id,
7351
- submission_id: submission.offline_id,
7352
- sha1,
7353
- name: file.name,
7354
- field_identifier: fieldIdentifier
7355
- });
7356
- }
7357
- }
7358
- }
7359
- const filesRecord = {};
7360
- for (const file of Object.values(files).flat()) {
7361
- const sha1 = await hashFile(file);
7362
- filesRecord[sha1] = {
7363
- sha1,
7364
- extension: file.name.split(".").pop() || "",
7365
- file_type: file.type,
7366
- size: file.size
7367
- };
7368
- }
7369
- store.dispatch(addFormSubmissions(offlineSubmissions));
7370
- store.dispatch(addFormSubmissionAttachments(offlineAttachments));
7371
- const promise = this.enqueueRequest({
7372
- description: "Bulk add form submissions",
7373
- method: HttpMethod.POST,
7374
- url: `/forms/revisions/${form_revision}/bulk-respond/`,
7375
- payload: {
7376
- form_data: values,
7377
- submitted_at: submittedAt,
7378
- submissions: submissionsPayload,
7379
- attachments: attachmentsPayload,
7380
- files: Object.values(filesRecord)
7381
- },
7382
- blockers: componentOfflineIds,
7383
- blocks: submissionOfflineIds
7384
- });
7385
- promise.then(({ submissions, attachments, presigned_urls }) => {
7386
- store.dispatch(updateFormSubmissions(submissions));
7387
- store.dispatch(updateFormSubmissionAttachments(attachments));
7388
- for (const [sha1, presigned_url] of Object.entries(presigned_urls)) {
7389
- const file = filesRecord[sha1];
7390
- if (!file)
7391
- continue;
7392
- void this.enqueueRequest({
7393
- url: presigned_url.url,
7394
- description: "Upload file",
7395
- method: HttpMethod.POST,
7396
- isExternalUrl: true,
7397
- isAuthNeeded: false,
7398
- attachmentHash: sha1,
7399
- blockers: [`s3-${file.sha1}.${file.extension}`],
7400
- blocks: [sha1],
7401
- s3url: presigned_url
7402
- });
7403
- }
7404
- }).catch(() => {
7405
- store.dispatch(deleteFormSubmissions(submissionOfflineIds));
7406
- store.dispatch(deleteFormSubmissionAttachments(offlineAttachments.map((x) => x.offline_id)));
7407
- });
7408
- return [offlineSubmissions, promise.then(({ submissions }) => submissions)];
7066
+ return [fullOfflineResult, settledPromise];
7409
7067
  }
7410
7068
  update(submission) {
7411
7069
  const { store } = this.client;
7412
- const { values, files } = separateFilesFromValues(submission.values);
7070
+ const { payloadWithoutFiles, files } = separateFilesFromValues(submission);
7071
+ if (!("created_by" in payloadWithoutFiles) || !("created_at" in payloadWithoutFiles)) {
7072
+ throw new Error("Expected payloadWithoutFiles to have created_by and created_at fields.");
7073
+ }
7413
7074
  const attachFilesPromises = this.getAttachFilesPromises(files, submission);
7414
- const offlineSubmission = {
7415
- ...submission,
7416
- values
7075
+ const fullResult = {
7076
+ ...payloadWithoutFiles,
7077
+ updated_at: (/* @__PURE__ */ new Date()).toISOString()
7417
7078
  };
7418
- const submissionToBeUpdated = store.getState().formSubmissionReducer.formSubmissions[submission.offline_id];
7419
- store.dispatch(updateFormSubmission(offlineSubmission));
7079
+ store.dispatch(updateOrCreateUserFormSubmission(fullResult));
7420
7080
  const promise = this.enqueueRequest({
7421
7081
  description: "Patch form submission",
7422
7082
  method: HttpMethod.PATCH,
7423
7083
  url: `/forms/submissions/${submission.offline_id}/`,
7424
- payload: offlineSubmission,
7425
- blockers: [offlineSubmission.issue, offlineSubmission.component, offlineSubmission.component_stage].filter(
7084
+ payload: fullResult,
7085
+ blockers: [fullResult.issue, fullResult.component, fullResult.component_stage].filter(
7426
7086
  (x) => x !== void 0
7427
7087
  ),
7428
- blocks: [offlineSubmission.offline_id]
7429
- });
7430
- promise.then((createdSubmission) => {
7431
- store.dispatch(setFormSubmission(createdSubmission));
7432
- }).catch(() => {
7433
- store.dispatch(setFormSubmission(submissionToBeUpdated));
7088
+ blocks: [fullResult.offline_id]
7434
7089
  });
7435
- return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
7090
+ return Promise.all([promise, ...attachFilesPromises]).then(() => promise);
7436
7091
  }
7437
7092
  async delete(submissionId) {
7438
7093
  const { store } = this.client;
7439
7094
  const state = store.getState();
7440
- const submission = state.formSubmissionReducer.formSubmissions[submissionId];
7441
- store.dispatch(deleteFormSubmission(submissionId));
7095
+ const submission = state.userFormReducer.submissions[submissionId];
7096
+ store.dispatch(deleteUserFormSubmission(submissionId));
7442
7097
  store.dispatch(addActiveProjectFormSubmissionsCount(-1));
7443
7098
  try {
7444
7099
  return await this.enqueueRequest({
@@ -7449,8 +7104,10 @@ class UserFormSubmissionService extends BaseApiService {
7449
7104
  blocks: []
7450
7105
  });
7451
7106
  } catch (e) {
7452
- store.dispatch(addActiveProjectFormSubmissionsCount(1));
7453
- store.dispatch(addFormSubmission(submission));
7107
+ if (submission) {
7108
+ store.dispatch(addActiveProjectFormSubmissionsCount(1));
7109
+ store.dispatch(updateOrCreateUserFormSubmission(submission));
7110
+ }
7454
7111
  throw e;
7455
7112
  }
7456
7113
  }
@@ -7464,7 +7121,7 @@ class UserFormSubmissionService extends BaseApiService {
7464
7121
  blockers: [],
7465
7122
  blocks: []
7466
7123
  });
7467
- store.dispatch(setFormSubmissions(submissions));
7124
+ store.dispatch(setUserFormSubmissions(submissions));
7468
7125
  const attachments = await this.enqueueRequest({
7469
7126
  description: "Fetch form attachments",
7470
7127
  method: HttpMethod.GET,
@@ -7472,7 +7129,7 @@ class UserFormSubmissionService extends BaseApiService {
7472
7129
  blockers: [],
7473
7130
  blocks: []
7474
7131
  });
7475
- store.dispatch(setFormSubmissionAttachments(attachments));
7132
+ store.dispatch(setUserFormSubmissionAttachments(attachments));
7476
7133
  }
7477
7134
  }
7478
7135
  class WorkspaceService extends BaseApiService {
@@ -14331,7 +13988,7 @@ const initialFormValues = (fields, values) => {
14331
13988
  };
14332
13989
  const useAttachImagesToFormRevisionFields = (revision) => {
14333
13990
  const { sdk } = useSDK();
14334
- const attachments = useAppSelector(selectAttachmentsOfFormRevision((revision == null ? void 0 : revision.offline_id) ?? ""));
13991
+ const attachments = useAppSelector(selectRevisionAttachments((revision == null ? void 0 : revision.offline_id) ?? ""));
14335
13992
  return useMemo(() => {
14336
13993
  if (!revision || !attachments)
14337
13994
  return revision;
@@ -14428,7 +14085,7 @@ const FormSubmissionViewer = memo(
14428
14085
  return formRevisionToSchema(revisionWithImages, { readonly: true });
14429
14086
  }, [revisionWithImages]);
14430
14087
  const submissionValuesWithAttachments = useMemo(() => {
14431
- const attachments = selectAttachmentsOfFormSubmission(submission.offline_id)(sdk.store.getState()) ?? [];
14088
+ const attachments = selectSubmissionAttachments(submission.offline_id)(sdk.store.getState()) ?? [];
14432
14089
  const downloadedAttachments = {};
14433
14090
  for (const attachment of attachments) {
14434
14091
  const promise = sdk.files.fetchFileFromUrl(attachment.file, attachment.file_sha1, attachment.file_name);
@@ -14478,8 +14135,8 @@ const FormBrowser = memo(
14478
14135
  }
14479
14136
  return ret;
14480
14137
  }, [filter, maxResults, ownerFilter]);
14481
- const userForms = useAppSelector(selectFilteredForms(ownerFilterOptions)) ?? [];
14482
- const userFormMapping = useAppSelector(selectFormMapping);
14138
+ const userForms = useAppSelector(selectFilteredUserForms(ownerFilterOptions)) ?? [];
14139
+ const userFormMapping = useAppSelector(selectUserFormMapping);
14483
14140
  const attachableUserForms = userForms.filter((form) => !form.component_type);
14484
14141
  const attachableUserFormMapping = Object.values(userFormMapping).filter(
14485
14142
  (form) => !form.component_type
@@ -14512,7 +14169,7 @@ const FormBrowser = memo(
14512
14169
  const handleChange = useCallback((e) => {
14513
14170
  setFilter(e.currentTarget.value);
14514
14171
  }, []);
14515
- const numberOfForms = useAppSelector(selectGeneralFormCount) || 0;
14172
+ const numberOfForms = useAppSelector(selectNumberOfGeneralUserForms) || 0;
14516
14173
  const numberOfHiddenForms = numberOfForms - attachableUserForms.length;
14517
14174
  const overflowMessage = attachableUserForms.length == maxResults && numberOfHiddenForms > 0 ? `Only the first ${maxResults} results are shown (${numberOfHiddenForms} hidden)` : numberOfHiddenForms > 0 && `${numberOfHiddenForms} hidden forms`;
14518
14175
  return /* @__PURE__ */ jsxs(Flex$1, { ref, direction: "column", gap: "2", children: [
@@ -14606,13 +14263,16 @@ const FormSubmissionBrowserEntry = memo((props) => {
14606
14263
  const { submission, onSubmissionClick, compact, labelType, rowDecorator } = props;
14607
14264
  const currentUser = useAppSelector(selectCurrentUser);
14608
14265
  const createdBy = useAppSelector(selectUser("created_by" in submission ? submission.created_by : currentUser.id));
14609
- const dateToUse = submission.submitted_at;
14610
- const formattedDateTime = getLocalDateString(dateToUse);
14266
+ const dateToUse = getCreatedAtOrSubmittedAtDate(submission);
14267
+ const formattedDateTime = isToday(dateToUse) ? dateToUse.toLocaleTimeString([], {
14268
+ hour: "2-digit",
14269
+ minute: "2-digit"
14270
+ }) : getLocalDateString(dateToUse);
14611
14271
  const revision = useAppSelector(selectFormRevision(submission.form_revision));
14612
14272
  if (!revision) {
14613
14273
  throw new Error(`Could not find revision ${submission.form_revision} for submission ${submission.offline_id}.`);
14614
14274
  }
14615
- const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevisionOfForm(revision.form))) == null ? void 0 : _a2.revision;
14275
+ const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevision(revision.form))) == null ? void 0 : _a2.revision;
14616
14276
  const creatorProfileSrc = useFileSrc({
14617
14277
  file: (createdBy == null ? void 0 : createdBy.profile.file) ?? null,
14618
14278
  fileSha1: (createdBy == null ? void 0 : createdBy.profile.file_sha1) ?? null
@@ -14643,6 +14303,10 @@ const FormSubmissionBrowserEntry = memo((props) => {
14643
14303
  return row;
14644
14304
  });
14645
14305
  FormSubmissionBrowserEntry.displayName = "FormSubmissionBrowserEntry";
14306
+ const getCreatedAtOrSubmittedAtDate = (submission) => {
14307
+ const date = "created_at" in submission ? submission.created_at : submission.submitted_at;
14308
+ return new Date(date);
14309
+ };
14646
14310
  const FormSubmissionBrowser = memo((props) => {
14647
14311
  const {
14648
14312
  formId: formId2,
@@ -14656,10 +14320,10 @@ const FormSubmissionBrowser = memo((props) => {
14656
14320
  if (!!formId2 === !!propSubmissions) {
14657
14321
  throw new Error("Either formId or submissions must be provided, but not both.");
14658
14322
  }
14659
- const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectFormSubmissionsOfForm(formId2));
14323
+ const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectSubmissionsForForm(formId2));
14660
14324
  const sortedSubmissions = useMemo(
14661
14325
  () => submissions == null ? void 0 : submissions.sort((a, b) => {
14662
- return a.submitted_at.localeCompare(b.submitted_at);
14326
+ return getCreatedAtOrSubmittedAtDate(b).getTime() - getCreatedAtOrSubmittedAtDate(a).getTime();
14663
14327
  }),
14664
14328
  [submissions]
14665
14329
  );
@@ -15977,7 +15641,6 @@ export {
15977
15641
  VerificationCodeType,
15978
15642
  WorkspaceService,
15979
15643
  YELLOW,
15980
- _selectLatestFormRevision,
15981
15644
  _setLatestRetryTime,
15982
15645
  acceptProjectInvite,
15983
15646
  addActiveProjectFormSubmissionsCount,
@@ -15995,16 +15658,6 @@ export {
15995
15658
  addDocuments,
15996
15659
  addEmailDomain,
15997
15660
  addFavouriteProjectId,
15998
- addForm,
15999
- addFormRevision,
16000
- addFormRevisionAttachment,
16001
- addFormRevisionAttachments,
16002
- addFormRevisions,
16003
- addFormSubmission,
16004
- addFormSubmissionAttachment,
16005
- addFormSubmissionAttachments,
16006
- addFormSubmissions,
16007
- addForms,
16008
15661
  addIssue,
16009
15662
  addIssueAttachment,
16010
15663
  addIssueAttachments,
@@ -16025,6 +15678,13 @@ export {
16025
15678
  addStageCompletions,
16026
15679
  addStages,
16027
15680
  addToRecentIssues,
15681
+ addUserForm,
15682
+ addUserFormRevision,
15683
+ addUserFormRevisionAttachment,
15684
+ addUserFormRevisions,
15685
+ addUserFormSubmissionAttachment,
15686
+ addUserFormSubmissions,
15687
+ addUserForms,
16028
15688
  addUsers,
16029
15689
  addWorkspace,
16030
15690
  areArraysEqual,
@@ -16045,7 +15705,6 @@ export {
16045
15705
  componentStageSlice,
16046
15706
  componentTypeReducer,
16047
15707
  componentTypeSlice,
16048
- constructUploadedFilePayloads,
16049
15708
  coordinatesAreEqual,
16050
15709
  coordinatesToLiteral,
16051
15710
  coordinatesToPointGeometry,
@@ -16056,16 +15715,12 @@ export {
16056
15715
  defaultBadgeColor,
16057
15716
  defaultStore,
16058
15717
  deleteComponentType,
16059
- deleteForm,
16060
- deleteFormRevision,
16061
- deleteFormRevisionAttachment,
16062
- deleteFormRevisionAttachments,
16063
- deleteFormRevisions,
16064
- deleteFormSubmission,
16065
- deleteFormSubmissionAttachment,
16066
- deleteFormSubmissionAttachments,
16067
- deleteFormSubmissions,
16068
15718
  deleteProject,
15719
+ deleteUserForm,
15720
+ deleteUserFormRevision,
15721
+ deleteUserFormRevisions,
15722
+ deleteUserFormSubmission,
15723
+ deleteUserFormSubmissions,
16069
15724
  dequeue,
16070
15725
  deserialize,
16071
15726
  deserializeField,
@@ -16094,13 +15749,7 @@ export {
16094
15749
  fileSlice,
16095
15750
  fileToBlob,
16096
15751
  flipCoordinates,
16097
- formReducer,
16098
- formRevisionReducer,
16099
15752
  formRevisionToSchema,
16100
- formRevisionsSlice,
16101
- formSlice,
16102
- formSubmissionReducer,
16103
- formSubmissionSlice,
16104
15753
  index as forms,
16105
15754
  fullComponentMarkerSize,
16106
15755
  generateBadgeColors,
@@ -16176,7 +15825,6 @@ export {
16176
15825
  removeFavouriteProjectId,
16177
15826
  removeIssue,
16178
15827
  removeIssueAttachment,
16179
- removeIssueAttachments,
16180
15828
  removeIssueComment,
16181
15829
  removeIssueComments,
16182
15830
  removeIssueUpdate,
@@ -16229,8 +15877,6 @@ export {
16229
15877
  selectAttachmentsOfComponentTypeByType,
16230
15878
  selectAttachmentsOfDocument,
16231
15879
  selectAttachmentsOfDocumentByType,
16232
- selectAttachmentsOfFormRevision,
16233
- selectAttachmentsOfFormSubmission,
16234
15880
  selectAttachmentsOfIssue,
16235
15881
  selectAttachmentsOfIssueByType,
16236
15882
  selectAttachmentsOfProject,
@@ -16246,11 +15892,11 @@ export {
16246
15892
  selectCompletedStageIdsForComponent,
16247
15893
  selectCompletedStages,
16248
15894
  selectComponent,
16249
- selectComponentAttachment,
16250
15895
  selectComponentAttachmentMapping,
15896
+ selectComponentSubmissionMapping,
16251
15897
  selectComponentType,
16252
- selectComponentTypeAttachment,
16253
15898
  selectComponentTypeAttachmentMapping,
15899
+ selectComponentTypeForm,
16254
15900
  selectComponentTypeFromComponent,
16255
15901
  selectComponentTypeFromComponents,
16256
15902
  selectComponentTypeStagesMapping,
@@ -16266,7 +15912,6 @@ export {
16266
15912
  selectCurrentUser,
16267
15913
  selectDeletedRequests,
16268
15914
  selectDocument,
16269
- selectDocumentAttachment,
16270
15915
  selectDocumentAttachmentMapping,
16271
15916
  selectDocuments,
16272
15917
  selectDocumentsMapping,
@@ -16280,24 +15925,8 @@ export {
16280
15925
  selectExpandedSections,
16281
15926
  selectFavouriteProjects,
16282
15927
  selectFileAttachmentsOfIssue,
16283
- selectFilteredForms,
16284
- selectForm,
16285
- selectFormMapping,
16286
- selectFormOfComponentType,
15928
+ selectFilteredUserForms,
16287
15929
  selectFormRevision,
16288
- selectFormRevisionMapping,
16289
- selectFormRevisions,
16290
- selectFormRevisionsOfForm,
16291
- selectFormSubmission,
16292
- selectFormSubmissionAttachmentsMapping,
16293
- selectFormSubmissions,
16294
- selectFormSubmissionsByComponents,
16295
- selectFormSubmissionsMapping,
16296
- selectFormSubmissionsOfComponent,
16297
- selectFormSubmissionsOfForm,
16298
- selectFormSubmissionsOfIssue,
16299
- selectFormsCount,
16300
- selectGeneralFormCount,
16301
15930
  selectHiddenCategoryCount,
16302
15931
  selectHiddenComponentTypeIds,
16303
15932
  selectIsFetchingInitialData,
@@ -16305,17 +15934,16 @@ export {
16305
15934
  selectIsLoading,
16306
15935
  selectIsLoggedIn,
16307
15936
  selectIssue,
16308
- selectIssueAttachment,
16309
15937
  selectIssueAttachmentMapping,
16310
15938
  selectIssueAttachments,
16311
15939
  selectIssueMapping,
16312
15940
  selectIssueUpdateMapping,
16313
15941
  selectIssueUpdatesOfIssue,
16314
15942
  selectIssues,
16315
- selectLatestFormRevisionByForm,
16316
- selectLatestFormRevisionOfForm,
16317
- selectLatestFormRevisionsOfComponentTypes,
15943
+ selectLatestFormRevision,
16318
15944
  selectLatestRetryTime,
15945
+ selectLatestRevisionByFormId,
15946
+ selectLatestRevisionsFromComponentTypeIds,
16319
15947
  selectLicense,
16320
15948
  selectLicenseForProject,
16321
15949
  selectLicenses,
@@ -16324,6 +15952,8 @@ export {
16324
15952
  selectMapStyle,
16325
15953
  selectNumberOfComponentTypesMatchingCaseInsensitiveName,
16326
15954
  selectNumberOfComponentsOfComponentType,
15955
+ selectNumberOfGeneralUserForms,
15956
+ selectNumberOfUserForms,
16327
15957
  selectOrganization,
16328
15958
  selectOrganizationAccess,
16329
15959
  selectOrganizationAccessForUser,
@@ -16351,6 +15981,8 @@ export {
16351
15981
  selectRecentIssuesAsSearchResults,
16352
15982
  selectRecentProjects,
16353
15983
  selectRehydrated,
15984
+ selectRevisionAttachments,
15985
+ selectRevisionsForForm,
16354
15986
  selectRootDocuments,
16355
15987
  selectShowTooltips,
16356
15988
  selectSortedEmailDomains,
@@ -16365,10 +15997,16 @@ export {
16365
15997
  selectStagesFromComponentType,
16366
15998
  selectStagesFromComponentTypeIds,
16367
15999
  selectStagesFromStageIds,
16000
+ selectSubmissionAttachments,
16001
+ selectSubmissionsForComponent,
16002
+ selectSubmissionsForForm,
16003
+ selectSubmissionsForIssue,
16368
16004
  selectUploadUrl,
16369
16005
  selectUsedColors,
16370
16006
  selectUser,
16371
- selectUserFormRevisionAttachmentsMapping,
16007
+ selectUserForm,
16008
+ selectUserFormMapping,
16009
+ selectUserFormSubmission,
16372
16010
  selectUsersAsMapping,
16373
16011
  selectVisibleStatuses,
16374
16012
  selectVisibleUserIds,
@@ -16395,13 +16033,6 @@ export {
16395
16033
  setEnableClustering,
16396
16034
  setEnableDuplicateIssues,
16397
16035
  setEnablePlacementMode,
16398
- setFormRevision,
16399
- setFormRevisionAttachments,
16400
- setFormRevisions,
16401
- setFormSubmission,
16402
- setFormSubmissionAttachments,
16403
- setFormSubmissions,
16404
- setForms,
16405
16036
  setIsFetchingInitialData,
16406
16037
  setIsImportingProjectFile,
16407
16038
  setIsLoading,
@@ -16426,6 +16057,9 @@ export {
16426
16057
  setTokens,
16427
16058
  setTourStep,
16428
16059
  setUploadUrl,
16060
+ setUserFormRevisionAttachments,
16061
+ setUserFormSubmissionAttachments,
16062
+ setUserFormSubmissions,
16429
16063
  setUsers,
16430
16064
  setVisibleStatuses,
16431
16065
  setVisibleUserIds,
@@ -16450,14 +16084,11 @@ export {
16450
16084
  updateComponentTypeAttachment,
16451
16085
  updateDocumentAttachment,
16452
16086
  updateDocuments,
16453
- updateFormSubmission,
16454
- updateFormSubmissionAttachments,
16455
- updateFormSubmissions,
16456
16087
  updateIssue,
16457
16088
  updateIssueAttachment,
16458
- updateIssueAttachments,
16459
16089
  updateLicense,
16460
16090
  updateOrCreateProject,
16091
+ updateOrCreateUserFormSubmission,
16461
16092
  updateOrganizationAccess,
16462
16093
  updateProjectAccess,
16463
16094
  updateProjectAttachment,
@@ -16471,6 +16102,8 @@ export {
16471
16102
  useFormikInput,
16472
16103
  useMemoCompare,
16473
16104
  useSDK,
16105
+ userFormReducer,
16106
+ userFormSlice,
16474
16107
  userReducer,
16475
16108
  userSlice,
16476
16109
  valueIsFile,