@overmap-ai/core 1.0.51-add-submitted-at-to-form-revisions.1 → 1.0.51-attachment-creation-flows.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.
Files changed (37) hide show
  1. package/dist/forms/renderer/FormSubmissionBrowser/FormSubmissionBrowser.d.ts +5 -5
  2. package/dist/forms/renderer/FormSubmissionViewer/FormSubmissionViewer.d.ts +3 -3
  3. package/dist/overmap-core.js +1231 -500
  4. package/dist/overmap-core.js.map +1 -1
  5. package/dist/overmap-core.umd.cjs +1231 -500
  6. package/dist/overmap-core.umd.cjs.map +1 -1
  7. package/dist/sdk/sdk.d.ts +6 -1
  8. package/dist/sdk/services/BaseAttachmentService.d.ts +31 -0
  9. package/dist/sdk/services/ComponentAttachmentService.d.ts +10 -0
  10. package/dist/sdk/services/ComponentTypeAttachmentService.d.ts +10 -0
  11. package/dist/sdk/services/DocumentAttachmentService.d.ts +10 -0
  12. package/dist/sdk/services/IssueAttachmentService.d.ts +10 -0
  13. package/dist/sdk/services/ProjectAttachmentService.d.ts +10 -0
  14. package/dist/sdk/services/UserFormSubmissionService.d.ts +9 -2
  15. package/dist/sdk/services/index.d.ts +5 -0
  16. package/dist/store/slices/categorySlice.d.ts +3 -1
  17. package/dist/store/slices/componentSlice.d.ts +15 -7
  18. package/dist/store/slices/componentTypeSlice.d.ts +16 -8
  19. package/dist/store/slices/documentSlice.d.ts +13 -3
  20. package/dist/store/slices/formRevisionSlice.d.ts +65 -0
  21. package/dist/store/slices/formSlice.d.ts +110 -0
  22. package/dist/store/slices/formSubmissionSlice.d.ts +47 -0
  23. package/dist/store/slices/index.d.ts +3 -1
  24. package/dist/store/slices/issueSlice.d.ts +36 -22
  25. package/dist/store/slices/projectFileSlice.d.ts +3 -1
  26. package/dist/store/slices/projectSlice.d.ts +12 -3
  27. package/dist/store/slices/utils.d.ts +4 -2
  28. package/dist/store/slices/workspaceSlice.d.ts +3 -1
  29. package/dist/store/store.d.ts +10 -4
  30. package/dist/typings/files.d.ts +11 -1
  31. package/dist/typings/models/attachments.d.ts +15 -11
  32. package/dist/typings/models/base.d.ts +7 -0
  33. package/dist/typings/models/forms.d.ts +6 -11
  34. package/dist/utils/file.d.ts +2 -0
  35. package/dist/utils/forms.d.ts +2 -0
  36. package/package.json +1 -1
  37. package/dist/store/slices/userFormSlice.d.ts +0 -145
@@ -668,15 +668,15 @@ var __publicField = (obj, key, value) => {
668
668
  };
669
669
  const migrations = [initialVersioning, signOut, signOut, createOutboxState];
670
670
  const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
671
- const initialState$n = {
671
+ const initialState$p = {
672
672
  accessToken: "",
673
673
  refreshToken: "",
674
674
  isLoggedIn: false
675
675
  };
676
676
  const authSlice = toolkit.createSlice({
677
677
  name: "auth",
678
- initialState: initialState$n,
679
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
678
+ initialState: initialState$p,
679
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$p)),
680
680
  reducers: {
681
681
  setTokens: (state, action) => {
682
682
  state.accessToken = action.payload.accessToken;
@@ -841,6 +841,19 @@ var __publicField = (obj, key, value) => {
841
841
  element.click();
842
842
  document.body.removeChild(element);
843
843
  }
844
+ const constructUploadedFilePayloads = async (files) => {
845
+ const filePayloads = {};
846
+ for (const file of files) {
847
+ const sha1 = await hashFile(file);
848
+ filePayloads[sha1] = {
849
+ sha1,
850
+ extension: file.name.split(".").pop() || "",
851
+ file_type: file.type,
852
+ size: file.size
853
+ };
854
+ }
855
+ return Object.values(filePayloads);
856
+ };
844
857
  const fileToBlob = async (dataUrl) => {
845
858
  return (await fetch(dataUrl)).blob();
846
859
  };
@@ -1407,7 +1420,7 @@ var __publicField = (obj, key, value) => {
1407
1420
  return getLocalDateString(date);
1408
1421
  return relative.format(days, "days");
1409
1422
  });
1410
- const initialState$m = {
1423
+ const initialState$o = {
1411
1424
  categories: {},
1412
1425
  usedCategoryColors: [],
1413
1426
  categoryVisibility: {
@@ -1417,8 +1430,8 @@ var __publicField = (obj, key, value) => {
1417
1430
  };
1418
1431
  const categorySlice = toolkit.createSlice({
1419
1432
  name: "categories",
1420
- initialState: initialState$m,
1421
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1433
+ initialState: initialState$o,
1434
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$o)),
1422
1435
  reducers: {
1423
1436
  setCategories: (state, action) => {
1424
1437
  if (!Array.isArray(action.payload))
@@ -1551,6 +1564,9 @@ var __publicField = (obj, key, value) => {
1551
1564
  return hiddenCategoryCount;
1552
1565
  };
1553
1566
  const categoryReducer = categorySlice.reducer;
1567
+ function setAttachment(state, action) {
1568
+ state.attachments[action.payload.offline_id] = action.payload;
1569
+ }
1554
1570
  function setAttachments(state, action) {
1555
1571
  state.attachments = {};
1556
1572
  for (const attachment of action.payload) {
@@ -1575,6 +1591,15 @@ var __publicField = (obj, key, value) => {
1575
1591
  throw new Error(`Attachment ${action.payload.offline_id} does not exist.`);
1576
1592
  }
1577
1593
  }
1594
+ function updateAttachments(state, action) {
1595
+ for (const attachment of action.payload) {
1596
+ if (attachment.offline_id in state.attachments) {
1597
+ state.attachments[attachment.offline_id] = attachment;
1598
+ } else {
1599
+ throw new Error(`Attachment ${attachment.offline_id} does not exist.`);
1600
+ }
1601
+ }
1602
+ }
1578
1603
  function removeAttachment(state, action) {
1579
1604
  if (action.payload in state.attachments) {
1580
1605
  delete state.attachments[action.payload];
@@ -1587,14 +1612,14 @@ var __publicField = (obj, key, value) => {
1587
1612
  delete state.attachments[attachmentId];
1588
1613
  }
1589
1614
  }
1590
- const initialState$l = {
1615
+ const initialState$n = {
1591
1616
  components: {},
1592
1617
  attachments: {}
1593
1618
  };
1594
1619
  const componentSlice = toolkit.createSlice({
1595
1620
  name: "components",
1596
- initialState: initialState$l,
1597
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1621
+ initialState: initialState$n,
1622
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
1598
1623
  reducers: {
1599
1624
  addComponent: (state, action) => {
1600
1625
  state.components[action.payload.offline_id] = action.payload;
@@ -1608,12 +1633,6 @@ var __publicField = (obj, key, value) => {
1608
1633
  state.components = toOfflineIdRecord(action.payload);
1609
1634
  prevComponents = null;
1610
1635
  },
1611
- setComponentAttachments: setAttachments,
1612
- addComponentAttachment: addAttachment,
1613
- addComponentAttachments: addAttachments,
1614
- updateComponentAttachment: updateAttachment,
1615
- removeComponentAttachment: removeAttachment,
1616
- removeComponentAttachments: removeAttachments,
1617
1636
  updateComponent: (state, action) => {
1618
1637
  if (action.payload.offline_id in state.components) {
1619
1638
  state.components[action.payload.offline_id] = action.payload;
@@ -1638,9 +1657,35 @@ var __publicField = (obj, key, value) => {
1638
1657
  }
1639
1658
  }
1640
1659
  prevComponents = null;
1641
- }
1660
+ },
1661
+ // Attachments
1662
+ setComponentAttachment: setAttachment,
1663
+ setComponentAttachments: setAttachments,
1664
+ addComponentAttachment: addAttachment,
1665
+ addComponentAttachments: addAttachments,
1666
+ updateComponentAttachment: updateAttachment,
1667
+ updateComponentAttachments: updateAttachments,
1668
+ removeComponentAttachment: removeAttachment,
1669
+ removeComponentAttachments: removeAttachments
1642
1670
  }
1643
1671
  });
1672
+ const {
1673
+ addComponent,
1674
+ updateComponent,
1675
+ removeComponent,
1676
+ addComponentsInBatches,
1677
+ setComponents,
1678
+ removeAllComponentsOfType,
1679
+ // Attachments
1680
+ setComponentAttachment,
1681
+ setComponentAttachments,
1682
+ addComponentAttachment,
1683
+ addComponentAttachments,
1684
+ updateComponentAttachment,
1685
+ updateComponentAttachments,
1686
+ removeComponentAttachment,
1687
+ removeComponentAttachments
1688
+ } = componentSlice.actions;
1644
1689
  let prevComponents = null;
1645
1690
  const selectComponents = (state) => {
1646
1691
  if (!prevComponents) {
@@ -1735,28 +1780,14 @@ var __publicField = (obj, key, value) => {
1735
1780
  }
1736
1781
  )
1737
1782
  );
1738
- const {
1739
- addComponent,
1740
- updateComponent,
1741
- removeComponent,
1742
- addComponentsInBatches,
1743
- setComponents,
1744
- setComponentAttachments,
1745
- addComponentAttachment,
1746
- addComponentAttachments,
1747
- updateComponentAttachment,
1748
- removeComponentAttachment,
1749
- removeComponentAttachments,
1750
- removeAllComponentsOfType
1751
- } = componentSlice.actions;
1752
1783
  const componentReducer = componentSlice.reducer;
1753
- const initialState$k = {
1784
+ const initialState$m = {
1754
1785
  completionsByComponentId: {}
1755
1786
  };
1756
1787
  const componentStageCompletionSlice = toolkit.createSlice({
1757
1788
  name: "componentStageCompletions",
1758
- initialState: initialState$k,
1759
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1789
+ initialState: initialState$m,
1790
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1760
1791
  reducers: {
1761
1792
  addStageCompletion: (state, action) => {
1762
1793
  let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
@@ -1807,13 +1838,13 @@ var __publicField = (obj, key, value) => {
1807
1838
  return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
1808
1839
  };
1809
1840
  const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
1810
- const initialState$j = {
1841
+ const initialState$l = {
1811
1842
  stages: {}
1812
1843
  };
1813
1844
  const componentStageSlice = toolkit.createSlice({
1814
1845
  name: "componentStages",
1815
- initialState: initialState$j,
1816
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1846
+ initialState: initialState$l,
1847
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1817
1848
  reducers: {
1818
1849
  addStages: (state, action) => {
1819
1850
  Object.assign(state.stages, toOfflineIdRecord(action.payload));
@@ -1923,15 +1954,15 @@ var __publicField = (obj, key, value) => {
1923
1954
  );
1924
1955
  const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
1925
1956
  const componentStageReducer = componentStageSlice.reducer;
1926
- const initialState$i = {
1957
+ const initialState$k = {
1927
1958
  componentTypes: {},
1928
1959
  hiddenComponentTypeIds: {},
1929
1960
  attachments: {}
1930
1961
  };
1931
1962
  const componentTypeSlice = toolkit.createSlice({
1932
1963
  name: "componentTypes",
1933
- initialState: initialState$i,
1934
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1964
+ initialState: initialState$k,
1965
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1935
1966
  reducers: {
1936
1967
  addComponentType: (state, action) => {
1937
1968
  state.componentTypes[action.payload.offline_id] = action.payload;
@@ -1939,20 +1970,38 @@ var __publicField = (obj, key, value) => {
1939
1970
  setComponentTypes: (state, action) => {
1940
1971
  state.componentTypes = toOfflineIdRecord(action.payload);
1941
1972
  },
1942
- setComponentTypeAttachments: setAttachments,
1943
- addComponentTypeAttachment: addAttachment,
1944
- addComponentTypeAttachments: addAttachments,
1945
- updateComponentTypeAttachment: updateAttachment,
1946
- removeComponentTypeAttachment: removeAttachment,
1947
- removeComponentTypeAttachments: removeAttachments,
1948
1973
  toggleComponentTypeVisibility: (state, action) => {
1949
1974
  state.hiddenComponentTypeIds[action.payload] = !state.hiddenComponentTypeIds[action.payload];
1950
1975
  },
1951
1976
  deleteComponentType: (state, action) => {
1952
1977
  delete state.componentTypes[action.payload];
1953
- }
1978
+ },
1979
+ // Attachments
1980
+ setComponentTypeAttachment: setAttachment,
1981
+ setComponentTypeAttachments: setAttachments,
1982
+ addComponentTypeAttachment: addAttachment,
1983
+ addComponentTypeAttachments: addAttachments,
1984
+ updateComponentTypeAttachment: updateAttachment,
1985
+ updateComponentTypeAttachments: updateAttachments,
1986
+ removeComponentTypeAttachment: removeAttachment,
1987
+ removeComponentTypeAttachments: removeAttachments
1954
1988
  }
1955
1989
  });
1990
+ const {
1991
+ addComponentType,
1992
+ setComponentTypes,
1993
+ toggleComponentTypeVisibility,
1994
+ deleteComponentType,
1995
+ // Attachmet
1996
+ setComponentTypeAttachment,
1997
+ setComponentTypeAttachments,
1998
+ addComponentTypeAttachment,
1999
+ addComponentTypeAttachments,
2000
+ updateComponentTypeAttachment,
2001
+ updateComponentTypeAttachments,
2002
+ removeComponentTypeAttachment,
2003
+ removeComponentTypeAttachments
2004
+ } = componentTypeSlice.actions;
1956
2005
  const selectComponentTypesMapping = (state) => state.componentTypeReducer.componentTypes;
1957
2006
  const selectComponentTypes = toolkit.createSelector(
1958
2007
  [selectComponentTypesMapping],
@@ -2029,26 +2078,14 @@ var __publicField = (obj, key, value) => {
2029
2078
  }
2030
2079
  )
2031
2080
  );
2032
- const {
2033
- addComponentType,
2034
- setComponentTypes,
2035
- setComponentTypeAttachments,
2036
- addComponentTypeAttachment,
2037
- addComponentTypeAttachments,
2038
- updateComponentTypeAttachment,
2039
- removeComponentTypeAttachment,
2040
- removeComponentTypeAttachments,
2041
- toggleComponentTypeVisibility,
2042
- deleteComponentType
2043
- } = componentTypeSlice.actions;
2044
2081
  const componentTypeReducer = componentTypeSlice.reducer;
2045
- const initialState$h = {
2082
+ const initialState$j = {
2046
2083
  workspaces: {},
2047
2084
  activeWorkspaceId: null
2048
2085
  };
2049
2086
  const workspaceSlice = toolkit.createSlice({
2050
2087
  name: "workspace",
2051
- initialState: initialState$h,
2088
+ initialState: initialState$j,
2052
2089
  // The `reducers` field lets us define reducers and generate associated actions
2053
2090
  reducers: {
2054
2091
  setWorkspaces: (state, action) => {
@@ -2105,7 +2142,7 @@ var __publicField = (obj, key, value) => {
2105
2142
  );
2106
2143
  const workspaceReducer = workspaceSlice.reducer;
2107
2144
  const maxRecentIssues = 10;
2108
- const initialState$g = {
2145
+ const initialState$i = {
2109
2146
  issues: {},
2110
2147
  attachments: {},
2111
2148
  comments: {},
@@ -2117,9 +2154,9 @@ var __publicField = (obj, key, value) => {
2117
2154
  };
2118
2155
  const issueSlice = toolkit.createSlice({
2119
2156
  name: "issues",
2120
- initialState: initialState$g,
2157
+ initialState: initialState$i,
2121
2158
  extraReducers: (builder) => builder.addCase("RESET", (state) => {
2122
- Object.assign(state, initialState$g);
2159
+ Object.assign(state, initialState$i);
2123
2160
  }),
2124
2161
  reducers: {
2125
2162
  setIssues: (state, action) => {
@@ -2130,7 +2167,6 @@ var __publicField = (obj, key, value) => {
2130
2167
  state.issues[issue.offline_id] = issue;
2131
2168
  });
2132
2169
  },
2133
- setIssueAttachments: setAttachments,
2134
2170
  setIssueUpdates: (state, action) => {
2135
2171
  if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2136
2172
  throw new Error("Tried to use setIssues reducer with duplicate ID's");
@@ -2150,8 +2186,6 @@ var __publicField = (obj, key, value) => {
2150
2186
  }
2151
2187
  state.issues[action.payload.offline_id] = action.payload;
2152
2188
  },
2153
- addIssueAttachment: addAttachment,
2154
- addIssueAttachments: addAttachments,
2155
2189
  addIssueUpdate: (state, action) => {
2156
2190
  if (action.payload.offline_id in state.updates) {
2157
2191
  throw new Error(`Tried to add duplicate issue update with offline_id: ${action.payload.offline_id}`);
@@ -2173,7 +2207,6 @@ var __publicField = (obj, key, value) => {
2173
2207
  throw new Error(`Tried to update issue with ID that doesn't exist: ${action.payload.offline_id}`);
2174
2208
  }
2175
2209
  },
2176
- updateIssueAttachment: updateAttachment,
2177
2210
  removeIssue: (state, action) => {
2178
2211
  if (action.payload in state.issues) {
2179
2212
  delete state.issues[action.payload];
@@ -2181,7 +2214,6 @@ var __publicField = (obj, key, value) => {
2181
2214
  throw new Error(`Failed to remove issue because ID doesn't exist: ${action.payload}`);
2182
2215
  }
2183
2216
  },
2184
- removeIssueAttachment: removeAttachment,
2185
2217
  removeIssueUpdate: (state, action) => {
2186
2218
  if (action.payload in state.updates) {
2187
2219
  delete state.updates[action.payload];
@@ -2278,19 +2310,25 @@ var __publicField = (obj, key, value) => {
2278
2310
  if (indexToRemove !== -1) {
2279
2311
  state.recentIssueIds.splice(indexToRemove, 1);
2280
2312
  }
2281
- }
2313
+ },
2314
+ // Attachments
2315
+ setIssueAttachment: setAttachment,
2316
+ setIssueAttachments: setAttachments,
2317
+ addIssueAttachment: addAttachment,
2318
+ addIssueAttachments: addAttachments,
2319
+ updateIssueAttachment: updateAttachment,
2320
+ updateIssueAttachments: updateAttachments,
2321
+ removeIssueAttachment: removeAttachment,
2322
+ removeIssueAttachments: removeAttachments
2282
2323
  }
2283
2324
  });
2284
2325
  const {
2285
- addIssueAttachment,
2286
- addIssueAttachments,
2287
2326
  addIssue,
2288
2327
  addIssueUpdate,
2289
2328
  addIssueUpdates,
2290
2329
  addOrReplaceIssueComment,
2291
2330
  addToRecentIssues,
2292
2331
  cleanRecentIssues,
2293
- removeIssueAttachment,
2294
2332
  removeAttachmentsOfIssue,
2295
2333
  removeIssue,
2296
2334
  removeIssueUpdate,
@@ -2298,13 +2336,20 @@ var __publicField = (obj, key, value) => {
2298
2336
  removeRecentIssue,
2299
2337
  resetRecentIssues,
2300
2338
  setActiveIssueId,
2301
- setIssueAttachments,
2302
2339
  setIssueUpdates,
2303
2340
  setIssues,
2304
2341
  setVisibleStatuses,
2305
2342
  setVisibleUserIds,
2306
- updateIssueAttachment,
2307
2343
  updateIssue,
2344
+ // Attachments
2345
+ setIssueAttachment,
2346
+ setIssueAttachments,
2347
+ addIssueAttachment,
2348
+ addIssueAttachments,
2349
+ updateIssueAttachment,
2350
+ updateIssueAttachments,
2351
+ removeIssueAttachment,
2352
+ removeIssueAttachments,
2308
2353
  // Commments
2309
2354
  addIssueComment,
2310
2355
  addIssueComments,
@@ -2527,15 +2572,15 @@ var __publicField = (obj, key, value) => {
2527
2572
  }
2528
2573
  );
2529
2574
  const issueReducer = issueSlice.reducer;
2530
- const initialState$f = {
2575
+ const initialState$h = {
2531
2576
  s3Urls: {}
2532
2577
  };
2533
2578
  const msPerHour = 1e3 * 60 * 60;
2534
2579
  const msPerWeek = msPerHour * 24 * 7;
2535
2580
  const fileSlice = toolkit.createSlice({
2536
2581
  name: "file",
2537
- initialState: initialState$f,
2538
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2582
+ initialState: initialState$h,
2583
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
2539
2584
  reducers: {
2540
2585
  setUploadUrl: (state, action) => {
2541
2586
  const { url, fields, sha1 } = action.payload;
@@ -2562,7 +2607,7 @@ var __publicField = (obj, key, value) => {
2562
2607
  return url;
2563
2608
  };
2564
2609
  const fileReducer = fileSlice.reducer;
2565
- const initialState$e = {
2610
+ const initialState$g = {
2566
2611
  // TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
2567
2612
  mapStyle: MapStyle.SATELLITE,
2568
2613
  showTooltips: false,
@@ -2570,8 +2615,8 @@ var __publicField = (obj, key, value) => {
2570
2615
  };
2571
2616
  const mapSlice = toolkit.createSlice({
2572
2617
  name: "map",
2573
- initialState: initialState$e,
2574
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2618
+ initialState: initialState$g,
2619
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
2575
2620
  reducers: {
2576
2621
  setMapStyle: (state, action) => {
2577
2622
  state.mapStyle = action.payload;
@@ -2599,6 +2644,14 @@ var __publicField = (obj, key, value) => {
2599
2644
  OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
2600
2645
  return OrganizationAccessLevel2;
2601
2646
  })(OrganizationAccessLevel || {});
2647
+ var AttachmentModel = /* @__PURE__ */ ((AttachmentModel2) => {
2648
+ AttachmentModel2["Issue"] = "issue";
2649
+ AttachmentModel2["Component"] = "component";
2650
+ AttachmentModel2["ComponentType"] = "component_type";
2651
+ AttachmentModel2["Project"] = "project";
2652
+ AttachmentModel2["Document"] = "document";
2653
+ return AttachmentModel2;
2654
+ })(AttachmentModel || {});
2602
2655
  var IssueUpdateChange = /* @__PURE__ */ ((IssueUpdateChange2) => {
2603
2656
  IssueUpdateChange2["STATUS"] = "status";
2604
2657
  IssueUpdateChange2["PRIORITY"] = "priority";
@@ -2640,7 +2693,7 @@ var __publicField = (obj, key, value) => {
2640
2693
  LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
2641
2694
  return LicenseStatus2;
2642
2695
  })(LicenseStatus || {});
2643
- const initialState$d = {
2696
+ const initialState$f = {
2644
2697
  users: {},
2645
2698
  currentUser: {
2646
2699
  id: 0,
@@ -2651,8 +2704,8 @@ var __publicField = (obj, key, value) => {
2651
2704
  };
2652
2705
  const userSlice = toolkit.createSlice({
2653
2706
  name: "users",
2654
- initialState: initialState$d,
2655
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2707
+ initialState: initialState$f,
2708
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2656
2709
  reducers: {
2657
2710
  setUsers: (state, action) => {
2658
2711
  const usersMapping = {};
@@ -2714,13 +2767,13 @@ var __publicField = (obj, key, value) => {
2714
2767
  const selectUsersAsMapping = (state) => state.userReducer.users;
2715
2768
  const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
2716
2769
  const userReducer = userSlice.reducer;
2717
- const initialState$c = {
2770
+ const initialState$e = {
2718
2771
  organizationAccesses: {}
2719
2772
  };
2720
2773
  const organizationAccessSlice = toolkit.createSlice({
2721
2774
  name: "organizationAccess",
2722
- initialState: initialState$c,
2723
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2775
+ initialState: initialState$e,
2776
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2724
2777
  reducers: {
2725
2778
  setOrganizationAccesses: (state, action) => {
2726
2779
  if (!Array.isArray(action.payload))
@@ -2783,13 +2836,13 @@ var __publicField = (obj, key, value) => {
2783
2836
  return organizationAccesses;
2784
2837
  };
2785
2838
  const organizationAccessReducer = organizationAccessSlice.reducer;
2786
- const initialState$b = {
2839
+ const initialState$d = {
2787
2840
  licenses: {}
2788
2841
  };
2789
2842
  const licenseSlice = toolkit.createSlice({
2790
2843
  name: "license",
2791
- initialState: initialState$b,
2792
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2844
+ initialState: initialState$d,
2845
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2793
2846
  reducers: {
2794
2847
  setLicenses: (state, action) => {
2795
2848
  if (!Array.isArray(action.payload))
@@ -2834,13 +2887,13 @@ var __publicField = (obj, key, value) => {
2834
2887
  (licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
2835
2888
  );
2836
2889
  const licenseReducer = licenseSlice.reducer;
2837
- const initialState$a = {
2890
+ const initialState$c = {
2838
2891
  projectAccesses: {}
2839
2892
  };
2840
2893
  const projectAccessSlice = toolkit.createSlice({
2841
2894
  name: "projectAccess",
2842
- initialState: initialState$a,
2843
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2895
+ initialState: initialState$c,
2896
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2844
2897
  reducers: {
2845
2898
  setProjectAccesses: (state, action) => {
2846
2899
  if (!Array.isArray(action.payload))
@@ -2908,7 +2961,7 @@ var __publicField = (obj, key, value) => {
2908
2961
  return projectAccesses;
2909
2962
  };
2910
2963
  const projectAccessReducer = projectAccessSlice.reducer;
2911
- const initialState$9 = {
2964
+ const initialState$b = {
2912
2965
  projects: {},
2913
2966
  activeProjectId: null,
2914
2967
  recentProjectIds: [],
@@ -2918,7 +2971,7 @@ var __publicField = (obj, key, value) => {
2918
2971
  };
2919
2972
  const projectSlice = toolkit.createSlice({
2920
2973
  name: "projects",
2921
- initialState: initialState$9,
2974
+ initialState: initialState$b,
2922
2975
  reducers: {
2923
2976
  setProjects: (state, action) => {
2924
2977
  const projectsMap = {};
@@ -2986,11 +3039,13 @@ var __publicField = (obj, key, value) => {
2986
3039
  throw new Error("Update form submissions count: no active project");
2987
3040
  }
2988
3041
  },
2989
- // Attachment related
3042
+ // Attachments
3043
+ setProjectAttachment: setAttachment,
2990
3044
  setProjectAttachments: setAttachments,
2991
3045
  addProjectAttachment: addAttachment,
2992
3046
  addProjectAttachments: addAttachments,
2993
3047
  updateProjectAttachment: updateAttachment,
3048
+ updateProjectAttachments: updateAttachments,
2994
3049
  removeProjectAttachment: removeAttachment,
2995
3050
  removeProjectAttachments: removeAttachments
2996
3051
  }
@@ -3005,11 +3060,13 @@ var __publicField = (obj, key, value) => {
3005
3060
  acceptProjectInvite,
3006
3061
  addActiveProjectIssuesCount,
3007
3062
  addActiveProjectFormSubmissionsCount,
3008
- // Attachment related
3063
+ // Attachments
3064
+ setProjectAttachment,
3009
3065
  setProjectAttachments,
3010
3066
  addProjectAttachment,
3011
3067
  addProjectAttachments,
3012
3068
  updateProjectAttachment,
3069
+ updateProjectAttachments,
3013
3070
  removeProjectAttachment,
3014
3071
  removeProjectAttachments
3015
3072
  } = projectSlice.actions;
@@ -3080,6 +3137,9 @@ var __publicField = (obj, key, value) => {
3080
3137
  [selectProjectAttachmentMapping],
3081
3138
  (mapping) => Object.values(mapping)
3082
3139
  );
3140
+ const selectProjectAttachment = (attachmentId) => (state) => {
3141
+ return state.projectReducer.attachments[attachmentId];
3142
+ };
3083
3143
  const selectAttachmentsOfProject = restructureCreateSelectorWithArgs(
3084
3144
  toolkit.createSelector(
3085
3145
  [selectAllProjectAttachments, (_state, projectId) => projectId],
@@ -3105,14 +3165,14 @@ var __publicField = (obj, key, value) => {
3105
3165
  }
3106
3166
  )
3107
3167
  );
3108
- const initialState$8 = {
3168
+ const initialState$a = {
3109
3169
  organizations: {},
3110
3170
  activeOrganizationId: null
3111
3171
  };
3112
3172
  const organizationSlice = toolkit.createSlice({
3113
3173
  name: "organizations",
3114
- initialState: initialState$8,
3115
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3174
+ initialState: initialState$a,
3175
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
3116
3176
  reducers: {
3117
3177
  setOrganizations: (state, action) => {
3118
3178
  for (const org of action.payload) {
@@ -3231,14 +3291,14 @@ var __publicField = (obj, key, value) => {
3231
3291
  }
3232
3292
  };
3233
3293
  };
3234
- const initialState$7 = {
3294
+ const initialState$9 = {
3235
3295
  deletedRequests: [],
3236
3296
  latestRetryTime: 0
3237
3297
  };
3238
3298
  const outboxSlice = toolkit.createSlice({
3239
3299
  name: "outbox",
3240
- initialState: initialState$7,
3241
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
3300
+ initialState: initialState$9,
3301
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
3242
3302
  reducers: {
3243
3303
  // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
3244
3304
  // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
@@ -3270,7 +3330,7 @@ var __publicField = (obj, key, value) => {
3270
3330
  const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
3271
3331
  const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
3272
3332
  const outboxReducer = outboxSlice.reducer;
3273
- const initialState$6 = {
3333
+ const initialState$8 = {
3274
3334
  projectFiles: {},
3275
3335
  activeProjectFileId: null,
3276
3336
  isImportingProjectFile: false,
@@ -3278,8 +3338,8 @@ var __publicField = (obj, key, value) => {
3278
3338
  };
3279
3339
  const projectFileSlice = toolkit.createSlice({
3280
3340
  name: "projectFiles",
3281
- initialState: initialState$6,
3282
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
3341
+ initialState: initialState$8,
3342
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3283
3343
  reducers: {
3284
3344
  addOrReplaceProjectFiles: (state, action) => {
3285
3345
  for (let fileObj of action.payload) {
@@ -3380,12 +3440,12 @@ var __publicField = (obj, key, value) => {
3380
3440
  const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
3381
3441
  const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
3382
3442
  const projectFileReducer = projectFileSlice.reducer;
3383
- const initialState$5 = {
3443
+ const initialState$7 = {
3384
3444
  isRehydrated: false
3385
3445
  };
3386
3446
  const rehydratedSlice = toolkit.createSlice({
3387
3447
  name: "rehydrated",
3388
- initialState: initialState$5,
3448
+ initialState: initialState$7,
3389
3449
  // The `reducers` field lets us define reducers and generate associated actions
3390
3450
  reducers: {
3391
3451
  setRehydrated: (state, action) => {
@@ -3395,7 +3455,7 @@ var __publicField = (obj, key, value) => {
3395
3455
  });
3396
3456
  const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
3397
3457
  const rehydratedReducer = rehydratedSlice.reducer;
3398
- const initialState$4 = {
3458
+ const initialState$6 = {
3399
3459
  useIssueTemplate: false,
3400
3460
  placementMode: false,
3401
3461
  enableClustering: false,
@@ -3412,8 +3472,8 @@ var __publicField = (obj, key, value) => {
3412
3472
  };
3413
3473
  const settingSlice = toolkit.createSlice({
3414
3474
  name: "settings",
3415
- initialState: initialState$4,
3416
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3475
+ initialState: initialState$6,
3476
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
3417
3477
  reducers: {
3418
3478
  setEnableDuplicateIssues: (state, action) => {
3419
3479
  state.useIssueTemplate = action.payload;
@@ -3459,146 +3519,231 @@ var __publicField = (obj, key, value) => {
3459
3519
  const settingReducer = settingSlice.reducer;
3460
3520
  const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
3461
3521
  const selectIsLoading = (state) => state.settingReducer.isLoading;
3462
- const LATEST_REVISION_CACHE = {};
3463
- function considerCachingRevision(revision, formId2, preferPending = false) {
3464
- var _a2;
3465
- if (!revision) {
3466
- if (!formId2) {
3467
- throw new Error("If revision is null, formId is required.");
3468
- }
3469
- const currentLatestRevision = getLatestRevisionFromCache(formId2);
3470
- if (currentLatestRevision)
3471
- return;
3472
- LATEST_REVISION_CACHE[formId2] = null;
3473
- return;
3474
- }
3475
- if (revision.revision === "Pending") {
3476
- if (preferPending) {
3477
- LATEST_REVISION_CACHE[revision.form] = revision;
3478
- }
3479
- return;
3480
- }
3481
- const cachedRevision = (_a2 = LATEST_REVISION_CACHE[revision.form]) == null ? void 0 : _a2.revision;
3482
- if (revision.revision > (typeof cachedRevision === "number" ? cachedRevision : -1)) {
3483
- LATEST_REVISION_CACHE[revision.form] = revision;
3522
+ const formRevisionSortFn = (formRevisionA, formRevisionB) => {
3523
+ const revisionA = formRevisionA.revision;
3524
+ const revisionB = formRevisionB.revision;
3525
+ if (revisionA === "Pending" && revisionB === "Pending") {
3526
+ return formRevisionA.submitted_at < formRevisionB.submitted_at ? -1 : 1;
3527
+ } else if (revisionA === "Pending") {
3528
+ return 1;
3529
+ } else if (revisionB === "Pending") {
3530
+ return -1;
3531
+ } else {
3532
+ return revisionA < revisionB ? -1 : 1;
3484
3533
  }
3485
- }
3486
- function getLatestRevisionFromCache(formId2) {
3487
- return LATEST_REVISION_CACHE[formId2];
3488
- }
3489
- const initialState$3 = {
3490
- userForms: {},
3491
- revisions: {},
3492
- submissions: {},
3493
- submissionAttachments: {},
3494
- revisionAttachments: {}
3495
- };
3496
- const userFormSlice = toolkit.createSlice({
3497
- name: "userForms",
3498
- initialState: initialState$3,
3499
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
3534
+ };
3535
+ const initialState$5 = {
3536
+ formRevisions: {},
3537
+ attachments: {}
3538
+ };
3539
+ const formRevisionsSlice = toolkit.createSlice({
3540
+ name: "formRevisions",
3541
+ initialState: initialState$5,
3542
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$5)),
3500
3543
  reducers: {
3501
- setUserForms: (state, action) => {
3502
- state.userForms = {};
3503
- action.payload.forEach((userForm) => {
3504
- state.userForms[userForm.offline_id] = userForm;
3505
- });
3544
+ // revision related actions
3545
+ setFormRevision: (state, action) => {
3546
+ state.formRevisions[action.payload.offline_id] = action.payload;
3506
3547
  },
3507
- addUserForm: (state, action) => {
3508
- state.userForms[action.payload.offline_id] = action.payload;
3509
- },
3510
- addUserForms: (state, action) => {
3511
- action.payload.forEach((userForm) => {
3512
- state.userForms[userForm.offline_id] = userForm;
3513
- });
3514
- },
3515
- addUserFormRevisions: (state, action) => {
3516
- action.payload.forEach((userFormRevision) => {
3517
- state.revisions[userFormRevision.offline_id] = userFormRevision;
3518
- considerCachingRevision(userFormRevision);
3519
- });
3520
- },
3521
- addUserFormRevision: (state, action) => {
3522
- state.revisions[action.payload.offline_id] = action.payload;
3523
- considerCachingRevision(action.payload);
3548
+ setFormRevisions: (state, action) => {
3549
+ state.formRevisions = {};
3550
+ for (const revision of action.payload) {
3551
+ state.formRevisions[revision.offline_id] = revision;
3552
+ }
3524
3553
  },
3525
- deleteUserFormRevision: (state, action) => {
3526
- delete state.revisions[action.payload];
3527
- delete LATEST_REVISION_CACHE[action.payload];
3554
+ addFormRevision: (state, action) => {
3555
+ if (state.formRevisions[action.payload.offline_id] !== void 0) {
3556
+ throw new Error(`Revision with offline_id ${action.payload.offline_id} already exists`);
3557
+ }
3558
+ state.formRevisions[action.payload.offline_id] = action.payload;
3528
3559
  },
3529
- deleteUserFormRevisions: (state, action) => {
3560
+ addFormRevisions: (state, action) => {
3530
3561
  for (const userFormRevision of action.payload) {
3531
- delete state.revisions[userFormRevision.offline_id];
3532
- delete LATEST_REVISION_CACHE[userFormRevision.offline_id];
3562
+ if (state.formRevisions[userFormRevision.offline_id] !== void 0) {
3563
+ throw new Error(`Revision with offline_id ${userFormRevision.offline_id} already exists`);
3564
+ }
3533
3565
  }
3534
- },
3535
- updateOrCreateUserFormSubmission: (state, action) => {
3536
- state.submissions[action.payload.offline_id] = action.payload;
3537
- },
3538
- addUserFormSubmissionAttachment: (state, action) => {
3539
- const submissionId = action.payload.submission;
3540
- const submissionAttachments = state.submissionAttachments[submissionId];
3541
- if (submissionAttachments) {
3542
- submissionAttachments.push(action.payload);
3543
- } else {
3544
- state.submissionAttachments[submissionId] = [action.payload];
3566
+ for (const userFormRevision of action.payload) {
3567
+ state.formRevisions[userFormRevision.offline_id] = userFormRevision;
3545
3568
  }
3546
3569
  },
3547
- addUserFormRevisionAttachment: (state, action) => {
3548
- const revisionId = action.payload.revision;
3549
- const revisionAttachments = state.revisionAttachments[revisionId];
3550
- if (revisionAttachments) {
3551
- revisionAttachments.push(action.payload);
3552
- } else {
3553
- state.revisionAttachments[revisionId] = [action.payload];
3570
+ // UserFormRevisions do not get updated
3571
+ deleteFormRevision: (state, action) => {
3572
+ if (state.formRevisions[action.payload] === void 0) {
3573
+ throw new Error(`Revision with offline_id ${action.payload} does not exist`);
3554
3574
  }
3575
+ delete state.formRevisions[action.payload];
3555
3576
  },
3556
- setUserFormSubmissionAttachments: (state, action) => {
3557
- state.submissionAttachments = {};
3558
- for (const attachment of action.payload) {
3559
- const submissionId = attachment.submission;
3560
- const submissionAttachments = state.submissionAttachments[submissionId];
3561
- if (submissionAttachments) {
3562
- submissionAttachments.push(attachment);
3563
- } else {
3564
- state.submissionAttachments[submissionId] = [attachment];
3577
+ deleteFormRevisions: (state, action) => {
3578
+ for (const offlineId of action.payload) {
3579
+ if (state.formRevisions[offlineId] === void 0) {
3580
+ throw new Error(`Revision with offline_id ${offlineId} does not exist`);
3565
3581
  }
3566
3582
  }
3583
+ for (const offlineId of action.payload) {
3584
+ delete state.formRevisions[offlineId];
3585
+ }
3567
3586
  },
3568
- setUserFormRevisionAttachments: (state, action) => {
3569
- state.revisionAttachments = {};
3587
+ // attachment related actions
3588
+ setFormRevisionAttachments: (state, action) => {
3589
+ state.attachments = {};
3570
3590
  for (const attachment of action.payload) {
3571
- const revisionId = attachment.revision;
3572
- const revisionAttachments = state.revisionAttachments[revisionId];
3573
- if (revisionAttachments) {
3574
- revisionAttachments.push(attachment);
3575
- } else {
3576
- state.revisionAttachments[revisionId] = [attachment];
3577
- }
3591
+ state.attachments[attachment.offline_id] = attachment;
3578
3592
  }
3579
3593
  },
3580
- deleteUserFormSubmission: (state, action) => {
3581
- delete state.submissions[action.payload];
3594
+ addFormRevisionAttachment: (state, action) => {
3595
+ if (state.attachments[action.payload.offline_id] !== void 0) {
3596
+ throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
3597
+ }
3598
+ state.attachments[action.payload.offline_id] = action.payload;
3582
3599
  },
3583
- deleteUserFormSubmissions: (state, action) => {
3584
- for (const userFormSubmission of action.payload) {
3585
- delete state.submissions[userFormSubmission.offline_id];
3600
+ addFormRevisionAttachments: (state, action) => {
3601
+ for (const attachment of action.payload) {
3602
+ if (state.attachments[attachment.offline_id] !== void 0) {
3603
+ throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
3604
+ }
3605
+ }
3606
+ for (const attachment of action.payload) {
3607
+ state.attachments[attachment.offline_id] = attachment;
3586
3608
  }
3587
3609
  },
3588
- addUserFormSubmissions: (state, action) => {
3589
- for (const submission of action.payload) {
3590
- state.submissions[submission.offline_id] = submission;
3610
+ deleteFormRevisionAttachment: (state, action) => {
3611
+ if (state.attachments[action.payload] === void 0) {
3612
+ throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
3591
3613
  }
3614
+ delete state.attachments[action.payload];
3592
3615
  },
3593
- setUserFormSubmissions: (state, action) => {
3594
- state.submissions = {};
3595
- action.payload.forEach((submission) => {
3596
- state.submissions[submission.offline_id] = submission;
3616
+ deleteFormRevisionAttachments: (state, action) => {
3617
+ for (const offlineId of action.payload) {
3618
+ if (state.attachments[offlineId] === void 0) {
3619
+ throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
3620
+ }
3621
+ }
3622
+ for (const offlineId of action.payload) {
3623
+ delete state.attachments[offlineId];
3624
+ }
3625
+ }
3626
+ }
3627
+ });
3628
+ const {
3629
+ setFormRevision,
3630
+ setFormRevisions,
3631
+ addFormRevision,
3632
+ addFormRevisions,
3633
+ deleteFormRevision,
3634
+ deleteFormRevisions,
3635
+ setFormRevisionAttachments,
3636
+ addFormRevisionAttachment,
3637
+ addFormRevisionAttachments,
3638
+ deleteFormRevisionAttachment,
3639
+ deleteFormRevisionAttachments
3640
+ } = formRevisionsSlice.actions;
3641
+ const selectFormRevisionMapping = (state) => state.formRevisionReducer.formRevisions;
3642
+ const selectFormRevisions = toolkit.createSelector(
3643
+ [selectFormRevisionMapping],
3644
+ (formRevisions) => Object.values(formRevisions)
3645
+ );
3646
+ const selectFormRevision = (formRevisionId) => (state) => {
3647
+ return state.formRevisionReducer.formRevisions[formRevisionId];
3648
+ };
3649
+ const _selectLatestFormRevision = (formRevisions, formId2) => {
3650
+ let ret = null;
3651
+ for (const candidate of Object.values(formRevisions)) {
3652
+ if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
3653
+ ret = candidate;
3654
+ }
3655
+ }
3656
+ if (!ret) {
3657
+ throw new Error("No form revision found for form " + formId2);
3658
+ }
3659
+ return ret;
3660
+ };
3661
+ const selectLatestFormRevisionOfForm = restructureCreateSelectorWithArgs(
3662
+ toolkit.createSelector([selectFormRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
3663
+ return revisions.filter((revision) => revision.form === formId2).sort(formRevisionSortFn).pop();
3664
+ })
3665
+ );
3666
+ const selectFormRevisionsOfForm = restructureCreateSelectorWithArgs(
3667
+ toolkit.createSelector([selectFormRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
3668
+ return revisions.filter((revision) => {
3669
+ return revision.form === formId2;
3670
+ });
3671
+ })
3672
+ );
3673
+ const selectLatestFormRevisionsOfComponentTypes = restructureCreateSelectorWithArgs(
3674
+ toolkit.createSelector(
3675
+ [
3676
+ (state) => state.formReducer.forms,
3677
+ selectFormRevisionMapping,
3678
+ (_state, componentTypeIds) => componentTypeIds
3679
+ ],
3680
+ (userForms, revisions, componentTypeIds) => {
3681
+ const componentTypeIdsSet = new Set(componentTypeIds);
3682
+ const formsOfComponentTypes = {};
3683
+ const ret = {};
3684
+ for (const form of Object.values(userForms)) {
3685
+ if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
3686
+ formsOfComponentTypes[form.offline_id] = form;
3687
+ }
3688
+ }
3689
+ for (const revision of Object.values(revisions)) {
3690
+ const form = formsOfComponentTypes[revision.form];
3691
+ if (!form || !form.component_type || ret[form.component_type] && formRevisionSortFn(ret[form.component_type], revision) > 0)
3692
+ continue;
3693
+ ret[form.component_type] = revision;
3694
+ }
3695
+ return ret;
3696
+ }
3697
+ )
3698
+ );
3699
+ const selectLatestFormRevisionByForm = toolkit.createSelector([selectFormRevisionMapping], (revisions) => {
3700
+ const latestRevisions = {};
3701
+ for (const revision of Object.values(revisions)) {
3702
+ const formId2 = revision.form;
3703
+ const currentLatestRevision = latestRevisions[formId2];
3704
+ if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
3705
+ latestRevisions[formId2] = revision;
3706
+ }
3707
+ }
3708
+ return latestRevisions;
3709
+ });
3710
+ const selectUserFormRevisionAttachmentsMapping = (state) => {
3711
+ return state.formRevisionReducer.attachments;
3712
+ };
3713
+ const selectAttachmentsOfFormRevision = restructureCreateSelectorWithArgs(
3714
+ toolkit.createSelector(
3715
+ [selectUserFormRevisionAttachmentsMapping, (_state, revisionId) => revisionId],
3716
+ (attachments, revisionId) => {
3717
+ return Object.values(attachments).filter((attachment) => attachment.revision === revisionId);
3718
+ }
3719
+ )
3720
+ );
3721
+ const formRevisionReducer = formRevisionsSlice.reducer;
3722
+ const initialState$4 = {
3723
+ forms: {}
3724
+ };
3725
+ const formSlice = toolkit.createSlice({
3726
+ name: "forms",
3727
+ initialState: initialState$4,
3728
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3729
+ reducers: {
3730
+ setForms: (state, action) => {
3731
+ state.forms = {};
3732
+ action.payload.forEach((userForm) => {
3733
+ state.forms[userForm.offline_id] = userForm;
3597
3734
  });
3598
3735
  },
3736
+ addForm: (state, action) => {
3737
+ state.forms[action.payload.offline_id] = action.payload;
3738
+ },
3739
+ addForms: (state, action) => {
3740
+ for (const userForm of action.payload) {
3741
+ state.forms[userForm.offline_id] = userForm;
3742
+ }
3743
+ },
3599
3744
  favoriteForm: (state, action) => {
3600
3745
  const { formId: formId2 } = action.payload;
3601
- const form = state.userForms[formId2];
3746
+ const form = state.forms[formId2];
3602
3747
  if (!form) {
3603
3748
  throw new Error("No form exists with the id " + formId2);
3604
3749
  }
@@ -3606,48 +3751,23 @@ var __publicField = (obj, key, value) => {
3606
3751
  },
3607
3752
  unfavoriteForm: (state, action) => {
3608
3753
  const { formId: formId2 } = action.payload;
3609
- const form = state.userForms[formId2];
3754
+ const form = state.forms[formId2];
3610
3755
  if (!form) {
3611
3756
  throw new Error("No form exists with the id " + formId2);
3612
3757
  }
3613
3758
  form.favorite = false;
3614
3759
  },
3615
- deleteUserForm: (state, action) => {
3616
- delete state.userForms[action.payload];
3760
+ deleteForm: (state, action) => {
3761
+ delete state.forms[action.payload];
3617
3762
  }
3618
3763
  }
3619
3764
  });
3620
- const {
3621
- addUserForm,
3622
- addUserForms,
3623
- addUserFormRevisions,
3624
- updateOrCreateUserFormSubmission,
3625
- addUserFormSubmissions,
3626
- deleteUserFormSubmission,
3627
- deleteUserFormSubmissions,
3628
- favoriteForm,
3629
- unfavoriteForm,
3630
- deleteUserForm,
3631
- deleteUserFormRevision,
3632
- deleteUserFormRevisions,
3633
- setUserFormSubmissions,
3634
- addUserFormRevision,
3635
- addUserFormSubmissionAttachment,
3636
- addUserFormRevisionAttachment,
3637
- setUserFormSubmissionAttachments,
3638
- setUserFormRevisionAttachments
3639
- } = userFormSlice.actions;
3640
- const selectSubmissionAttachments = (submissionId) => (state) => {
3641
- return state.userFormReducer.submissionAttachments[submissionId] || [];
3642
- };
3643
- const selectRevisionAttachments = (revisionId) => (state) => {
3644
- return state.userFormReducer.revisionAttachments[revisionId] || [];
3645
- };
3646
- const selectFilteredUserForms = restructureCreateSelectorWithArgs(
3765
+ const { setForms, addForm, addForms, favoriteForm, unfavoriteForm, deleteForm } = formSlice.actions;
3766
+ const selectFilteredForms = restructureCreateSelectorWithArgs(
3647
3767
  toolkit.createSelector(
3648
3768
  [
3649
- (state) => state.userFormReducer.userForms,
3650
- (state) => state.userFormReducer.revisions,
3769
+ (state) => state.formReducer.forms,
3770
+ (state) => state.formRevisionReducer.formRevisions,
3651
3771
  (_state, search) => search
3652
3772
  ],
3653
3773
  (userForms, revisions, search) => {
@@ -3674,70 +3794,195 @@ var __publicField = (obj, key, value) => {
3674
3794
  break;
3675
3795
  }
3676
3796
  }
3677
- const maxRegularMatches = maxResults - favoriteMatches.length;
3678
- return [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)];
3797
+ const maxRegularMatches = maxResults - favoriteMatches.length;
3798
+ return [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)];
3799
+ },
3800
+ // as the argument is an object, we check the first level of properties for equality
3801
+ { memoizeOptions: { equalityCheck: reactRedux.shallowEqual } }
3802
+ )
3803
+ );
3804
+ const selectForm = (formId2) => (state) => {
3805
+ return state.formReducer.forms[formId2];
3806
+ };
3807
+ const selectFormMapping = (state) => {
3808
+ return state.formReducer.forms;
3809
+ };
3810
+ const selectFormOfComponentType = restructureCreateSelectorWithArgs(
3811
+ toolkit.createSelector(
3812
+ [selectFormMapping, (_state, componentTypeId) => componentTypeId],
3813
+ (userForms, componentTypeId) => {
3814
+ return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
3815
+ }
3816
+ )
3817
+ );
3818
+ const selectFormsCount = toolkit.createSelector([selectFormMapping], (userForms) => {
3819
+ return Object.keys(userForms).length;
3820
+ });
3821
+ const selectGeneralFormCount = toolkit.createSelector([selectFormMapping], (userForms) => {
3822
+ return Object.values(userForms).filter((form) => !form.component_type).length;
3823
+ });
3824
+ const formReducer = formSlice.reducer;
3825
+ const initialState$3 = {
3826
+ formSubmissions: {},
3827
+ attachments: {}
3828
+ };
3829
+ const formSubmissionSlice = toolkit.createSlice({
3830
+ name: "formSubmissions",
3831
+ initialState: initialState$3,
3832
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
3833
+ reducers: {
3834
+ setFormSubmission: (state, action) => {
3835
+ state.formSubmissions[action.payload.offline_id] = action.payload;
3836
+ },
3837
+ setFormSubmissions: (state, action) => {
3838
+ state.formSubmissions = {};
3839
+ for (const submission of action.payload) {
3840
+ state.formSubmissions[submission.offline_id] = submission;
3841
+ }
3842
+ },
3843
+ addFormSubmission: (state, action) => {
3844
+ if (action.payload.offline_id in state.formSubmissions) {
3845
+ throw new Error(`Submission with offline_id ${action.payload.offline_id} already exists`);
3846
+ }
3847
+ state.formSubmissions[action.payload.offline_id] = action.payload;
3848
+ },
3849
+ addFormSubmissions: (state, action) => {
3850
+ for (const submission of action.payload) {
3851
+ if (state.formSubmissions[submission.offline_id] !== void 0) {
3852
+ throw new Error(`Submission with offline_id ${submission.offline_id} already exists`);
3853
+ }
3854
+ }
3855
+ for (const submission of action.payload) {
3856
+ state.formSubmissions[submission.offline_id] = submission;
3857
+ }
3858
+ },
3859
+ updateFormSubmission: (state, action) => {
3860
+ if (state.formSubmissions[action.payload.offline_id] === void 0) {
3861
+ throw new Error(`Submission with offline_id ${action.payload.offline_id} does not exist`);
3862
+ }
3863
+ state.formSubmissions[action.payload.offline_id] = action.payload;
3864
+ },
3865
+ updateFormSubmissions: (state, action) => {
3866
+ for (const submission of action.payload) {
3867
+ if (state.formSubmissions[submission.offline_id] === void 0) {
3868
+ throw new Error(`Submission with offline_id ${submission.offline_id} does not exist`);
3869
+ }
3870
+ }
3871
+ for (const submission of action.payload) {
3872
+ state.formSubmissions[submission.offline_id] = submission;
3873
+ }
3874
+ },
3875
+ deleteFormSubmission: (state, action) => {
3876
+ if (state.formSubmissions[action.payload] === void 0) {
3877
+ throw new Error(`Submission with offline_id ${action.payload} does not exist`);
3878
+ }
3879
+ delete state.formSubmissions[action.payload];
3880
+ },
3881
+ deleteFormSubmissions: (state, action) => {
3882
+ for (const offlineId of action.payload) {
3883
+ if (state.formSubmissions[offlineId] === void 0) {
3884
+ throw new Error(`Submission with offline_id ${offlineId} does not exist`);
3885
+ }
3886
+ delete state.formSubmissions[offlineId];
3887
+ }
3888
+ for (const offlineId of action.payload) {
3889
+ delete state.formSubmissions[offlineId];
3890
+ }
3891
+ },
3892
+ // Attachments
3893
+ addFormSubmissionAttachment: (state, action) => {
3894
+ if (state.attachments[action.payload.offline_id] !== void 0) {
3895
+ throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
3896
+ }
3897
+ state.attachments[action.payload.offline_id] = action.payload;
3898
+ },
3899
+ addFormSubmissionAttachments: (state, action) => {
3900
+ for (const attachment of action.payload) {
3901
+ if (state.attachments[attachment.offline_id] !== void 0) {
3902
+ throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
3903
+ }
3904
+ }
3905
+ for (const attachment of action.payload) {
3906
+ state.attachments[attachment.offline_id] = attachment;
3907
+ }
3908
+ },
3909
+ // We only need a multi set for attachments because they are not updated, only added and deleted
3910
+ setFormSubmissionAttachments: (state, action) => {
3911
+ state.attachments = {};
3912
+ for (const attachment of action.payload) {
3913
+ state.attachments[attachment.offline_id] = attachment;
3914
+ }
3915
+ },
3916
+ updateFormSubmissionAttachments: (state, action) => {
3917
+ for (const attachment of action.payload) {
3918
+ if (state.attachments[attachment.offline_id] === void 0) {
3919
+ throw new Error(`Attachment with offline_id ${attachment.offline_id} does not exist`);
3920
+ }
3921
+ }
3922
+ for (const attachment of action.payload) {
3923
+ state.attachments[attachment.offline_id] = attachment;
3924
+ }
3679
3925
  },
3680
- // as the argument is an object, we check the first level of properties for equality
3681
- { memoizeOptions: { equalityCheck: reactRedux.shallowEqual } }
3682
- )
3683
- );
3684
- const selectFormRevision = (revisionId) => (state) => {
3685
- return state.userFormReducer.revisions[revisionId];
3686
- };
3687
- const _selectLatestFormRevision = (revisions, formId2) => {
3688
- let ret = null;
3689
- for (const candidate of Object.values(revisions)) {
3690
- if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
3691
- ret = candidate;
3926
+ // The delete actions for UserFormSubmissionAttachments are not used in the app, but are included for completeness
3927
+ // Could be used if editing a submission is ever supported, will be applicable for supporting tip tap content in submissions
3928
+ deleteFormSubmissionAttachment: (state, action) => {
3929
+ if (state.attachments[action.payload] === void 0) {
3930
+ throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
3931
+ }
3932
+ delete state.attachments[action.payload];
3933
+ },
3934
+ deleteFormSubmissionAttachments: (state, action) => {
3935
+ for (const offlineId of action.payload) {
3936
+ if (state.attachments[offlineId] === void 0) {
3937
+ throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
3938
+ }
3939
+ delete state.attachments[offlineId];
3940
+ }
3692
3941
  }
3693
3942
  }
3694
- if (!ret) {
3695
- throw new Error("No revision found for form " + formId2);
3696
- }
3697
- return ret;
3943
+ });
3944
+ const {
3945
+ setFormSubmission,
3946
+ setFormSubmissions,
3947
+ addFormSubmission,
3948
+ addFormSubmissions,
3949
+ updateFormSubmission,
3950
+ updateFormSubmissions,
3951
+ deleteFormSubmission,
3952
+ deleteFormSubmissions,
3953
+ addFormSubmissionAttachment,
3954
+ addFormSubmissionAttachments,
3955
+ setFormSubmissionAttachments,
3956
+ updateFormSubmissionAttachments,
3957
+ deleteFormSubmissionAttachment,
3958
+ deleteFormSubmissionAttachments
3959
+ } = formSubmissionSlice.actions;
3960
+ const selectFormSubmissionsMapping = (state) => {
3961
+ return state.formSubmissionReducer.formSubmissions;
3698
3962
  };
3699
- const selectLatestFormRevision = restructureCreateSelectorWithArgs(
3700
- toolkit.createSelector(
3701
- [(state) => state.userFormReducer.revisions, (_state, formId2) => formId2],
3702
- (revisions, formId2) => {
3703
- if (!formId2) {
3704
- throw new Error("formId is required");
3705
- }
3706
- return _selectLatestFormRevision(revisions, formId2);
3707
- }
3708
- )
3709
- );
3710
- const selectUserForm = (formId2) => (state) => {
3711
- return state.userFormReducer.userForms[formId2];
3712
- };
3713
- const selectSubmissionMapping = (state) => state.userFormReducer.submissions;
3714
- const selectUserFormSubmission = (submissionId) => (state) => {
3715
- return state.userFormReducer.submissions[submissionId];
3716
- };
3717
- const selectSubmissions = toolkit.createSelector([selectSubmissionMapping], (submissions) => Object.values(submissions));
3718
- const selectRevisionMapping = (state) => state.userFormReducer.revisions;
3719
- const selectRevisions = toolkit.createSelector([selectRevisionMapping], (revisions) => Object.values(revisions));
3720
- const selectRevisionsForForm = restructureCreateSelectorWithArgs(
3721
- toolkit.createSelector([selectRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
3722
- return revisions.filter((revision) => {
3723
- return revision.form === formId2;
3724
- });
3725
- })
3963
+ const selectFormSubmissions = toolkit.createSelector(
3964
+ [selectFormSubmissionsMapping],
3965
+ (submissions) => {
3966
+ return Object.values(submissions);
3967
+ }
3726
3968
  );
3727
- const selectSubmissionsForForm = restructureCreateSelectorWithArgs(
3969
+ const selectFormSubmission = (submissionId) => (state) => {
3970
+ return state.formSubmissionReducer.formSubmissions[submissionId];
3971
+ };
3972
+ const selectFormSubmissionsOfForm = restructureCreateSelectorWithArgs(
3728
3973
  toolkit.createSelector(
3729
- [selectSubmissions, selectRevisionMapping, (_state, formId2) => formId2],
3974
+ [selectFormSubmissions, selectFormRevisionMapping, (_state, formId2) => formId2],
3730
3975
  (submissions, revisionMapping, formId2) => {
3731
- return Object.values(submissions).filter((submission) => {
3976
+ return submissions.filter((submission) => {
3732
3977
  const revision = revisionMapping[submission.form_revision];
3733
3978
  return (revision == null ? void 0 : revision.form) === formId2;
3734
3979
  });
3735
3980
  }
3736
3981
  )
3737
3982
  );
3738
- const selectSubmissionsForIssue = restructureCreateSelectorWithArgs(
3983
+ const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(
3739
3984
  toolkit.createSelector(
3740
- [(state) => state.userFormReducer.submissions, (_state, issueId) => issueId],
3985
+ [selectFormSubmissions, (_state, issueId) => issueId],
3741
3986
  (submissions, issueId) => {
3742
3987
  return Object.values(submissions).filter((submission) => {
3743
3988
  return submission.issue === issueId;
@@ -3745,9 +3990,9 @@ var __publicField = (obj, key, value) => {
3745
3990
  }
3746
3991
  )
3747
3992
  );
3748
- const selectSubmissionsForComponent = restructureCreateSelectorWithArgs(
3993
+ const selectFormSubmissionsOfComponent = restructureCreateSelectorWithArgs(
3749
3994
  toolkit.createSelector(
3750
- [selectSubmissions, (_state, componentId) => componentId],
3995
+ [selectFormSubmissions, (_state, componentId) => componentId],
3751
3996
  (submissions, componentId) => {
3752
3997
  return submissions.filter((submission) => {
3753
3998
  return submission.component === componentId;
@@ -3755,8 +4000,8 @@ var __publicField = (obj, key, value) => {
3755
4000
  }
3756
4001
  )
3757
4002
  );
3758
- const selectComponentSubmissionMapping = toolkit.createSelector(
3759
- [selectSubmissionMapping, selectComponentsMapping],
4003
+ const selectFormSubmissionsByComponents = toolkit.createSelector(
4004
+ [selectFormSubmissionsMapping, selectComponentsMapping],
3760
4005
  (submissions, components) => {
3761
4006
  var _a2;
3762
4007
  const componentSubmissionMapping = {};
@@ -3772,54 +4017,18 @@ var __publicField = (obj, key, value) => {
3772
4017
  return componentSubmissionMapping;
3773
4018
  }
3774
4019
  );
3775
- const selectUserFormMapping = (state) => {
3776
- return state.userFormReducer.userForms;
4020
+ const selectFormSubmissionAttachmentsMapping = (state) => {
4021
+ return state.formSubmissionReducer.attachments;
3777
4022
  };
3778
- const selectComponentTypeForm = restructureCreateSelectorWithArgs(
3779
- toolkit.createSelector(
3780
- [selectUserFormMapping, (_state, componentTypeId) => componentTypeId],
3781
- (userForms, componentTypeId) => {
3782
- return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
3783
- }
3784
- )
3785
- );
3786
- const selectLatestRevisionsFromComponentTypeIds = restructureCreateSelectorWithArgs(
4023
+ const selectAttachmentsOfFormSubmission = restructureCreateSelectorWithArgs(
3787
4024
  toolkit.createSelector(
3788
- [
3789
- selectUserFormMapping,
3790
- selectRevisionMapping,
3791
- (_state, componentTypeIds) => componentTypeIds
3792
- ],
3793
- (userForms, revisions, componentTypeIds) => {
3794
- const componentTypeIdsSet = new Set(componentTypeIds);
3795
- const ret = {};
3796
- for (const form of Object.values(userForms)) {
3797
- if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
3798
- ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
3799
- }
3800
- }
3801
- return ret;
4025
+ [selectFormSubmissionAttachmentsMapping, (_state, submissionId) => submissionId],
4026
+ (attachmentsMapping, submissionId) => {
4027
+ return Object.values(attachmentsMapping).filter((attachment) => attachment.submission === submissionId);
3802
4028
  }
3803
4029
  )
3804
4030
  );
3805
- const selectLatestRevisionByFormId = toolkit.createSelector([selectRevisionMapping], (revisions) => {
3806
- const latestRevisions = {};
3807
- for (const revision of Object.values(revisions)) {
3808
- const formId2 = revision.form;
3809
- const currentLatestRevision = latestRevisions[formId2];
3810
- if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
3811
- latestRevisions[formId2] = revision;
3812
- }
3813
- }
3814
- return latestRevisions;
3815
- });
3816
- const selectNumberOfUserForms = toolkit.createSelector([selectUserFormMapping], (userForms) => {
3817
- return Object.keys(userForms).length;
3818
- });
3819
- const selectNumberOfGeneralUserForms = toolkit.createSelector([selectUserFormMapping], (userForms) => {
3820
- return Object.values(userForms).filter((form) => !form.component_type).length;
3821
- });
3822
- const userFormReducer = userFormSlice.reducer;
4031
+ const formSubmissionReducer = formSubmissionSlice.reducer;
3823
4032
  const initialState$2 = {
3824
4033
  emailDomains: {}
3825
4034
  };
@@ -3992,10 +4201,13 @@ var __publicField = (obj, key, value) => {
3992
4201
  delete state.documents[documentId];
3993
4202
  }
3994
4203
  },
4204
+ // Attachments
4205
+ setDocumentAttachment: setAttachment,
3995
4206
  setDocumentAttachments: setAttachments,
3996
4207
  addDocumentAttachment: addAttachment,
3997
4208
  addDocumentAttachments: addAttachments,
3998
4209
  updateDocumentAttachment: updateAttachment,
4210
+ updateDocumentAttachments: updateAttachments,
3999
4211
  removeDocumentAttachment: removeAttachment,
4000
4212
  removeDocumentAttachments: removeAttachments
4001
4213
  }
@@ -4006,10 +4218,13 @@ var __publicField = (obj, key, value) => {
4006
4218
  updateDocuments,
4007
4219
  moveDocument,
4008
4220
  removeDocuments,
4221
+ // Attachments
4222
+ setDocumentAttachment,
4009
4223
  setDocumentAttachments,
4010
4224
  addDocumentAttachment,
4011
4225
  addDocumentAttachments,
4012
4226
  updateDocumentAttachment,
4227
+ updateDocumentAttachments,
4013
4228
  removeDocumentAttachment,
4014
4229
  removeDocumentAttachments
4015
4230
  } = documentSlice.actions;
@@ -4117,7 +4332,9 @@ var __publicField = (obj, key, value) => {
4117
4332
  projectFileReducer,
4118
4333
  rehydratedReducer,
4119
4334
  settingReducer,
4120
- userFormReducer,
4335
+ formReducer,
4336
+ formRevisionReducer,
4337
+ formSubmissionReducer,
4121
4338
  userReducer,
4122
4339
  workspaceReducer,
4123
4340
  emailDomainsReducer,
@@ -4170,9 +4387,7 @@ var __publicField = (obj, key, value) => {
4170
4387
  throw new Error(`Failed to update index_workspace of issue ${issue.offline_id} to main workspace`);
4171
4388
  }
4172
4389
  }
4173
- const indexedForms = Object.values(draft.userFormReducer.userForms).filter(
4174
- (form) => form.index_workspace === workspaceId
4175
- );
4390
+ const indexedForms = Object.values(draft.formReducer.forms).filter((form) => form.index_workspace === workspaceId);
4176
4391
  for (const form of indexedForms) {
4177
4392
  form.index_workspace = mainWorkspace.offline_id;
4178
4393
  }
@@ -5879,6 +6094,221 @@ var __publicField = (obj, key, value) => {
5879
6094
  store.dispatch(addStages(result));
5880
6095
  }
5881
6096
  }
6097
+ const AttachmentModelMeta = {
6098
+ [AttachmentModel.Issue]: {
6099
+ name: "issue",
6100
+ attachUrlPrefix: "/issues",
6101
+ deleteUrlPrefix: "/issues",
6102
+ fetchUrlPostfix: "/issue-attachments"
6103
+ },
6104
+ [AttachmentModel.Component]: {
6105
+ name: "component",
6106
+ attachUrlPrefix: "/components",
6107
+ deleteUrlPrefix: "/components",
6108
+ fetchUrlPostfix: "/component-attachments"
6109
+ },
6110
+ [AttachmentModel.ComponentType]: {
6111
+ name: "component type",
6112
+ attachUrlPrefix: "/components/types",
6113
+ deleteUrlPrefix: "/components/types",
6114
+ fetchUrlPostfix: "/component-type-attachments"
6115
+ },
6116
+ [AttachmentModel.Project]: {
6117
+ name: "component project",
6118
+ attachUrlPrefix: "/projects",
6119
+ deleteUrlPrefix: "/projects",
6120
+ fetchUrlPostfix: "/attachments"
6121
+ },
6122
+ [AttachmentModel.Document]: {
6123
+ name: "document",
6124
+ attachUrlPrefix: "/documents",
6125
+ deleteUrlPrefix: "/documents",
6126
+ fetchUrlPostfix: "/document-attachments"
6127
+ }
6128
+ };
6129
+ class BaseAttachmentService extends BaseApiService {
6130
+ getNumberOfAttachmentsWithSha1(sha1) {
6131
+ const {
6132
+ issueReducer: issueReducer2,
6133
+ componentReducer: componentReducer2,
6134
+ componentTypeReducer: componentTypeReducer2,
6135
+ documentsReducer: documentsReducer2,
6136
+ projectReducer: projectReducer2,
6137
+ formSubmissionReducer: formSubmissionReducer2,
6138
+ formRevisionReducer: formRevisionReducer2
6139
+ } = this.client.store.getState();
6140
+ const objectsWithSha1 = [].concat(
6141
+ Object.values(issueReducer2.attachments),
6142
+ Object.values(componentReducer2.attachments),
6143
+ Object.values(componentTypeReducer2.attachments),
6144
+ Object.values(documentsReducer2.attachments),
6145
+ Object.values(projectReducer2.attachments),
6146
+ Object.values(formRevisionReducer2.attachments),
6147
+ Object.values(formSubmissionReducer2.attachments)
6148
+ );
6149
+ return objectsWithSha1.filter((object) => object.file_sha1 === sha1).length;
6150
+ }
6151
+ processPresignedUrls(presignedUrls) {
6152
+ for (const [sha1, presignedUrl] of Object.entries(presignedUrls)) {
6153
+ void this.enqueueRequest({
6154
+ url: presignedUrl.url,
6155
+ description: "Upload file to S3",
6156
+ method: HttpMethod.POST,
6157
+ isExternalUrl: true,
6158
+ isAuthNeeded: false,
6159
+ attachmentHash: sha1,
6160
+ // TODO: can we use the sha1 as the blocker?
6161
+ blockers: [`s3-${presignedUrl.fields.key}`],
6162
+ blocks: [sha1],
6163
+ s3url: presignedUrl
6164
+ });
6165
+ }
6166
+ }
6167
+ // Note that currently the fetching of attachments for all models dependds on the active projectId. This may change in the future. And
6168
+ // so for some attachment model services, this method will have to be overridden.
6169
+ async getAttachments(actions) {
6170
+ const { store } = this.client;
6171
+ const activeProjectId = store.getState().projectReducer.activeProjectId;
6172
+ const meta = AttachmentModelMeta[this.attachmentModel];
6173
+ const result = await this.enqueueRequest({
6174
+ description: `Get ${meta.name} attachments`,
6175
+ method: HttpMethod.GET,
6176
+ url: `/projects/${activeProjectId}${meta.fetchUrlPostfix}/`,
6177
+ blocks: [],
6178
+ blockers: []
6179
+ });
6180
+ store.dispatch(actions.setAttachments(result));
6181
+ }
6182
+ async attachFiles(files, modelId, buildOfflineAttachment, actions) {
6183
+ const { store } = this.client;
6184
+ const currentUser = store.getState().userReducer.currentUser;
6185
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
6186
+ const offlineAttachments = [];
6187
+ const attachmentPayloads = [];
6188
+ const filePayloads = {};
6189
+ for (const file of files) {
6190
+ const sha1 = await hashFile(file);
6191
+ if (!(sha1 in filePayloads)) {
6192
+ filePayloads[sha1] = {
6193
+ sha1,
6194
+ file_type: file.type,
6195
+ extension: file.name.split(".").pop(),
6196
+ size: file.size
6197
+ };
6198
+ await this.client.files.addCache(file, sha1);
6199
+ }
6200
+ const offlineAttachment = buildOfflineAttachment({
6201
+ file,
6202
+ sha1,
6203
+ submittedAt,
6204
+ createdBy: currentUser.id,
6205
+ description: "",
6206
+ modelId
6207
+ });
6208
+ offlineAttachments.push(offlineAttachment);
6209
+ attachmentPayloads.push({
6210
+ offline_id: offlineAttachment.offline_id,
6211
+ name: offlineAttachment.file_name,
6212
+ sha1: offlineAttachment.file_sha1,
6213
+ description: offlineAttachment.description
6214
+ });
6215
+ }
6216
+ store.dispatch(actions.addAttachments(offlineAttachments));
6217
+ const meta = AttachmentModelMeta[this.attachmentModel];
6218
+ const promise = this.enqueueRequest({
6219
+ description: `Attach files to ${meta.name}`,
6220
+ method: HttpMethod.POST,
6221
+ url: `${meta.attachUrlPrefix}/${modelId}/attach/`,
6222
+ payload: {
6223
+ submitted_at: submittedAt,
6224
+ attachments: attachmentPayloads,
6225
+ files: Object.values(filePayloads)
6226
+ },
6227
+ blocks: offlineAttachments.map((attachment) => attachment.offline_id),
6228
+ blockers: offlineAttachments.map((attachment) => attachment.file_sha1)
6229
+ });
6230
+ promise.then(({ attachments, presigned_urls }) => {
6231
+ store.dispatch(actions.updateAttachments(attachments));
6232
+ this.processPresignedUrls(presigned_urls);
6233
+ }).catch(() => {
6234
+ store.dispatch(actions.removeAttachments(offlineAttachments.map((attachment) => attachment.offline_id)));
6235
+ });
6236
+ return [offlineAttachments, promise.then(({ attachments }) => attachments)];
6237
+ }
6238
+ async deleteAttachment(attachmendId, actions, selectors) {
6239
+ const { store } = this.client;
6240
+ const attachment = selectors.selectAttachment(attachmendId)(store.getState());
6241
+ if (!attachment) {
6242
+ throw new Error(
6243
+ `Attempting to delete attachment with offline_id ${attachmendId} that does not exist in the store`
6244
+ );
6245
+ }
6246
+ store.dispatch(actions.removeAttachment(attachment.offline_id));
6247
+ const meta = AttachmentModelMeta[this.attachmentModel];
6248
+ const promise = this.enqueueRequest({
6249
+ description: "Delete attachment",
6250
+ method: HttpMethod.DELETE,
6251
+ url: `${meta.deleteUrlPrefix}/attachments/${attachmendId}/`,
6252
+ blockers: [attachmendId],
6253
+ blocks: []
6254
+ });
6255
+ promise.then(() => {
6256
+ if (this.getNumberOfAttachmentsWithSha1(attachment.file_sha1) === 0) {
6257
+ void this.client.files.removeCache(attachment.file_sha1);
6258
+ }
6259
+ }).catch(() => {
6260
+ store.dispatch(actions.setAttachment(attachment));
6261
+ });
6262
+ return promise;
6263
+ }
6264
+ }
6265
+ class ComponentAttachmentService extends BaseAttachmentService {
6266
+ constructor() {
6267
+ super(...arguments);
6268
+ __publicField(this, "attachmentModel", AttachmentModel.Component);
6269
+ }
6270
+ buildOfflineAttachment(data) {
6271
+ return offline({
6272
+ file: URL.createObjectURL(data.file),
6273
+ file_sha1: data.sha1,
6274
+ created_by: data.createdBy,
6275
+ file_name: data.file.name,
6276
+ file_type: data.file.type,
6277
+ submitted_at: data.submittedAt,
6278
+ description: data.description,
6279
+ component: data.modelId
6280
+ });
6281
+ }
6282
+ async attachFilesToComponent(files, componentId) {
6283
+ return this.attachFiles(
6284
+ files,
6285
+ componentId,
6286
+ this.buildOfflineAttachment.bind(this),
6287
+ {
6288
+ addAttachments: addComponentAttachments,
6289
+ updateAttachments: updateComponentAttachments,
6290
+ removeAttachments: removeComponentAttachments
6291
+ }
6292
+ );
6293
+ }
6294
+ deleteComponentAttachment(attachmentId) {
6295
+ return this.deleteAttachment(
6296
+ attachmentId,
6297
+ {
6298
+ setAttachment: setComponentAttachment,
6299
+ removeAttachment: removeComponentAttachment
6300
+ },
6301
+ {
6302
+ selectAttachment: selectComponentAttachment
6303
+ }
6304
+ );
6305
+ }
6306
+ async refreshStore() {
6307
+ return this.getAttachments({
6308
+ setAttachments: setComponentAttachments
6309
+ });
6310
+ }
6311
+ }
5882
6312
  class ComponentTypeService extends BaseApiService {
5883
6313
  add(componentType) {
5884
6314
  const offlineComponentType = offline(componentType);
@@ -5951,6 +6381,53 @@ var __publicField = (obj, key, value) => {
5951
6381
  store.dispatch(setComponentTypes(result));
5952
6382
  }
5953
6383
  }
6384
+ class ComponentTypeAttachmentService extends BaseAttachmentService {
6385
+ constructor() {
6386
+ super(...arguments);
6387
+ __publicField(this, "attachmentModel", AttachmentModel.ComponentType);
6388
+ }
6389
+ buildOfflineAttachment(data) {
6390
+ return offline({
6391
+ file: URL.createObjectURL(data.file),
6392
+ file_sha1: data.sha1,
6393
+ created_by: data.createdBy,
6394
+ file_name: data.file.name,
6395
+ file_type: data.file.type,
6396
+ submitted_at: data.submittedAt,
6397
+ description: data.description,
6398
+ component_type: data.modelId
6399
+ });
6400
+ }
6401
+ async attachFilesToComponentType(files, componentTypeId) {
6402
+ return this.attachFiles(
6403
+ files,
6404
+ componentTypeId,
6405
+ this.buildOfflineAttachment.bind(this),
6406
+ {
6407
+ addAttachments: addComponentTypeAttachments,
6408
+ updateAttachments: updateComponentTypeAttachments,
6409
+ removeAttachments: removeComponentTypeAttachments
6410
+ }
6411
+ );
6412
+ }
6413
+ deleteComponentTypeAttachment(attachmentId) {
6414
+ return this.deleteAttachment(
6415
+ attachmentId,
6416
+ {
6417
+ setAttachment: setComponentTypeAttachment,
6418
+ removeAttachment: removeComponentTypeAttachment
6419
+ },
6420
+ {
6421
+ selectAttachment: selectComponentTypeAttachment
6422
+ }
6423
+ );
6424
+ }
6425
+ async refreshStore() {
6426
+ return this.getAttachments({
6427
+ setAttachments: setComponentTypeAttachments
6428
+ });
6429
+ }
6430
+ }
5954
6431
  class IssueCommentService extends BaseApiService {
5955
6432
  // Omit author and submitted_at since these will always be set internally
5956
6433
  add(comment) {
@@ -6047,6 +6524,48 @@ var __publicField = (obj, key, value) => {
6047
6524
  store.dispatch(setIssueUpdates(filteredResult));
6048
6525
  }
6049
6526
  }
6527
+ class IssueAttachmentService extends BaseAttachmentService {
6528
+ constructor() {
6529
+ super(...arguments);
6530
+ __publicField(this, "attachmentModel", AttachmentModel.Issue);
6531
+ }
6532
+ buildOfflineAttachment(data) {
6533
+ return offline({
6534
+ file: URL.createObjectURL(data.file),
6535
+ file_sha1: data.sha1,
6536
+ created_by: data.createdBy,
6537
+ file_name: data.file.name,
6538
+ file_type: data.file.type,
6539
+ submitted_at: data.submittedAt,
6540
+ description: data.description,
6541
+ issue: data.modelId
6542
+ });
6543
+ }
6544
+ async attachFilesToIssue(files, issueId) {
6545
+ return this.attachFiles(files, issueId, this.buildOfflineAttachment.bind(this), {
6546
+ addAttachments: addIssueAttachments,
6547
+ updateAttachments: updateIssueAttachments,
6548
+ removeAttachments: removeIssueAttachments
6549
+ });
6550
+ }
6551
+ deleteIssueAttachment(attachmentId) {
6552
+ return this.deleteAttachment(
6553
+ attachmentId,
6554
+ {
6555
+ setAttachment: setIssueAttachment,
6556
+ removeAttachment: removeIssueAttachment
6557
+ },
6558
+ {
6559
+ selectAttachment: selectIssueAttachment
6560
+ }
6561
+ );
6562
+ }
6563
+ async refreshStore() {
6564
+ return this.getAttachments({
6565
+ setAttachments: setIssueAttachments
6566
+ });
6567
+ }
6568
+ }
6050
6569
  class IssueService extends BaseApiService {
6051
6570
  // Basic CRUD functions
6052
6571
  // TODO: Once all models are represented in `Created<TModel>`, use `Created` in `OptimisticModelResult`, so we don't
@@ -6392,6 +6911,7 @@ var __publicField = (obj, key, value) => {
6392
6911
  const usersResult = await usersResultPromise;
6393
6912
  await projectAccessRefreshPromise;
6394
6913
  store.dispatch(addUsers(usersResult));
6914
+ void this.client.projectAttachments.refreshStore();
6395
6915
  }
6396
6916
  let currentWorkspaceId;
6397
6917
  const oldWorkspaceId = this.client.store.getState().workspaceReducer.activeWorkspaceId;
@@ -6404,38 +6924,30 @@ var __publicField = (obj, key, value) => {
6404
6924
  store.dispatch(setActiveWorkspaceId(currentWorkspaceId));
6405
6925
  void this.client.categories.refreshStore().then(() => {
6406
6926
  void this.client.issues.refreshStore().then(() => {
6927
+ void this.client.issueAttachments.refreshStore().then();
6407
6928
  void this.client.issueComments.refreshStore().then();
6929
+ void this.client.issueUpdates.refreshStore().then();
6408
6930
  });
6409
6931
  });
6410
6932
  void this.client.projectFiles.refreshStore().then();
6411
6933
  void this.client.componentTypes.refreshStore().then(() => {
6412
- void this.client.componentStages.refreshStore().then(() => {
6413
- void this.client.components.refreshStore(overwrite).then();
6934
+ void this.client.componentTypeAttachments.refreshStore().then(() => {
6935
+ void this.client.componentStages.refreshStore().then(() => {
6936
+ void this.client.components.refreshStore(overwrite).then(() => {
6937
+ void this.client.componentAttachments.refreshStore().then();
6938
+ });
6939
+ });
6940
+ void this.client.componentStageCompletions.refreshStore().then();
6414
6941
  });
6415
- void this.client.componentStageCompletions.refreshStore().then();
6416
6942
  });
6417
6943
  void this.client.userForms.refreshStore().then(() => {
6418
6944
  void this.client.userFormSubmissions.refreshStore().then();
6419
6945
  });
6420
6946
  }
6421
6947
  if (currentProjectId) {
6422
- const [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId);
6423
- void promise.then((result) => {
6424
- const {
6425
- issue_attachments,
6426
- component_type_attachments,
6427
- component_attachments,
6428
- project_attachments,
6429
- document_attachments
6430
- } = result;
6431
- store.dispatch(setIssueAttachments(issue_attachments));
6432
- store.dispatch(setComponentAttachments(component_attachments));
6433
- store.dispatch(setComponentTypeAttachments(component_type_attachments));
6434
- store.dispatch(setProjectAttachments(project_attachments));
6435
- store.dispatch(setDocumentAttachments(document_attachments));
6948
+ void this.client.documents.refreshStore().then(() => {
6949
+ void this.client.documentAttachments.refreshStore().then();
6436
6950
  });
6437
- void this.client.documents.refreshStore();
6438
- void this.client.issueUpdates.refreshStore();
6439
6951
  }
6440
6952
  store.dispatch(setIsFetchingInitialData(false));
6441
6953
  if (overwrite) {
@@ -6599,6 +7111,48 @@ var __publicField = (obj, key, value) => {
6599
7111
  });
6600
7112
  }
6601
7113
  }
7114
+ class ProjectAttachmentService extends BaseAttachmentService {
7115
+ constructor() {
7116
+ super(...arguments);
7117
+ __publicField(this, "attachmentModel", AttachmentModel.Project);
7118
+ }
7119
+ buildOfflineAttachment(data) {
7120
+ return offline({
7121
+ file: URL.createObjectURL(data.file),
7122
+ file_sha1: data.sha1,
7123
+ created_by: data.createdBy,
7124
+ file_name: data.file.name,
7125
+ file_type: data.file.type,
7126
+ submitted_at: data.submittedAt,
7127
+ description: data.description,
7128
+ project: data.modelId
7129
+ });
7130
+ }
7131
+ async attachFilesToProject(files, projectId) {
7132
+ return this.attachFiles(files, projectId, this.buildOfflineAttachment.bind(this), {
7133
+ addAttachments: addProjectAttachments,
7134
+ updateAttachments: updateProjectAttachments,
7135
+ removeAttachments: removeProjectAttachments
7136
+ });
7137
+ }
7138
+ deleteProjectAttachment(attachmentId) {
7139
+ return this.deleteAttachment(
7140
+ attachmentId,
7141
+ {
7142
+ setAttachment: setProjectAttachment,
7143
+ removeAttachment: removeProjectAttachment
7144
+ },
7145
+ {
7146
+ selectAttachment: selectProjectAttachment
7147
+ }
7148
+ );
7149
+ }
7150
+ async refreshStore() {
7151
+ return this.getAttachments({
7152
+ setAttachments: setProjectAttachments
7153
+ });
7154
+ }
7155
+ }
6602
7156
  class ProjectService extends BaseApiService {
6603
7157
  /**
6604
7158
  * Creates a new project. Due to the nature of project creation,
@@ -6800,7 +7354,7 @@ var __publicField = (obj, key, value) => {
6800
7354
  ...revisionAttachmentPayload,
6801
7355
  file: URL.createObjectURL(image)
6802
7356
  };
6803
- store.dispatch(addUserFormRevisionAttachment(offlinePayload));
7357
+ store.dispatch(addFormRevisionAttachment(offlinePayload));
6804
7358
  return attach;
6805
7359
  });
6806
7360
  });
@@ -6836,8 +7390,8 @@ var __publicField = (obj, key, value) => {
6836
7390
  submitted_at: submittedAt
6837
7391
  };
6838
7392
  const { store } = this.client;
6839
- store.dispatch(addUserForm(retForm));
6840
- store.dispatch(addUserFormRevision(retRevision));
7393
+ store.dispatch(addForm(retForm));
7394
+ store.dispatch(addFormRevision(retRevision));
6841
7395
  const formPromise = this.enqueueRequest({
6842
7396
  description: "Create form",
6843
7397
  method: HttpMethod.POST,
@@ -6855,8 +7409,8 @@ var __publicField = (obj, key, value) => {
6855
7409
  });
6856
7410
  const attachImagesPromises = this.getAttachImagePromises(images, offlineRevisionPayload.offline_id);
6857
7411
  void formPromise.catch((e) => {
6858
- store.dispatch(deleteUserForm(retForm.offline_id));
6859
- store.dispatch(deleteUserFormRevision(retRevision.offline_id));
7412
+ store.dispatch(deleteForm(retForm.offline_id));
7413
+ store.dispatch(deleteFormRevision(retRevision.offline_id));
6860
7414
  throw e;
6861
7415
  });
6862
7416
  const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
@@ -6899,7 +7453,7 @@ var __publicField = (obj, key, value) => {
6899
7453
  form: formId2,
6900
7454
  submitted_at: (/* @__PURE__ */ new Date()).toISOString()
6901
7455
  };
6902
- store.dispatch(addUserFormRevision(fullRevision));
7456
+ store.dispatch(addFormRevision(fullRevision));
6903
7457
  const promise = this.enqueueRequest({
6904
7458
  description: "Create form revision",
6905
7459
  method: HttpMethod.PATCH,
@@ -6913,9 +7467,9 @@ var __publicField = (obj, key, value) => {
6913
7467
  });
6914
7468
  const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
6915
7469
  void promise.then((result) => {
6916
- store.dispatch(addUserFormRevision(result));
7470
+ store.dispatch(setFormRevision(result));
6917
7471
  }).catch(() => {
6918
- store.dispatch(deleteUserFormRevision(fullRevision.offline_id));
7472
+ store.dispatch(deleteFormRevision(fullRevision.offline_id));
6919
7473
  });
6920
7474
  const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
6921
7475
  return [fullRevision, settledPromise];
@@ -6957,19 +7511,19 @@ var __publicField = (obj, key, value) => {
6957
7511
  async delete(formId2) {
6958
7512
  const { store } = this.client;
6959
7513
  const state = store.getState();
6960
- const userForm = selectUserForm(formId2)(state);
7514
+ const userForm = selectForm(formId2)(state);
6961
7515
  if (!userForm) {
6962
7516
  throw new Error("Expected userForm to exist");
6963
7517
  }
6964
- const userFormSubmissions = selectSubmissionsForForm(formId2)(state);
7518
+ const userFormSubmissions = selectFormSubmissionsOfForm(formId2)(state);
6965
7519
  if (userFormSubmissions && userFormSubmissions.length > 0) {
6966
- store.dispatch(deleteUserFormSubmissions(userFormSubmissions));
7520
+ store.dispatch(deleteFormSubmissions(userFormSubmissions.map(({ offline_id }) => offline_id)));
6967
7521
  }
6968
- const userFormRevisions = selectRevisionsForForm(formId2)(state);
7522
+ const userFormRevisions = selectFormRevisionsOfForm(formId2)(state);
6969
7523
  if (userFormRevisions && userFormRevisions.length > 0) {
6970
- store.dispatch(deleteUserFormRevisions(userFormRevisions));
7524
+ store.dispatch(deleteFormRevisions(userFormRevisions.map(({ offline_id }) => offline_id)));
6971
7525
  }
6972
- store.dispatch(deleteUserForm(formId2));
7526
+ store.dispatch(deleteForm(formId2));
6973
7527
  try {
6974
7528
  return await this.enqueueRequest({
6975
7529
  description: "Delete form",
@@ -6979,12 +7533,12 @@ var __publicField = (obj, key, value) => {
6979
7533
  blocks: []
6980
7534
  });
6981
7535
  } catch (e) {
6982
- store.dispatch(addUserForm(userForm));
7536
+ store.dispatch(addForm(userForm));
6983
7537
  if (userFormRevisions && userFormRevisions.length > 0) {
6984
- store.dispatch(addUserFormRevisions(userFormRevisions));
7538
+ store.dispatch(addFormRevisions(userFormRevisions));
6985
7539
  }
6986
7540
  if (userFormSubmissions && userFormSubmissions.length > 0) {
6987
- store.dispatch(addUserFormSubmissions(userFormSubmissions));
7541
+ store.dispatch(addFormSubmissions(userFormSubmissions));
6988
7542
  }
6989
7543
  throw e;
6990
7544
  }
@@ -6998,16 +7552,15 @@ var __publicField = (obj, key, value) => {
6998
7552
  blockers: [],
6999
7553
  blocks: []
7000
7554
  });
7001
- store.dispatch(addUserForms(Object.values(result.forms)));
7002
- store.dispatch(addUserFormRevisions(Object.values(result.revisions)));
7003
- store.dispatch(setUserFormRevisionAttachments(Object.values(result.attachments)));
7555
+ store.dispatch(setForms(Object.values(result.forms)));
7556
+ store.dispatch(setFormRevisions(Object.values(result.revisions)));
7557
+ store.dispatch(setFormRevisionAttachments(Object.values(result.attachments)));
7004
7558
  }
7005
7559
  }
7006
7560
  const isArrayOfFiles = (value) => {
7007
7561
  return Array.isArray(value) && value[0] instanceof File;
7008
7562
  };
7009
- const separateFilesFromValues = (payload) => {
7010
- const { values } = payload;
7563
+ const separateFilesFromValues = (values) => {
7011
7564
  const files = {};
7012
7565
  const newValues = {};
7013
7566
  for (const key in values) {
@@ -7022,17 +7575,13 @@ var __publicField = (obj, key, value) => {
7022
7575
  newValues[key] = value;
7023
7576
  }
7024
7577
  }
7025
- const payloadWithoutFiles = {
7026
- ...payload,
7027
- values: newValues
7028
- };
7029
- return { payloadWithoutFiles, files };
7578
+ return { values: newValues, files };
7030
7579
  };
7031
7580
  class UserFormSubmissionService extends BaseApiService {
7032
7581
  constructor() {
7033
7582
  super(...arguments);
7034
7583
  // Attach files to submission, after uploading them to S3
7035
- __publicField(this, "getAttachFilesPromises", (files, payload) => {
7584
+ __publicField(this, "getAttachFilesPromises", (files, submission) => {
7036
7585
  const { store } = this.client;
7037
7586
  return Object.entries(files).map(async ([key, fileArray]) => {
7038
7587
  const attachResults = [];
@@ -7042,24 +7591,27 @@ var __publicField = (obj, key, value) => {
7042
7591
  const [fileProps] = await this.client.files.uploadFileToS3(sha1);
7043
7592
  const submissionAttachmentPayload = offline({
7044
7593
  ...fileProps,
7045
- submission: payload.offline_id,
7594
+ submission: submission.offline_id,
7046
7595
  field_identifier: key
7047
7596
  });
7048
7597
  const attach = await this.enqueueRequest({
7049
7598
  description: "Attach file to form submission",
7050
7599
  method: HttpMethod.POST,
7051
- url: `/forms/submission/${payload.offline_id}/attachments/`,
7600
+ url: `/forms/submission/${submission.offline_id}/attachments/`,
7052
7601
  payload: submissionAttachmentPayload,
7053
- blockers: [payload.component, payload.component_stage, payload.issue, payload.form_revision].filter(
7054
- (x) => x !== void 0
7055
- ),
7602
+ blockers: [
7603
+ submission.component,
7604
+ submission.component_stage,
7605
+ submission.issue,
7606
+ submission.form_revision
7607
+ ].filter((x) => x !== void 0),
7056
7608
  blocks: [submissionAttachmentPayload.offline_id]
7057
7609
  });
7058
7610
  const offlinePayload = {
7059
7611
  ...submissionAttachmentPayload,
7060
7612
  file: URL.createObjectURL(file)
7061
7613
  };
7062
- store.dispatch(addUserFormSubmissionAttachment(offlinePayload));
7614
+ store.dispatch(addFormSubmissionAttachment(offlinePayload));
7063
7615
  attachResults.push(attach);
7064
7616
  }
7065
7617
  return attachResults;
@@ -7073,71 +7625,168 @@ var __publicField = (obj, key, value) => {
7073
7625
  if (!activeProjectId) {
7074
7626
  throw new Error("Expected an active project");
7075
7627
  }
7076
- const { payloadWithoutFiles, files } = separateFilesFromValues(payload);
7628
+ const { values, files } = separateFilesFromValues(payload.values);
7629
+ const offlineSubmission = {
7630
+ ...payload,
7631
+ values,
7632
+ created_by: state.userReducer.currentUser.id,
7633
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString()
7634
+ };
7077
7635
  const promise = this.enqueueRequest({
7078
7636
  description: "Respond to form",
7079
7637
  method: HttpMethod.POST,
7080
7638
  url: `/forms/revisions/${payload.form_revision}/respond/`,
7081
- payload: { ...payloadWithoutFiles, project: activeProjectId },
7639
+ payload: { ...offlineSubmission, project: activeProjectId },
7082
7640
  blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
7083
7641
  (x) => x !== void 0
7084
7642
  ),
7085
7643
  blocks: [payload.offline_id]
7086
7644
  });
7087
- const attachFilesPromises = this.getAttachFilesPromises(files, payload);
7088
- const now = (/* @__PURE__ */ new Date()).toISOString();
7089
- const fullOfflineResult = {
7090
- ...payload,
7091
- created_by: state.userReducer.currentUser.id,
7092
- created_at: now,
7093
- updated_at: now
7094
- };
7095
- const offlineResultWithoutFiles = {
7096
- ...fullOfflineResult,
7097
- ...payloadWithoutFiles
7098
- };
7099
- store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
7645
+ const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
7646
+ store.dispatch(addFormSubmission(offlineSubmission));
7100
7647
  void promise.then((result) => {
7101
7648
  store.dispatch(addActiveProjectFormSubmissionsCount(1));
7102
- store.dispatch(updateOrCreateUserFormSubmission(result));
7649
+ store.dispatch(setFormSubmission(result));
7103
7650
  return result;
7104
7651
  }).catch(() => {
7105
- store.dispatch(deleteUserFormSubmission(payload.offline_id));
7652
+ store.dispatch(deleteFormSubmission(payload.offline_id));
7106
7653
  store.dispatch(addActiveProjectFormSubmissionsCount(-1));
7107
7654
  });
7108
7655
  const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
7109
- return [fullOfflineResult, settledPromise];
7656
+ return [offlineSubmission, settledPromise];
7110
7657
  }
7111
- update(submission) {
7658
+ // Note currently the bulkAdd method is specific to form submissions for components
7659
+ // TODO: adapt the support bulk adding to any model type
7660
+ async bulkAdd(args) {
7661
+ const { formRevision, values: argsValues, componentOfflineIds } = args;
7112
7662
  const { store } = this.client;
7113
- const { payloadWithoutFiles, files } = separateFilesFromValues(submission);
7114
- if (!("created_by" in payloadWithoutFiles) || !("created_at" in payloadWithoutFiles)) {
7115
- throw new Error("Expected payloadWithoutFiles to have created_by and created_at fields.");
7663
+ const offlineSubmissions = [];
7664
+ const offlineAttachments = [];
7665
+ const submissionOfflineIds = [];
7666
+ const submissionsPayload = [];
7667
+ const attachmentsPayload = [];
7668
+ const { values, files } = separateFilesFromValues(argsValues);
7669
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
7670
+ const createdBy = store.getState().userReducer.currentUser.id;
7671
+ for (const component_id of componentOfflineIds) {
7672
+ const submission = offline({
7673
+ form_revision: formRevision,
7674
+ values,
7675
+ created_by: createdBy,
7676
+ submitted_at: submittedAt,
7677
+ component: component_id
7678
+ });
7679
+ submissionOfflineIds.push(submission.offline_id);
7680
+ submissionsPayload.push({ offline_id: submission.offline_id, component_id });
7681
+ offlineSubmissions.push(submission);
7682
+ for (const [fieldIdentifier, fileArray] of Object.entries(files)) {
7683
+ for (const file of fileArray) {
7684
+ const sha1 = await hashFile(file);
7685
+ await this.client.files.addCache(file, sha1);
7686
+ const offlineAttachment = offline({
7687
+ file_name: file.name,
7688
+ file_sha1: sha1,
7689
+ file: URL.createObjectURL(file),
7690
+ submission: submission.offline_id,
7691
+ field_identifier: fieldIdentifier
7692
+ });
7693
+ offlineAttachments.push(offlineAttachment);
7694
+ attachmentsPayload.push({
7695
+ offline_id: offlineAttachment.offline_id,
7696
+ submission_id: submission.offline_id,
7697
+ sha1,
7698
+ name: file.name,
7699
+ field_identifier: fieldIdentifier
7700
+ });
7701
+ }
7702
+ }
7703
+ }
7704
+ const filesRecord = {};
7705
+ for (const file of Object.values(files).flat()) {
7706
+ const sha1 = await hashFile(file);
7707
+ filesRecord[sha1] = {
7708
+ sha1,
7709
+ extension: file.name.split(".").pop() || "",
7710
+ file_type: file.type,
7711
+ size: file.size
7712
+ };
7116
7713
  }
7714
+ store.dispatch(addFormSubmissions(offlineSubmissions));
7715
+ store.dispatch(addFormSubmissionAttachments(offlineAttachments));
7716
+ const promise = this.enqueueRequest({
7717
+ description: "Bulk add form submissions",
7718
+ method: HttpMethod.POST,
7719
+ url: `/forms/revisions/${formRevision}/bulk-respond/`,
7720
+ payload: {
7721
+ form_data: values,
7722
+ submitted_at: submittedAt,
7723
+ submissions: submissionsPayload,
7724
+ attachments: attachmentsPayload,
7725
+ files: Object.values(filesRecord)
7726
+ },
7727
+ blockers: componentOfflineIds,
7728
+ blocks: submissionOfflineIds
7729
+ });
7730
+ promise.then(({ submissions, attachments, presigned_urls }) => {
7731
+ store.dispatch(updateFormSubmissions(submissions));
7732
+ store.dispatch(updateFormSubmissionAttachments(attachments));
7733
+ for (const [sha1, presigned_url] of Object.entries(presigned_urls)) {
7734
+ const file = filesRecord[sha1];
7735
+ if (!file)
7736
+ continue;
7737
+ void this.enqueueRequest({
7738
+ url: presigned_url.url,
7739
+ description: "Upload file",
7740
+ method: HttpMethod.POST,
7741
+ isExternalUrl: true,
7742
+ isAuthNeeded: false,
7743
+ attachmentHash: sha1,
7744
+ blockers: [`s3-${file.sha1}.${file.extension}`],
7745
+ blocks: [sha1],
7746
+ s3url: presigned_url
7747
+ });
7748
+ }
7749
+ }).catch(() => {
7750
+ store.dispatch(deleteFormSubmissions(submissionOfflineIds));
7751
+ store.dispatch(deleteFormSubmissionAttachments(offlineAttachments.map((x) => x.offline_id)));
7752
+ });
7753
+ return [offlineSubmissions, promise.then(({ submissions }) => submissions)];
7754
+ }
7755
+ update(submission) {
7756
+ const { store } = this.client;
7757
+ const { values, files } = separateFilesFromValues(submission.values);
7117
7758
  const attachFilesPromises = this.getAttachFilesPromises(files, submission);
7118
- const fullResult = {
7119
- ...payloadWithoutFiles,
7120
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
7759
+ const offlineSubmission = {
7760
+ ...submission,
7761
+ values
7121
7762
  };
7122
- store.dispatch(updateOrCreateUserFormSubmission(fullResult));
7763
+ const submissionToBeUpdated = store.getState().formSubmissionReducer.formSubmissions[submission.offline_id];
7764
+ store.dispatch(updateFormSubmission(offlineSubmission));
7123
7765
  const promise = this.enqueueRequest({
7124
7766
  description: "Patch form submission",
7125
7767
  method: HttpMethod.PATCH,
7126
7768
  url: `/forms/submissions/${submission.offline_id}/`,
7127
- payload: fullResult,
7128
- blockers: [fullResult.issue, fullResult.component, fullResult.component_stage].filter(
7769
+ payload: offlineSubmission,
7770
+ blockers: [offlineSubmission.issue, offlineSubmission.component, offlineSubmission.component_stage].filter(
7129
7771
  (x) => x !== void 0
7130
7772
  ),
7131
- blocks: [fullResult.offline_id]
7773
+ blocks: [offlineSubmission.offline_id]
7774
+ });
7775
+ promise.then((createdSubmission) => {
7776
+ store.dispatch(setFormSubmission(createdSubmission));
7777
+ }).catch(() => {
7778
+ store.dispatch(setFormSubmission(submissionToBeUpdated));
7132
7779
  });
7133
- return Promise.all([promise, ...attachFilesPromises]).then(() => promise);
7780
+ return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
7134
7781
  }
7135
7782
  async delete(submissionId) {
7136
7783
  const { store } = this.client;
7137
7784
  const state = store.getState();
7138
- const submission = state.userFormReducer.submissions[submissionId];
7139
- store.dispatch(deleteUserFormSubmission(submissionId));
7785
+ const submission = state.formSubmissionReducer.formSubmissions[submissionId];
7786
+ const submissionAttachments = selectAttachmentsOfFormSubmission(submissionId)(state);
7787
+ store.dispatch(deleteFormSubmission(submissionId));
7140
7788
  store.dispatch(addActiveProjectFormSubmissionsCount(-1));
7789
+ store.dispatch(deleteFormSubmissionAttachments(submissionAttachments.map((x) => x.offline_id)));
7141
7790
  try {
7142
7791
  return await this.enqueueRequest({
7143
7792
  description: "Delete user form submissions",
@@ -7147,10 +7796,9 @@ var __publicField = (obj, key, value) => {
7147
7796
  blocks: []
7148
7797
  });
7149
7798
  } catch (e) {
7150
- if (submission) {
7151
- store.dispatch(addActiveProjectFormSubmissionsCount(1));
7152
- store.dispatch(updateOrCreateUserFormSubmission(submission));
7153
- }
7799
+ store.dispatch(addActiveProjectFormSubmissionsCount(1));
7800
+ store.dispatch(addFormSubmission(submission));
7801
+ store.dispatch(addFormSubmissionAttachments(submissionAttachments));
7154
7802
  throw e;
7155
7803
  }
7156
7804
  }
@@ -7164,7 +7812,7 @@ var __publicField = (obj, key, value) => {
7164
7812
  blockers: [],
7165
7813
  blocks: []
7166
7814
  });
7167
- store.dispatch(setUserFormSubmissions(submissions));
7815
+ store.dispatch(setFormSubmissions(submissions));
7168
7816
  const attachments = await this.enqueueRequest({
7169
7817
  description: "Fetch form attachments",
7170
7818
  method: HttpMethod.GET,
@@ -7172,7 +7820,7 @@ var __publicField = (obj, key, value) => {
7172
7820
  blockers: [],
7173
7821
  blocks: []
7174
7822
  });
7175
- store.dispatch(setUserFormSubmissionAttachments(attachments));
7823
+ store.dispatch(setFormSubmissionAttachments(attachments));
7176
7824
  }
7177
7825
  }
7178
7826
  class WorkspaceService extends BaseApiService {
@@ -7864,6 +8512,48 @@ var __publicField = (obj, key, value) => {
7864
8512
  store.dispatch(setDocuments(result));
7865
8513
  }
7866
8514
  }
8515
+ class DocumentAttachmentService extends BaseAttachmentService {
8516
+ constructor() {
8517
+ super(...arguments);
8518
+ __publicField(this, "attachmentModel", AttachmentModel.Document);
8519
+ }
8520
+ buildOfflineAttachment(data) {
8521
+ return offline({
8522
+ file: URL.createObjectURL(data.file),
8523
+ file_sha1: data.sha1,
8524
+ created_by: data.createdBy,
8525
+ file_name: data.file.name,
8526
+ file_type: data.file.type,
8527
+ submitted_at: data.submittedAt,
8528
+ description: data.description,
8529
+ document: data.modelId
8530
+ });
8531
+ }
8532
+ async attachFilesToDocument(files, documentId) {
8533
+ return this.attachFiles(files, documentId, this.buildOfflineAttachment.bind(this), {
8534
+ addAttachments: addDocumentAttachments,
8535
+ updateAttachments: updateDocumentAttachments,
8536
+ removeAttachments: removeDocumentAttachments
8537
+ });
8538
+ }
8539
+ deleteDocumentAttachment(attachmentId) {
8540
+ return this.deleteAttachment(
8541
+ attachmentId,
8542
+ {
8543
+ setAttachment: setDocumentAttachment,
8544
+ removeAttachment: removeDocumentAttachment
8545
+ },
8546
+ {
8547
+ selectAttachment: selectDocumentAttachment
8548
+ }
8549
+ );
8550
+ }
8551
+ async refreshStore() {
8552
+ return this.getAttachments({
8553
+ setAttachments: setDocumentAttachments
8554
+ });
8555
+ }
8556
+ }
7867
8557
  class AgentService extends BaseApiService {
7868
8558
  /**
7869
8559
  * Prompt the agent with a message.
@@ -7911,20 +8601,25 @@ var __publicField = (obj, key, value) => {
7911
8601
  __publicField(this, "issues", new IssueService(this));
7912
8602
  __publicField(this, "issueComments", new IssueCommentService(this));
7913
8603
  __publicField(this, "issueUpdates", new IssueUpdateService(this));
8604
+ __publicField(this, "issueAttachments", new IssueAttachmentService(this));
7914
8605
  __publicField(this, "workspaces", new WorkspaceService(this));
7915
8606
  __publicField(this, "main", new MainService(this));
7916
8607
  __publicField(this, "components", new ComponentService(this));
8608
+ __publicField(this, "componentAttachments", new ComponentAttachmentService(this));
7917
8609
  __publicField(this, "componentTypes", new ComponentTypeService(this));
8610
+ __publicField(this, "componentTypeAttachments", new ComponentTypeAttachmentService(this));
7918
8611
  __publicField(this, "componentStages", new ComponentStageService(this));
7919
8612
  __publicField(this, "componentStageCompletions", new ComponentStageCompletionService(this));
7920
8613
  __publicField(this, "userForms", new UserFormService(this));
7921
8614
  __publicField(this, "userFormSubmissions", new UserFormSubmissionService(this));
7922
8615
  __publicField(this, "projects", new ProjectService(this));
7923
8616
  __publicField(this, "projectFiles", new ProjectFileService(this));
8617
+ __publicField(this, "projectAttachments", new ProjectAttachmentService(this));
7924
8618
  __publicField(this, "emailVerification", new EmailVerificationService(this));
7925
8619
  __publicField(this, "emailDomains", new EmailDomainsService(this));
7926
8620
  __publicField(this, "licenses", new LicenseService(this));
7927
8621
  __publicField(this, "documents", new DocumentService(this));
8622
+ __publicField(this, "documentAttachments", new DocumentAttachmentService(this));
7928
8623
  this.API_URL = apiUrl;
7929
8624
  this.store = store;
7930
8625
  }
@@ -14030,7 +14725,7 @@ var __publicField = (obj, key, value) => {
14030
14725
  };
14031
14726
  const useAttachImagesToFormRevisionFields = (revision) => {
14032
14727
  const { sdk } = useSDK();
14033
- const attachments = useAppSelector(selectRevisionAttachments((revision == null ? void 0 : revision.offline_id) ?? ""));
14728
+ const attachments = useAppSelector(selectAttachmentsOfFormRevision((revision == null ? void 0 : revision.offline_id) ?? ""));
14034
14729
  return React.useMemo(() => {
14035
14730
  if (!revision || !attachments)
14036
14731
  return revision;
@@ -14127,7 +14822,7 @@ var __publicField = (obj, key, value) => {
14127
14822
  return formRevisionToSchema(revisionWithImages, { readonly: true });
14128
14823
  }, [revisionWithImages]);
14129
14824
  const submissionValuesWithAttachments = React.useMemo(() => {
14130
- const attachments = selectSubmissionAttachments(submission.offline_id)(sdk.store.getState()) ?? [];
14825
+ const attachments = selectAttachmentsOfFormSubmission(submission.offline_id)(sdk.store.getState()) ?? [];
14131
14826
  const downloadedAttachments = {};
14132
14827
  for (const attachment of attachments) {
14133
14828
  const promise = sdk.files.fetchFileFromUrl(attachment.file, attachment.file_sha1, attachment.file_name);
@@ -14177,8 +14872,8 @@ var __publicField = (obj, key, value) => {
14177
14872
  }
14178
14873
  return ret;
14179
14874
  }, [filter, maxResults, ownerFilter]);
14180
- const userForms = useAppSelector(selectFilteredUserForms(ownerFilterOptions)) ?? [];
14181
- const userFormMapping = useAppSelector(selectUserFormMapping);
14875
+ const userForms = useAppSelector(selectFilteredForms(ownerFilterOptions)) ?? [];
14876
+ const userFormMapping = useAppSelector(selectFormMapping);
14182
14877
  const attachableUserForms = userForms.filter((form) => !form.component_type);
14183
14878
  const attachableUserFormMapping = Object.values(userFormMapping).filter(
14184
14879
  (form) => !form.component_type
@@ -14211,7 +14906,7 @@ var __publicField = (obj, key, value) => {
14211
14906
  const handleChange = React.useCallback((e) => {
14212
14907
  setFilter(e.currentTarget.value);
14213
14908
  }, []);
14214
- const numberOfForms = useAppSelector(selectNumberOfGeneralUserForms) || 0;
14909
+ const numberOfForms = useAppSelector(selectGeneralFormCount) || 0;
14215
14910
  const numberOfHiddenForms = numberOfForms - attachableUserForms.length;
14216
14911
  const overflowMessage = attachableUserForms.length == maxResults && numberOfHiddenForms > 0 ? `Only the first ${maxResults} results are shown (${numberOfHiddenForms} hidden)` : numberOfHiddenForms > 0 && `${numberOfHiddenForms} hidden forms`;
14217
14912
  return /* @__PURE__ */ jsxRuntime.jsxs(blocks.Flex, { ref, direction: "column", gap: "2", children: [
@@ -14305,16 +15000,13 @@ var __publicField = (obj, key, value) => {
14305
15000
  const { submission, onSubmissionClick, compact, labelType, rowDecorator } = props;
14306
15001
  const currentUser = useAppSelector(selectCurrentUser);
14307
15002
  const createdBy = useAppSelector(selectUser("created_by" in submission ? submission.created_by : currentUser.id));
14308
- const dateToUse = getCreatedAtOrSubmittedAtDate(submission);
14309
- const formattedDateTime = isToday(dateToUse) ? dateToUse.toLocaleTimeString([], {
14310
- hour: "2-digit",
14311
- minute: "2-digit"
14312
- }) : getLocalDateString(dateToUse);
15003
+ const dateToUse = submission.submitted_at;
15004
+ const formattedDateTime = getLocalDateString(dateToUse);
14313
15005
  const revision = useAppSelector(selectFormRevision(submission.form_revision));
14314
15006
  if (!revision) {
14315
15007
  throw new Error(`Could not find revision ${submission.form_revision} for submission ${submission.offline_id}.`);
14316
15008
  }
14317
- const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevision(revision.form))) == null ? void 0 : _a2.revision;
15009
+ const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevisionOfForm(revision.form))) == null ? void 0 : _a2.revision;
14318
15010
  const creatorProfileSrc = useFileSrc({
14319
15011
  file: (createdBy == null ? void 0 : createdBy.profile.file) ?? null,
14320
15012
  fileSha1: (createdBy == null ? void 0 : createdBy.profile.file_sha1) ?? null
@@ -14345,10 +15037,6 @@ var __publicField = (obj, key, value) => {
14345
15037
  return row;
14346
15038
  });
14347
15039
  FormSubmissionBrowserEntry.displayName = "FormSubmissionBrowserEntry";
14348
- const getCreatedAtOrSubmittedAtDate = (submission) => {
14349
- const date = "created_at" in submission ? submission.created_at : submission.submitted_at;
14350
- return new Date(date);
14351
- };
14352
15040
  const FormSubmissionBrowser = React.memo((props) => {
14353
15041
  const {
14354
15042
  formId: formId2,
@@ -14362,10 +15050,10 @@ var __publicField = (obj, key, value) => {
14362
15050
  if (!!formId2 === !!propSubmissions) {
14363
15051
  throw new Error("Either formId or submissions must be provided, but not both.");
14364
15052
  }
14365
- const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectSubmissionsForForm(formId2));
15053
+ const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectFormSubmissionsOfForm(formId2));
14366
15054
  const sortedSubmissions = React.useMemo(
14367
15055
  () => submissions == null ? void 0 : submissions.sort((a, b) => {
14368
- return getCreatedAtOrSubmittedAtDate(b).getTime() - getCreatedAtOrSubmittedAtDate(a).getTime();
15056
+ return a.submitted_at.localeCompare(b.submitted_at);
14369
15057
  }),
14370
15058
  [submissions]
14371
15059
  );
@@ -15588,6 +16276,7 @@ var __publicField = (obj, key, value) => {
15588
16276
  }, Symbol.toStringTag, { value: "Module" }));
15589
16277
  exports2.APIError = APIError;
15590
16278
  exports2.AgentService = AgentService;
16279
+ exports2.AttachmentModel = AttachmentModel;
15591
16280
  exports2.AttachmentService = AttachmentService;
15592
16281
  exports2.AuthService = AuthService;
15593
16282
  exports2.BaseApiService = BaseApiService;
@@ -15599,15 +16288,18 @@ var __publicField = (obj, key, value) => {
15599
16288
  exports2.ColorPicker = ColorPicker;
15600
16289
  exports2.Colors = Colors;
15601
16290
  exports2.ColorsToString = ColorsToString;
16291
+ exports2.ComponentAttachmentService = ComponentAttachmentService;
15602
16292
  exports2.ComponentService = ComponentService;
15603
16293
  exports2.ComponentStageColors = ComponentStageColors;
15604
16294
  exports2.ComponentStageCompletionService = ComponentStageCompletionService;
15605
16295
  exports2.ComponentStageService = ComponentStageService;
16296
+ exports2.ComponentTypeAttachmentService = ComponentTypeAttachmentService;
15606
16297
  exports2.ComponentTypeService = ComponentTypeService;
15607
16298
  exports2.DEFAULT_ISSUE_PRIORITY = DEFAULT_ISSUE_PRIORITY;
15608
16299
  exports2.DEFAULT_ISSUE_STATUS = DEFAULT_ISSUE_STATUS;
15609
16300
  exports2.DateField = DateField;
15610
16301
  exports2.DateInput = DateInput;
16302
+ exports2.DocumentAttachmentService = DocumentAttachmentService;
15611
16303
  exports2.DocumentService = DocumentService;
15612
16304
  exports2.EmailDomainsService = EmailDomainsService;
15613
16305
  exports2.EmailVerificationService = EmailVerificationService;
@@ -15631,6 +16323,7 @@ var __publicField = (obj, key, value) => {
15631
16323
  exports2.InputWithHelpText = InputWithHelpText;
15632
16324
  exports2.InputWithLabel = InputWithLabel;
15633
16325
  exports2.InputWithLabelAndHelpText = InputWithLabelAndHelpText;
16326
+ exports2.IssueAttachmentService = IssueAttachmentService;
15634
16327
  exports2.IssueCommentService = IssueCommentService;
15635
16328
  exports2.IssuePriority = IssuePriority;
15636
16329
  exports2.IssueService = IssueService;
@@ -15662,6 +16355,7 @@ var __publicField = (obj, key, value) => {
15662
16355
  exports2.PatchFormProvider = PatchFormProvider;
15663
16356
  exports2.ProjectAccessLevel = ProjectAccessLevel;
15664
16357
  exports2.ProjectAccessService = ProjectAccessService;
16358
+ exports2.ProjectAttachmentService = ProjectAttachmentService;
15665
16359
  exports2.ProjectFileService = ProjectFileService;
15666
16360
  exports2.ProjectService = ProjectService;
15667
16361
  exports2.ProjectType = ProjectType;
@@ -15682,6 +16376,7 @@ var __publicField = (obj, key, value) => {
15682
16376
  exports2.VerificationCodeType = VerificationCodeType;
15683
16377
  exports2.WorkspaceService = WorkspaceService;
15684
16378
  exports2.YELLOW = YELLOW;
16379
+ exports2._selectLatestFormRevision = _selectLatestFormRevision;
15685
16380
  exports2._setLatestRetryTime = _setLatestRetryTime;
15686
16381
  exports2.acceptProjectInvite = acceptProjectInvite;
15687
16382
  exports2.addActiveProjectFormSubmissionsCount = addActiveProjectFormSubmissionsCount;
@@ -15699,6 +16394,16 @@ var __publicField = (obj, key, value) => {
15699
16394
  exports2.addDocuments = addDocuments;
15700
16395
  exports2.addEmailDomain = addEmailDomain;
15701
16396
  exports2.addFavouriteProjectId = addFavouriteProjectId;
16397
+ exports2.addForm = addForm;
16398
+ exports2.addFormRevision = addFormRevision;
16399
+ exports2.addFormRevisionAttachment = addFormRevisionAttachment;
16400
+ exports2.addFormRevisionAttachments = addFormRevisionAttachments;
16401
+ exports2.addFormRevisions = addFormRevisions;
16402
+ exports2.addFormSubmission = addFormSubmission;
16403
+ exports2.addFormSubmissionAttachment = addFormSubmissionAttachment;
16404
+ exports2.addFormSubmissionAttachments = addFormSubmissionAttachments;
16405
+ exports2.addFormSubmissions = addFormSubmissions;
16406
+ exports2.addForms = addForms;
15702
16407
  exports2.addIssue = addIssue;
15703
16408
  exports2.addIssueAttachment = addIssueAttachment;
15704
16409
  exports2.addIssueAttachments = addIssueAttachments;
@@ -15719,13 +16424,6 @@ var __publicField = (obj, key, value) => {
15719
16424
  exports2.addStageCompletions = addStageCompletions;
15720
16425
  exports2.addStages = addStages;
15721
16426
  exports2.addToRecentIssues = addToRecentIssues;
15722
- exports2.addUserForm = addUserForm;
15723
- exports2.addUserFormRevision = addUserFormRevision;
15724
- exports2.addUserFormRevisionAttachment = addUserFormRevisionAttachment;
15725
- exports2.addUserFormRevisions = addUserFormRevisions;
15726
- exports2.addUserFormSubmissionAttachment = addUserFormSubmissionAttachment;
15727
- exports2.addUserFormSubmissions = addUserFormSubmissions;
15728
- exports2.addUserForms = addUserForms;
15729
16427
  exports2.addUsers = addUsers;
15730
16428
  exports2.addWorkspace = addWorkspace;
15731
16429
  exports2.areArraysEqual = areArraysEqual;
@@ -15746,6 +16444,7 @@ var __publicField = (obj, key, value) => {
15746
16444
  exports2.componentStageSlice = componentStageSlice;
15747
16445
  exports2.componentTypeReducer = componentTypeReducer;
15748
16446
  exports2.componentTypeSlice = componentTypeSlice;
16447
+ exports2.constructUploadedFilePayloads = constructUploadedFilePayloads;
15749
16448
  exports2.coordinatesAreEqual = coordinatesAreEqual;
15750
16449
  exports2.coordinatesToLiteral = coordinatesToLiteral;
15751
16450
  exports2.coordinatesToPointGeometry = coordinatesToPointGeometry;
@@ -15756,12 +16455,16 @@ var __publicField = (obj, key, value) => {
15756
16455
  exports2.defaultBadgeColor = defaultBadgeColor;
15757
16456
  exports2.defaultStore = defaultStore;
15758
16457
  exports2.deleteComponentType = deleteComponentType;
16458
+ exports2.deleteForm = deleteForm;
16459
+ exports2.deleteFormRevision = deleteFormRevision;
16460
+ exports2.deleteFormRevisionAttachment = deleteFormRevisionAttachment;
16461
+ exports2.deleteFormRevisionAttachments = deleteFormRevisionAttachments;
16462
+ exports2.deleteFormRevisions = deleteFormRevisions;
16463
+ exports2.deleteFormSubmission = deleteFormSubmission;
16464
+ exports2.deleteFormSubmissionAttachment = deleteFormSubmissionAttachment;
16465
+ exports2.deleteFormSubmissionAttachments = deleteFormSubmissionAttachments;
16466
+ exports2.deleteFormSubmissions = deleteFormSubmissions;
15759
16467
  exports2.deleteProject = deleteProject;
15760
- exports2.deleteUserForm = deleteUserForm;
15761
- exports2.deleteUserFormRevision = deleteUserFormRevision;
15762
- exports2.deleteUserFormRevisions = deleteUserFormRevisions;
15763
- exports2.deleteUserFormSubmission = deleteUserFormSubmission;
15764
- exports2.deleteUserFormSubmissions = deleteUserFormSubmissions;
15765
16468
  exports2.dequeue = dequeue;
15766
16469
  exports2.deserialize = deserialize;
15767
16470
  exports2.deserializeField = deserializeField;
@@ -15790,7 +16493,13 @@ var __publicField = (obj, key, value) => {
15790
16493
  exports2.fileSlice = fileSlice;
15791
16494
  exports2.fileToBlob = fileToBlob;
15792
16495
  exports2.flipCoordinates = flipCoordinates;
16496
+ exports2.formReducer = formReducer;
16497
+ exports2.formRevisionReducer = formRevisionReducer;
15793
16498
  exports2.formRevisionToSchema = formRevisionToSchema;
16499
+ exports2.formRevisionsSlice = formRevisionsSlice;
16500
+ exports2.formSlice = formSlice;
16501
+ exports2.formSubmissionReducer = formSubmissionReducer;
16502
+ exports2.formSubmissionSlice = formSubmissionSlice;
15794
16503
  exports2.forms = index;
15795
16504
  exports2.fullComponentMarkerSize = fullComponentMarkerSize;
15796
16505
  exports2.generateBadgeColors = generateBadgeColors;
@@ -15866,6 +16575,7 @@ var __publicField = (obj, key, value) => {
15866
16575
  exports2.removeFavouriteProjectId = removeFavouriteProjectId;
15867
16576
  exports2.removeIssue = removeIssue;
15868
16577
  exports2.removeIssueAttachment = removeIssueAttachment;
16578
+ exports2.removeIssueAttachments = removeIssueAttachments;
15869
16579
  exports2.removeIssueComment = removeIssueComment;
15870
16580
  exports2.removeIssueComments = removeIssueComments;
15871
16581
  exports2.removeIssueUpdate = removeIssueUpdate;
@@ -15918,6 +16628,8 @@ var __publicField = (obj, key, value) => {
15918
16628
  exports2.selectAttachmentsOfComponentTypeByType = selectAttachmentsOfComponentTypeByType;
15919
16629
  exports2.selectAttachmentsOfDocument = selectAttachmentsOfDocument;
15920
16630
  exports2.selectAttachmentsOfDocumentByType = selectAttachmentsOfDocumentByType;
16631
+ exports2.selectAttachmentsOfFormRevision = selectAttachmentsOfFormRevision;
16632
+ exports2.selectAttachmentsOfFormSubmission = selectAttachmentsOfFormSubmission;
15921
16633
  exports2.selectAttachmentsOfIssue = selectAttachmentsOfIssue;
15922
16634
  exports2.selectAttachmentsOfIssueByType = selectAttachmentsOfIssueByType;
15923
16635
  exports2.selectAttachmentsOfProject = selectAttachmentsOfProject;
@@ -15935,11 +16647,9 @@ var __publicField = (obj, key, value) => {
15935
16647
  exports2.selectComponent = selectComponent;
15936
16648
  exports2.selectComponentAttachment = selectComponentAttachment;
15937
16649
  exports2.selectComponentAttachmentMapping = selectComponentAttachmentMapping;
15938
- exports2.selectComponentSubmissionMapping = selectComponentSubmissionMapping;
15939
16650
  exports2.selectComponentType = selectComponentType;
15940
16651
  exports2.selectComponentTypeAttachment = selectComponentTypeAttachment;
15941
16652
  exports2.selectComponentTypeAttachmentMapping = selectComponentTypeAttachmentMapping;
15942
- exports2.selectComponentTypeForm = selectComponentTypeForm;
15943
16653
  exports2.selectComponentTypeFromComponent = selectComponentTypeFromComponent;
15944
16654
  exports2.selectComponentTypeFromComponents = selectComponentTypeFromComponents;
15945
16655
  exports2.selectComponentTypeStagesMapping = selectComponentTypeStagesMapping;
@@ -15969,8 +16679,24 @@ var __publicField = (obj, key, value) => {
15969
16679
  exports2.selectExpandedSections = selectExpandedSections;
15970
16680
  exports2.selectFavouriteProjects = selectFavouriteProjects;
15971
16681
  exports2.selectFileAttachmentsOfIssue = selectFileAttachmentsOfIssue;
15972
- exports2.selectFilteredUserForms = selectFilteredUserForms;
16682
+ exports2.selectFilteredForms = selectFilteredForms;
16683
+ exports2.selectForm = selectForm;
16684
+ exports2.selectFormMapping = selectFormMapping;
16685
+ exports2.selectFormOfComponentType = selectFormOfComponentType;
15973
16686
  exports2.selectFormRevision = selectFormRevision;
16687
+ exports2.selectFormRevisionMapping = selectFormRevisionMapping;
16688
+ exports2.selectFormRevisions = selectFormRevisions;
16689
+ exports2.selectFormRevisionsOfForm = selectFormRevisionsOfForm;
16690
+ exports2.selectFormSubmission = selectFormSubmission;
16691
+ exports2.selectFormSubmissionAttachmentsMapping = selectFormSubmissionAttachmentsMapping;
16692
+ exports2.selectFormSubmissions = selectFormSubmissions;
16693
+ exports2.selectFormSubmissionsByComponents = selectFormSubmissionsByComponents;
16694
+ exports2.selectFormSubmissionsMapping = selectFormSubmissionsMapping;
16695
+ exports2.selectFormSubmissionsOfComponent = selectFormSubmissionsOfComponent;
16696
+ exports2.selectFormSubmissionsOfForm = selectFormSubmissionsOfForm;
16697
+ exports2.selectFormSubmissionsOfIssue = selectFormSubmissionsOfIssue;
16698
+ exports2.selectFormsCount = selectFormsCount;
16699
+ exports2.selectGeneralFormCount = selectGeneralFormCount;
15974
16700
  exports2.selectHiddenCategoryCount = selectHiddenCategoryCount;
15975
16701
  exports2.selectHiddenComponentTypeIds = selectHiddenComponentTypeIds;
15976
16702
  exports2.selectIsFetchingInitialData = selectIsFetchingInitialData;
@@ -15985,10 +16711,10 @@ var __publicField = (obj, key, value) => {
15985
16711
  exports2.selectIssueUpdateMapping = selectIssueUpdateMapping;
15986
16712
  exports2.selectIssueUpdatesOfIssue = selectIssueUpdatesOfIssue;
15987
16713
  exports2.selectIssues = selectIssues;
15988
- exports2.selectLatestFormRevision = selectLatestFormRevision;
16714
+ exports2.selectLatestFormRevisionByForm = selectLatestFormRevisionByForm;
16715
+ exports2.selectLatestFormRevisionOfForm = selectLatestFormRevisionOfForm;
16716
+ exports2.selectLatestFormRevisionsOfComponentTypes = selectLatestFormRevisionsOfComponentTypes;
15989
16717
  exports2.selectLatestRetryTime = selectLatestRetryTime;
15990
- exports2.selectLatestRevisionByFormId = selectLatestRevisionByFormId;
15991
- exports2.selectLatestRevisionsFromComponentTypeIds = selectLatestRevisionsFromComponentTypeIds;
15992
16718
  exports2.selectLicense = selectLicense;
15993
16719
  exports2.selectLicenseForProject = selectLicenseForProject;
15994
16720
  exports2.selectLicenses = selectLicenses;
@@ -15997,8 +16723,6 @@ var __publicField = (obj, key, value) => {
15997
16723
  exports2.selectMapStyle = selectMapStyle;
15998
16724
  exports2.selectNumberOfComponentTypesMatchingCaseInsensitiveName = selectNumberOfComponentTypesMatchingCaseInsensitiveName;
15999
16725
  exports2.selectNumberOfComponentsOfComponentType = selectNumberOfComponentsOfComponentType;
16000
- exports2.selectNumberOfGeneralUserForms = selectNumberOfGeneralUserForms;
16001
- exports2.selectNumberOfUserForms = selectNumberOfUserForms;
16002
16726
  exports2.selectOrganization = selectOrganization;
16003
16727
  exports2.selectOrganizationAccess = selectOrganizationAccess;
16004
16728
  exports2.selectOrganizationAccessForUser = selectOrganizationAccessForUser;
@@ -16015,6 +16739,7 @@ var __publicField = (obj, key, value) => {
16015
16739
  exports2.selectProjectAccessForUser = selectProjectAccessForUser;
16016
16740
  exports2.selectProjectAccessUserMapping = selectProjectAccessUserMapping;
16017
16741
  exports2.selectProjectAccesses = selectProjectAccesses;
16742
+ exports2.selectProjectAttachment = selectProjectAttachment;
16018
16743
  exports2.selectProjectAttachmentMapping = selectProjectAttachmentMapping;
16019
16744
  exports2.selectProjectFileVisibility = selectProjectFileVisibility;
16020
16745
  exports2.selectProjectFiles = selectProjectFiles;
@@ -16026,8 +16751,6 @@ var __publicField = (obj, key, value) => {
16026
16751
  exports2.selectRecentIssuesAsSearchResults = selectRecentIssuesAsSearchResults;
16027
16752
  exports2.selectRecentProjects = selectRecentProjects;
16028
16753
  exports2.selectRehydrated = selectRehydrated;
16029
- exports2.selectRevisionAttachments = selectRevisionAttachments;
16030
- exports2.selectRevisionsForForm = selectRevisionsForForm;
16031
16754
  exports2.selectRootDocuments = selectRootDocuments;
16032
16755
  exports2.selectShowTooltips = selectShowTooltips;
16033
16756
  exports2.selectSortedEmailDomains = selectSortedEmailDomains;
@@ -16042,16 +16765,10 @@ var __publicField = (obj, key, value) => {
16042
16765
  exports2.selectStagesFromComponentType = selectStagesFromComponentType;
16043
16766
  exports2.selectStagesFromComponentTypeIds = selectStagesFromComponentTypeIds;
16044
16767
  exports2.selectStagesFromStageIds = selectStagesFromStageIds;
16045
- exports2.selectSubmissionAttachments = selectSubmissionAttachments;
16046
- exports2.selectSubmissionsForComponent = selectSubmissionsForComponent;
16047
- exports2.selectSubmissionsForForm = selectSubmissionsForForm;
16048
- exports2.selectSubmissionsForIssue = selectSubmissionsForIssue;
16049
16768
  exports2.selectUploadUrl = selectUploadUrl;
16050
16769
  exports2.selectUsedColors = selectUsedColors;
16051
16770
  exports2.selectUser = selectUser;
16052
- exports2.selectUserForm = selectUserForm;
16053
- exports2.selectUserFormMapping = selectUserFormMapping;
16054
- exports2.selectUserFormSubmission = selectUserFormSubmission;
16771
+ exports2.selectUserFormRevisionAttachmentsMapping = selectUserFormRevisionAttachmentsMapping;
16055
16772
  exports2.selectUsersAsMapping = selectUsersAsMapping;
16056
16773
  exports2.selectVisibleStatuses = selectVisibleStatuses;
16057
16774
  exports2.selectVisibleUserIds = selectVisibleUserIds;
@@ -16066,21 +16783,32 @@ var __publicField = (obj, key, value) => {
16066
16783
  exports2.setAppearance = setAppearance;
16067
16784
  exports2.setCategories = setCategories;
16068
16785
  exports2.setCenterMapToProject = setCenterMapToProject;
16786
+ exports2.setComponentAttachment = setComponentAttachment;
16069
16787
  exports2.setComponentAttachments = setComponentAttachments;
16788
+ exports2.setComponentTypeAttachment = setComponentTypeAttachment;
16070
16789
  exports2.setComponentTypeAttachments = setComponentTypeAttachments;
16071
16790
  exports2.setComponentTypes = setComponentTypes;
16072
16791
  exports2.setComponents = setComponents;
16073
16792
  exports2.setCreateProjectType = setCreateProjectType;
16074
16793
  exports2.setCurrentUser = setCurrentUser;
16794
+ exports2.setDocumentAttachment = setDocumentAttachment;
16075
16795
  exports2.setDocumentAttachments = setDocumentAttachments;
16076
16796
  exports2.setDocuments = setDocuments;
16077
16797
  exports2.setEmailDomains = setEmailDomains;
16078
16798
  exports2.setEnableClustering = setEnableClustering;
16079
16799
  exports2.setEnableDuplicateIssues = setEnableDuplicateIssues;
16080
16800
  exports2.setEnablePlacementMode = setEnablePlacementMode;
16801
+ exports2.setFormRevision = setFormRevision;
16802
+ exports2.setFormRevisionAttachments = setFormRevisionAttachments;
16803
+ exports2.setFormRevisions = setFormRevisions;
16804
+ exports2.setFormSubmission = setFormSubmission;
16805
+ exports2.setFormSubmissionAttachments = setFormSubmissionAttachments;
16806
+ exports2.setFormSubmissions = setFormSubmissions;
16807
+ exports2.setForms = setForms;
16081
16808
  exports2.setIsFetchingInitialData = setIsFetchingInitialData;
16082
16809
  exports2.setIsImportingProjectFile = setIsImportingProjectFile;
16083
16810
  exports2.setIsLoading = setIsLoading;
16811
+ exports2.setIssueAttachment = setIssueAttachment;
16084
16812
  exports2.setIssueAttachments = setIssueAttachments;
16085
16813
  exports2.setIssueComment = setIssueComment;
16086
16814
  exports2.setIssueComments = setIssueComments;
@@ -16093,6 +16821,7 @@ var __publicField = (obj, key, value) => {
16093
16821
  exports2.setOrganizations = setOrganizations;
16094
16822
  exports2.setProfilePicture = setProfilePicture;
16095
16823
  exports2.setProjectAccesses = setProjectAccesses;
16824
+ exports2.setProjectAttachment = setProjectAttachment;
16096
16825
  exports2.setProjectAttachments = setProjectAttachments;
16097
16826
  exports2.setProjectFileVisible = setProjectFileVisible;
16098
16827
  exports2.setProjects = setProjects;
@@ -16102,9 +16831,6 @@ var __publicField = (obj, key, value) => {
16102
16831
  exports2.setTokens = setTokens;
16103
16832
  exports2.setTourStep = setTourStep;
16104
16833
  exports2.setUploadUrl = setUploadUrl;
16105
- exports2.setUserFormRevisionAttachments = setUserFormRevisionAttachments;
16106
- exports2.setUserFormSubmissionAttachments = setUserFormSubmissionAttachments;
16107
- exports2.setUserFormSubmissions = setUserFormSubmissions;
16108
16834
  exports2.setUsers = setUsers;
16109
16835
  exports2.setVisibleStatuses = setVisibleStatuses;
16110
16836
  exports2.setVisibleUserIds = setVisibleUserIds;
@@ -16126,17 +16852,24 @@ var __publicField = (obj, key, value) => {
16126
16852
  exports2.updateActiveOrganization = updateActiveOrganization;
16127
16853
  exports2.updateComponent = updateComponent;
16128
16854
  exports2.updateComponentAttachment = updateComponentAttachment;
16855
+ exports2.updateComponentAttachments = updateComponentAttachments;
16129
16856
  exports2.updateComponentTypeAttachment = updateComponentTypeAttachment;
16857
+ exports2.updateComponentTypeAttachments = updateComponentTypeAttachments;
16130
16858
  exports2.updateDocumentAttachment = updateDocumentAttachment;
16859
+ exports2.updateDocumentAttachments = updateDocumentAttachments;
16131
16860
  exports2.updateDocuments = updateDocuments;
16861
+ exports2.updateFormSubmission = updateFormSubmission;
16862
+ exports2.updateFormSubmissionAttachments = updateFormSubmissionAttachments;
16863
+ exports2.updateFormSubmissions = updateFormSubmissions;
16132
16864
  exports2.updateIssue = updateIssue;
16133
16865
  exports2.updateIssueAttachment = updateIssueAttachment;
16866
+ exports2.updateIssueAttachments = updateIssueAttachments;
16134
16867
  exports2.updateLicense = updateLicense;
16135
16868
  exports2.updateOrCreateProject = updateOrCreateProject;
16136
- exports2.updateOrCreateUserFormSubmission = updateOrCreateUserFormSubmission;
16137
16869
  exports2.updateOrganizationAccess = updateOrganizationAccess;
16138
16870
  exports2.updateProjectAccess = updateProjectAccess;
16139
16871
  exports2.updateProjectAttachment = updateProjectAttachment;
16872
+ exports2.updateProjectAttachments = updateProjectAttachments;
16140
16873
  exports2.updateStages = updateStages;
16141
16874
  exports2.useAppDispatch = useAppDispatch;
16142
16875
  exports2.useAppSelector = useAppSelector;
@@ -16147,8 +16880,6 @@ var __publicField = (obj, key, value) => {
16147
16880
  exports2.useFormikInput = useFormikInput;
16148
16881
  exports2.useMemoCompare = useMemoCompare;
16149
16882
  exports2.useSDK = useSDK;
16150
- exports2.userFormReducer = userFormReducer;
16151
- exports2.userFormSlice = userFormSlice;
16152
16883
  exports2.userReducer = userReducer;
16153
16884
  exports2.userSlice = userSlice;
16154
16885
  exports2.valueIsFile = valueIsFile;