@overmap-ai/core 1.0.48-add-agent-response-rating.2 → 1.0.48-bulk-form-submission.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/README.md +4 -4
  2. package/dist/components/ImageCard/ImageCard.d.ts +1 -1
  3. package/dist/forms/builder/hooks.d.ts +2 -1
  4. package/dist/forms/renderer/FormSubmissionBrowser/FormSubmissionBrowser.d.ts +5 -5
  5. package/dist/forms/renderer/FormSubmissionViewer/FormSubmissionViewer.d.ts +3 -3
  6. package/dist/overmap-core.js +1017 -532
  7. package/dist/overmap-core.js.map +1 -1
  8. package/dist/overmap-core.umd.cjs +1016 -531
  9. package/dist/overmap-core.umd.cjs.map +1 -1
  10. package/dist/sdk/sdk.d.ts +2 -1
  11. package/dist/sdk/services/IssueCommentService.d.ts +2 -2
  12. package/dist/sdk/services/IssueUpdateService.d.ts +4 -0
  13. package/dist/sdk/services/UserFormSubmissionService.d.ts +9 -2
  14. package/dist/sdk/services/index.d.ts +1 -0
  15. package/dist/store/slices/categorySlice.d.ts +3 -1
  16. package/dist/store/slices/componentSlice.d.ts +1 -0
  17. package/dist/store/slices/componentStageSlice.d.ts +2 -0
  18. package/dist/store/slices/documentSlice.d.ts +3 -1
  19. package/dist/store/slices/formRevisionSlice.d.ts +73 -0
  20. package/dist/store/slices/formSubmissionSlice.d.ts +46 -0
  21. package/dist/store/slices/index.d.ts +2 -0
  22. package/dist/store/slices/issueSlice.d.ts +24 -4
  23. package/dist/store/slices/projectFileSlice.d.ts +3 -1
  24. package/dist/store/slices/userFormSlice.d.ts +38 -63
  25. package/dist/store/slices/workspaceSlice.d.ts +3 -1
  26. package/dist/store/store.d.ts +10 -4
  27. package/dist/typings/models/access.d.ts +1 -1
  28. package/dist/typings/models/attachments.d.ts +3 -1
  29. package/dist/typings/models/base.d.ts +7 -0
  30. package/dist/typings/models/forms.d.ts +3 -6
  31. package/dist/typings/models/issues.d.ts +35 -1
  32. package/package.json +152 -152
@@ -622,15 +622,15 @@ var __publicField = (obj, key, value) => {
622
622
  };
623
623
  const migrations = [initialVersioning, signOut, signOut, createOutboxState];
624
624
  const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
625
- const initialState$n = {
625
+ const initialState$p = {
626
626
  accessToken: "",
627
627
  refreshToken: "",
628
628
  isLoggedIn: false
629
629
  };
630
630
  const authSlice = toolkit.createSlice({
631
631
  name: "auth",
632
- initialState: initialState$n,
633
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
632
+ initialState: initialState$p,
633
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$p)),
634
634
  reducers: {
635
635
  setTokens: (state, action) => {
636
636
  state.accessToken = action.payload.accessToken;
@@ -1361,7 +1361,7 @@ var __publicField = (obj, key, value) => {
1361
1361
  return getLocalDateString(date);
1362
1362
  return relative.format(days, "days");
1363
1363
  });
1364
- const initialState$m = {
1364
+ const initialState$o = {
1365
1365
  categories: {},
1366
1366
  usedCategoryColors: [],
1367
1367
  categoryVisibility: {
@@ -1371,8 +1371,8 @@ var __publicField = (obj, key, value) => {
1371
1371
  };
1372
1372
  const categorySlice = toolkit.createSlice({
1373
1373
  name: "categories",
1374
- initialState: initialState$m,
1375
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1374
+ initialState: initialState$o,
1375
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$o)),
1376
1376
  reducers: {
1377
1377
  setCategories: (state, action) => {
1378
1378
  if (!Array.isArray(action.payload))
@@ -1540,14 +1540,14 @@ var __publicField = (obj, key, value) => {
1540
1540
  delete state.attachments[attachmentId];
1541
1541
  }
1542
1542
  }
1543
- const initialState$l = {
1543
+ const initialState$n = {
1544
1544
  components: {},
1545
1545
  attachments: {}
1546
1546
  };
1547
1547
  const componentSlice = toolkit.createSlice({
1548
1548
  name: "components",
1549
- initialState: initialState$l,
1550
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1549
+ initialState: initialState$n,
1550
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
1551
1551
  reducers: {
1552
1552
  addComponent: (state, action) => {
1553
1553
  state.components[action.payload.offline_id] = action.payload;
@@ -1601,6 +1601,7 @@ var __publicField = (obj, key, value) => {
1601
1601
  }
1602
1602
  return prevComponents;
1603
1603
  };
1604
+ const selectComponentsMapping = (state) => state.componentReducer.components;
1604
1605
  const selectComponentsFromComponentType = (componentTypeId) => (state) => {
1605
1606
  if (!componentTypeId)
1606
1607
  return [];
@@ -1631,16 +1632,14 @@ var __publicField = (obj, key, value) => {
1631
1632
  }
1632
1633
  return ret;
1633
1634
  };
1634
- const selectComponentsByType = (componentTypeId) => (state) => {
1635
- const components = state.componentReducer.components;
1636
- const componentsOfType = [];
1637
- for (const component of Object.values(components)) {
1638
- if (component.component_type === componentTypeId) {
1639
- componentsOfType.push(component);
1635
+ const selectComponentsByType = restructureCreateSelectorWithArgs(
1636
+ toolkit.createSelector(
1637
+ [selectComponents, (_state, componentTypeId) => componentTypeId],
1638
+ (components, componentTypeId) => {
1639
+ return components.filter((component) => component.component_type === componentTypeId);
1640
1640
  }
1641
- }
1642
- return componentsOfType;
1643
- };
1641
+ )
1642
+ );
1644
1643
  const selectNumberOfComponentsOfComponentType = (componentTypeId) => (state) => {
1645
1644
  var _a2;
1646
1645
  if (!componentTypeId)
@@ -1701,13 +1700,13 @@ var __publicField = (obj, key, value) => {
1701
1700
  removeAllComponentsOfType
1702
1701
  } = componentSlice.actions;
1703
1702
  const componentReducer = componentSlice.reducer;
1704
- const initialState$k = {
1703
+ const initialState$m = {
1705
1704
  completionsByComponentId: {}
1706
1705
  };
1707
1706
  const componentStageCompletionSlice = toolkit.createSlice({
1708
1707
  name: "componentStageCompletions",
1709
- initialState: initialState$k,
1710
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1708
+ initialState: initialState$m,
1709
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1711
1710
  reducers: {
1712
1711
  addStageCompletion: (state, action) => {
1713
1712
  let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
@@ -1758,13 +1757,13 @@ var __publicField = (obj, key, value) => {
1758
1757
  return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
1759
1758
  };
1760
1759
  const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
1761
- const initialState$j = {
1760
+ const initialState$l = {
1762
1761
  stages: {}
1763
1762
  };
1764
1763
  const componentStageSlice = toolkit.createSlice({
1765
1764
  name: "componentStages",
1766
- initialState: initialState$j,
1767
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1765
+ initialState: initialState$l,
1766
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1768
1767
  reducers: {
1769
1768
  addStages: (state, action) => {
1770
1769
  Object.assign(state.stages, toOfflineIdRecord(action.payload));
@@ -1798,6 +1797,11 @@ var __publicField = (obj, key, value) => {
1798
1797
  }
1799
1798
  });
1800
1799
  const selectStageMapping = (state) => state.componentStageReducer.stages;
1800
+ const selectStage = restructureCreateSelectorWithArgs(
1801
+ toolkit.createSelector([selectStageMapping, (_state, stageId) => stageId], (stageMapping, stageId) => {
1802
+ return stageMapping[stageId];
1803
+ })
1804
+ );
1801
1805
  const selectStages = toolkit.createSelector(
1802
1806
  [selectStageMapping],
1803
1807
  (stageMapping) => {
@@ -1825,6 +1829,20 @@ var __publicField = (obj, key, value) => {
1825
1829
  }
1826
1830
  )
1827
1831
  );
1832
+ const selectComponentTypeStagesMapping = restructureCreateSelectorWithArgs(
1833
+ toolkit.createSelector(
1834
+ [selectStageMapping, (_state, componentTypeId) => componentTypeId],
1835
+ (stagesMapping, componentTypeId) => {
1836
+ const componentTypeStagesMapping = {};
1837
+ for (const [stageId, stage] of Object.entries(stagesMapping)) {
1838
+ if (stage.component_type === componentTypeId) {
1839
+ componentTypeStagesMapping[stageId] = stage;
1840
+ }
1841
+ }
1842
+ return componentTypeStagesMapping;
1843
+ }
1844
+ )
1845
+ );
1828
1846
  const selectStagesFromComponentType = restructureCreateSelectorWithArgs(
1829
1847
  toolkit.createSelector(
1830
1848
  [selectStages, (_state, componentTypeId) => componentTypeId],
@@ -1855,15 +1873,15 @@ var __publicField = (obj, key, value) => {
1855
1873
  );
1856
1874
  const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
1857
1875
  const componentStageReducer = componentStageSlice.reducer;
1858
- const initialState$i = {
1876
+ const initialState$k = {
1859
1877
  componentTypes: {},
1860
1878
  hiddenComponentTypeIds: {},
1861
1879
  attachments: {}
1862
1880
  };
1863
1881
  const componentTypeSlice = toolkit.createSlice({
1864
1882
  name: "componentTypes",
1865
- initialState: initialState$i,
1866
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1883
+ initialState: initialState$k,
1884
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1867
1885
  reducers: {
1868
1886
  addComponentType: (state, action) => {
1869
1887
  state.componentTypes[action.payload.offline_id] = action.payload;
@@ -1971,13 +1989,13 @@ var __publicField = (obj, key, value) => {
1971
1989
  deleteComponentType
1972
1990
  } = componentTypeSlice.actions;
1973
1991
  const componentTypeReducer = componentTypeSlice.reducer;
1974
- const initialState$h = {
1992
+ const initialState$j = {
1975
1993
  workspaces: {},
1976
1994
  activeWorkspaceId: null
1977
1995
  };
1978
1996
  const workspaceSlice = toolkit.createSlice({
1979
1997
  name: "workspace",
1980
- initialState: initialState$h,
1998
+ initialState: initialState$j,
1981
1999
  // The `reducers` field lets us define reducers and generate associated actions
1982
2000
  reducers: {
1983
2001
  setWorkspaces: (state, action) => {
@@ -2034,10 +2052,11 @@ var __publicField = (obj, key, value) => {
2034
2052
  );
2035
2053
  const workspaceReducer = workspaceSlice.reducer;
2036
2054
  const maxRecentIssues = 10;
2037
- const initialState$g = {
2055
+ const initialState$i = {
2038
2056
  issues: {},
2039
2057
  attachments: {},
2040
2058
  comments: {},
2059
+ updates: {},
2041
2060
  visibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],
2042
2061
  visibleUserIds: null,
2043
2062
  recentIssueIds: [],
@@ -2045,9 +2064,9 @@ var __publicField = (obj, key, value) => {
2045
2064
  };
2046
2065
  const issueSlice = toolkit.createSlice({
2047
2066
  name: "issues",
2048
- initialState: initialState$g,
2067
+ initialState: initialState$i,
2049
2068
  extraReducers: (builder) => builder.addCase("RESET", (state) => {
2050
- Object.assign(state, initialState$g);
2069
+ Object.assign(state, initialState$i);
2051
2070
  }),
2052
2071
  reducers: {
2053
2072
  setIssues: (state, action) => {
@@ -2059,6 +2078,16 @@ var __publicField = (obj, key, value) => {
2059
2078
  });
2060
2079
  },
2061
2080
  setIssueAttachments: setAttachments,
2081
+ setIssueUpdates: (state, action) => {
2082
+ if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2083
+ throw new Error("Tried to use setIssues reducer with duplicate ID's");
2084
+ }
2085
+ const newUpdates = {};
2086
+ for (const update of action.payload) {
2087
+ newUpdates[update.offline_id] = update;
2088
+ }
2089
+ state.updates = newUpdates;
2090
+ },
2062
2091
  setActiveIssueId: (state, action) => {
2063
2092
  state.activeIssueId = action.payload;
2064
2093
  },
@@ -2070,6 +2099,17 @@ var __publicField = (obj, key, value) => {
2070
2099
  },
2071
2100
  addIssueAttachment: addAttachment,
2072
2101
  addIssueAttachments: addAttachments,
2102
+ addIssueUpdate: (state, action) => {
2103
+ if (action.payload.offline_id in state.updates) {
2104
+ throw new Error(`Tried to add duplicate issue update with offline_id: ${action.payload.offline_id}`);
2105
+ }
2106
+ state.updates[action.payload.offline_id] = action.payload;
2107
+ },
2108
+ addIssueUpdates: (state, action) => {
2109
+ for (const update of action.payload) {
2110
+ state.updates[update.offline_id] = update;
2111
+ }
2112
+ },
2073
2113
  updateIssue: (state, action) => {
2074
2114
  if (action.payload.offline_id in state.issues) {
2075
2115
  state.issues[action.payload.offline_id] = {
@@ -2089,6 +2129,18 @@ var __publicField = (obj, key, value) => {
2089
2129
  }
2090
2130
  },
2091
2131
  removeIssueAttachment: removeAttachment,
2132
+ removeIssueUpdate: (state, action) => {
2133
+ if (action.payload in state.updates) {
2134
+ delete state.updates[action.payload];
2135
+ } else {
2136
+ throw new Error(`Failed to remove issue update because offline_id doesn't exist: ${action.payload}`);
2137
+ }
2138
+ },
2139
+ removeIssueUpdates: (state, action) => {
2140
+ for (const updateId of action.payload) {
2141
+ delete state.updates[updateId];
2142
+ }
2143
+ },
2092
2144
  removeAttachmentsOfIssue: (state, action) => {
2093
2145
  const attachments = Object.values(state.attachments).filter((a) => a.issue === action.payload);
2094
2146
  for (const attachment of attachments) {
@@ -2101,20 +2153,55 @@ var __publicField = (obj, key, value) => {
2101
2153
  setVisibleUserIds: (state, action) => {
2102
2154
  state.visibleUserIds = [...new Set(action.payload)];
2103
2155
  },
2104
- setIssueComments: (state, action) => {
2156
+ // Comments
2157
+ addIssueComment: (state, action) => {
2158
+ if (action.payload.offline_id in state.comments) {
2159
+ throw new Error(
2160
+ `Tried to add issue comment with offline_id: ${action.payload.offline_id} that already exists`
2161
+ );
2162
+ }
2163
+ state.comments[action.payload.offline_id] = action.payload;
2164
+ },
2165
+ addIssueComments: (state, action) => {
2166
+ for (const comment of action.payload) {
2167
+ if (comment.offline_id in state.comments) {
2168
+ throw new Error(
2169
+ `Tried to add issue comment with offline_id: ${comment.offline_id} that already exists`
2170
+ );
2171
+ }
2172
+ }
2105
2173
  for (const comment of action.payload) {
2106
2174
  state.comments[comment.offline_id] = comment;
2107
2175
  }
2108
2176
  },
2177
+ setIssueComment: (state, action) => {
2178
+ state.comments[action.payload.offline_id] = action.payload;
2179
+ },
2180
+ setIssueComments: (state, action) => {
2181
+ const newComments = {};
2182
+ for (const comment of action.payload) {
2183
+ newComments[comment.offline_id] = comment;
2184
+ }
2185
+ state.comments = newComments;
2186
+ },
2109
2187
  addOrReplaceIssueComment: (state, action) => {
2110
2188
  state.comments[action.payload.offline_id] = action.payload;
2111
2189
  },
2112
2190
  removeIssueComment: (state, action) => {
2113
- if (action.payload in state.comments) {
2114
- delete state.comments[action.payload];
2115
- } else {
2191
+ if (!(action.payload in state.comments)) {
2116
2192
  throw new Error(`Failed to remove issue comment because ID doesn't exist: ${action.payload}`);
2117
2193
  }
2194
+ delete state.comments[action.payload];
2195
+ },
2196
+ removeIssueComments: (state, action) => {
2197
+ for (const commentId of action.payload) {
2198
+ if (!(commentId in state.comments)) {
2199
+ throw new Error(`Failed to remove issue comment because ID doesn't exist: ${commentId}`);
2200
+ }
2201
+ }
2202
+ for (const commentId of action.payload) {
2203
+ delete state.comments[commentId];
2204
+ }
2118
2205
  },
2119
2206
  cleanRecentIssues: (state) => {
2120
2207
  state.recentIssueIds = state.recentIssueIds.filter((recentIssue) => state.issues[recentIssue.offlineId]);
@@ -2145,23 +2232,33 @@ var __publicField = (obj, key, value) => {
2145
2232
  addIssueAttachment,
2146
2233
  addIssueAttachments,
2147
2234
  addIssue,
2235
+ addIssueUpdate,
2236
+ addIssueUpdates,
2148
2237
  addOrReplaceIssueComment,
2149
2238
  addToRecentIssues,
2150
2239
  cleanRecentIssues,
2151
2240
  removeIssueAttachment,
2152
2241
  removeAttachmentsOfIssue,
2153
2242
  removeIssue,
2154
- removeIssueComment,
2243
+ removeIssueUpdate,
2244
+ removeIssueUpdates,
2155
2245
  removeRecentIssue,
2156
2246
  resetRecentIssues,
2157
2247
  setActiveIssueId,
2158
2248
  setIssueAttachments,
2159
- setIssueComments,
2249
+ setIssueUpdates,
2160
2250
  setIssues,
2161
2251
  setVisibleStatuses,
2162
2252
  setVisibleUserIds,
2163
2253
  updateIssueAttachment,
2164
- updateIssue
2254
+ updateIssue,
2255
+ // Commments
2256
+ addIssueComment,
2257
+ addIssueComments,
2258
+ setIssueComment,
2259
+ setIssueComments,
2260
+ removeIssueComment,
2261
+ removeIssueComments
2165
2262
  } = issueSlice.actions;
2166
2263
  const selectIssueMapping = (state) => state.issueReducer.issues;
2167
2264
  const selectRecentIssueIds = (state) => state.issueReducer.recentIssueIds;
@@ -2232,6 +2329,12 @@ var __publicField = (obj, key, value) => {
2232
2329
  return Object.values(commentMapping).filter((comment) => comment.issue === issueId);
2233
2330
  })
2234
2331
  );
2332
+ const selectIssueUpdateMapping = (state) => state.issueReducer.updates;
2333
+ const selectIssueUpdatesOfIssue = restructureCreateSelectorWithArgs(
2334
+ toolkit.createSelector([selectIssueUpdateMapping, (_state, issueId) => issueId], (updates, issueId) => {
2335
+ return Object.values(updates).filter((update) => update.issue === issueId);
2336
+ })
2337
+ );
2235
2338
  const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(
2236
2339
  toolkit.createSelector(
2237
2340
  [selectIssueAttachments, (_state, issueId) => issueId],
@@ -2368,15 +2471,15 @@ var __publicField = (obj, key, value) => {
2368
2471
  }
2369
2472
  );
2370
2473
  const issueReducer = issueSlice.reducer;
2371
- const initialState$f = {
2474
+ const initialState$h = {
2372
2475
  s3Urls: {}
2373
2476
  };
2374
2477
  const msPerHour = 1e3 * 60 * 60;
2375
2478
  const msPerWeek = msPerHour * 24 * 7;
2376
2479
  const fileSlice = toolkit.createSlice({
2377
2480
  name: "file",
2378
- initialState: initialState$f,
2379
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2481
+ initialState: initialState$h,
2482
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
2380
2483
  reducers: {
2381
2484
  setUploadUrl: (state, action) => {
2382
2485
  const { url, fields, sha1 } = action.payload;
@@ -2403,7 +2506,7 @@ var __publicField = (obj, key, value) => {
2403
2506
  return url;
2404
2507
  };
2405
2508
  const fileReducer = fileSlice.reducer;
2406
- const initialState$e = {
2509
+ const initialState$g = {
2407
2510
  // TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
2408
2511
  mapStyle: MapStyle.SATELLITE,
2409
2512
  showTooltips: false,
@@ -2411,8 +2514,8 @@ var __publicField = (obj, key, value) => {
2411
2514
  };
2412
2515
  const mapSlice = toolkit.createSlice({
2413
2516
  name: "map",
2414
- initialState: initialState$e,
2415
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2517
+ initialState: initialState$g,
2518
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
2416
2519
  reducers: {
2417
2520
  setMapStyle: (state, action) => {
2418
2521
  state.mapStyle = action.payload;
@@ -2440,6 +2543,16 @@ var __publicField = (obj, key, value) => {
2440
2543
  OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
2441
2544
  return OrganizationAccessLevel2;
2442
2545
  })(OrganizationAccessLevel || {});
2546
+ var IssueUpdateChange = /* @__PURE__ */ ((IssueUpdateChange2) => {
2547
+ IssueUpdateChange2["STATUS"] = "status";
2548
+ IssueUpdateChange2["PRIORITY"] = "priority";
2549
+ IssueUpdateChange2["CATEGORY"] = "category";
2550
+ IssueUpdateChange2["DESCRIPTION"] = "description";
2551
+ IssueUpdateChange2["TITLE"] = "title";
2552
+ IssueUpdateChange2["ASSIGNED_TO"] = "assigned_to";
2553
+ IssueUpdateChange2["DUE_DATE"] = "due_date";
2554
+ return IssueUpdateChange2;
2555
+ })(IssueUpdateChange || {});
2443
2556
  var ProjectType = /* @__PURE__ */ ((ProjectType2) => {
2444
2557
  ProjectType2[ProjectType2["PERSONAL"] = 0] = "PERSONAL";
2445
2558
  ProjectType2[ProjectType2["ORGANIZATION"] = 2] = "ORGANIZATION";
@@ -2471,7 +2584,7 @@ var __publicField = (obj, key, value) => {
2471
2584
  LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
2472
2585
  return LicenseStatus2;
2473
2586
  })(LicenseStatus || {});
2474
- const initialState$d = {
2587
+ const initialState$f = {
2475
2588
  users: {},
2476
2589
  currentUser: {
2477
2590
  id: 0,
@@ -2482,8 +2595,8 @@ var __publicField = (obj, key, value) => {
2482
2595
  };
2483
2596
  const userSlice = toolkit.createSlice({
2484
2597
  name: "users",
2485
- initialState: initialState$d,
2486
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2598
+ initialState: initialState$f,
2599
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2487
2600
  reducers: {
2488
2601
  setUsers: (state, action) => {
2489
2602
  const usersMapping = {};
@@ -2545,13 +2658,13 @@ var __publicField = (obj, key, value) => {
2545
2658
  const selectUsersAsMapping = (state) => state.userReducer.users;
2546
2659
  const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
2547
2660
  const userReducer = userSlice.reducer;
2548
- const initialState$c = {
2661
+ const initialState$e = {
2549
2662
  organizationAccesses: {}
2550
2663
  };
2551
2664
  const organizationAccessSlice = toolkit.createSlice({
2552
2665
  name: "organizationAccess",
2553
- initialState: initialState$c,
2554
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2666
+ initialState: initialState$e,
2667
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2555
2668
  reducers: {
2556
2669
  setOrganizationAccesses: (state, action) => {
2557
2670
  if (!Array.isArray(action.payload))
@@ -2614,13 +2727,13 @@ var __publicField = (obj, key, value) => {
2614
2727
  return organizationAccesses;
2615
2728
  };
2616
2729
  const organizationAccessReducer = organizationAccessSlice.reducer;
2617
- const initialState$b = {
2730
+ const initialState$d = {
2618
2731
  licenses: {}
2619
2732
  };
2620
2733
  const licenseSlice = toolkit.createSlice({
2621
2734
  name: "license",
2622
- initialState: initialState$b,
2623
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2735
+ initialState: initialState$d,
2736
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2624
2737
  reducers: {
2625
2738
  setLicenses: (state, action) => {
2626
2739
  if (!Array.isArray(action.payload))
@@ -2665,13 +2778,13 @@ var __publicField = (obj, key, value) => {
2665
2778
  (licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
2666
2779
  );
2667
2780
  const licenseReducer = licenseSlice.reducer;
2668
- const initialState$a = {
2781
+ const initialState$c = {
2669
2782
  projectAccesses: {}
2670
2783
  };
2671
2784
  const projectAccessSlice = toolkit.createSlice({
2672
2785
  name: "projectAccess",
2673
- initialState: initialState$a,
2674
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2786
+ initialState: initialState$c,
2787
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2675
2788
  reducers: {
2676
2789
  setProjectAccesses: (state, action) => {
2677
2790
  if (!Array.isArray(action.payload))
@@ -2739,7 +2852,7 @@ var __publicField = (obj, key, value) => {
2739
2852
  return projectAccesses;
2740
2853
  };
2741
2854
  const projectAccessReducer = projectAccessSlice.reducer;
2742
- const initialState$9 = {
2855
+ const initialState$b = {
2743
2856
  projects: {},
2744
2857
  activeProjectId: null,
2745
2858
  recentProjectIds: [],
@@ -2749,7 +2862,7 @@ var __publicField = (obj, key, value) => {
2749
2862
  };
2750
2863
  const projectSlice = toolkit.createSlice({
2751
2864
  name: "projects",
2752
- initialState: initialState$9,
2865
+ initialState: initialState$b,
2753
2866
  reducers: {
2754
2867
  setProjects: (state, action) => {
2755
2868
  const projectsMap = {};
@@ -2936,14 +3049,14 @@ var __publicField = (obj, key, value) => {
2936
3049
  }
2937
3050
  )
2938
3051
  );
2939
- const initialState$8 = {
3052
+ const initialState$a = {
2940
3053
  organizations: {},
2941
3054
  activeOrganizationId: null
2942
3055
  };
2943
3056
  const organizationSlice = toolkit.createSlice({
2944
3057
  name: "organizations",
2945
- initialState: initialState$8,
2946
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3058
+ initialState: initialState$a,
3059
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2947
3060
  reducers: {
2948
3061
  setOrganizations: (state, action) => {
2949
3062
  for (const org of action.payload) {
@@ -3062,14 +3175,14 @@ var __publicField = (obj, key, value) => {
3062
3175
  }
3063
3176
  };
3064
3177
  };
3065
- const initialState$7 = {
3178
+ const initialState$9 = {
3066
3179
  deletedRequests: [],
3067
3180
  latestRetryTime: 0
3068
3181
  };
3069
3182
  const outboxSlice = toolkit.createSlice({
3070
3183
  name: "outbox",
3071
- initialState: initialState$7,
3072
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
3184
+ initialState: initialState$9,
3185
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
3073
3186
  reducers: {
3074
3187
  // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
3075
3188
  // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
@@ -3101,7 +3214,7 @@ var __publicField = (obj, key, value) => {
3101
3214
  const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
3102
3215
  const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
3103
3216
  const outboxReducer = outboxSlice.reducer;
3104
- const initialState$6 = {
3217
+ const initialState$8 = {
3105
3218
  projectFiles: {},
3106
3219
  activeProjectFileId: null,
3107
3220
  isImportingProjectFile: false,
@@ -3109,8 +3222,8 @@ var __publicField = (obj, key, value) => {
3109
3222
  };
3110
3223
  const projectFileSlice = toolkit.createSlice({
3111
3224
  name: "projectFiles",
3112
- initialState: initialState$6,
3113
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
3225
+ initialState: initialState$8,
3226
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3114
3227
  reducers: {
3115
3228
  addOrReplaceProjectFiles: (state, action) => {
3116
3229
  for (let fileObj of action.payload) {
@@ -3211,12 +3324,12 @@ var __publicField = (obj, key, value) => {
3211
3324
  const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
3212
3325
  const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
3213
3326
  const projectFileReducer = projectFileSlice.reducer;
3214
- const initialState$5 = {
3327
+ const initialState$7 = {
3215
3328
  isRehydrated: false
3216
3329
  };
3217
3330
  const rehydratedSlice = toolkit.createSlice({
3218
3331
  name: "rehydrated",
3219
- initialState: initialState$5,
3332
+ initialState: initialState$7,
3220
3333
  // The `reducers` field lets us define reducers and generate associated actions
3221
3334
  reducers: {
3222
3335
  setRehydrated: (state, action) => {
@@ -3226,7 +3339,7 @@ var __publicField = (obj, key, value) => {
3226
3339
  });
3227
3340
  const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
3228
3341
  const rehydratedReducer = rehydratedSlice.reducer;
3229
- const initialState$4 = {
3342
+ const initialState$6 = {
3230
3343
  useIssueTemplate: false,
3231
3344
  placementMode: false,
3232
3345
  enableClustering: false,
@@ -3243,8 +3356,8 @@ var __publicField = (obj, key, value) => {
3243
3356
  };
3244
3357
  const settingSlice = toolkit.createSlice({
3245
3358
  name: "settings",
3246
- initialState: initialState$4,
3247
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3359
+ initialState: initialState$6,
3360
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
3248
3361
  reducers: {
3249
3362
  setEnableDuplicateIssues: (state, action) => {
3250
3363
  state.useIssueTemplate = action.payload;
@@ -3290,146 +3403,248 @@ var __publicField = (obj, key, value) => {
3290
3403
  const settingReducer = settingSlice.reducer;
3291
3404
  const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
3292
3405
  const selectIsLoading = (state) => state.settingReducer.isLoading;
3293
- const LATEST_REVISION_CACHE = {};
3294
- function considerCachingRevision(revision, formId2, preferPending = false) {
3406
+ const LATEST_FORM_REVISION_CACHE = {};
3407
+ function considerCachingFormRevision(formRevision, formId2, preferPending = false) {
3295
3408
  var _a2;
3296
- if (!revision) {
3409
+ if (!formRevision) {
3297
3410
  if (!formId2) {
3298
- throw new Error("If revision is null, formId is required.");
3411
+ throw new Error("If form revision is null, formId is required.");
3299
3412
  }
3300
- const currentLatestRevision = getLatestRevisionFromCache(formId2);
3301
- if (currentLatestRevision)
3413
+ const currentLatestFormRevision = getLatestFormRevisionFromCache(formId2);
3414
+ if (currentLatestFormRevision)
3302
3415
  return;
3303
- LATEST_REVISION_CACHE[formId2] = null;
3416
+ LATEST_FORM_REVISION_CACHE[formId2] = null;
3304
3417
  return;
3305
3418
  }
3306
- if (revision.revision === "Pending") {
3419
+ if (formRevision.revision === "Pending") {
3307
3420
  if (preferPending) {
3308
- LATEST_REVISION_CACHE[revision.form] = revision;
3421
+ LATEST_FORM_REVISION_CACHE[formRevision.form] = formRevision;
3309
3422
  }
3310
3423
  return;
3311
3424
  }
3312
- const cachedRevision = (_a2 = LATEST_REVISION_CACHE[revision.form]) == null ? void 0 : _a2.revision;
3313
- if (revision.revision > (typeof cachedRevision === "number" ? cachedRevision : -1)) {
3314
- LATEST_REVISION_CACHE[revision.form] = revision;
3425
+ const cachedFormRevision = (_a2 = LATEST_FORM_REVISION_CACHE[formRevision.form]) == null ? void 0 : _a2.revision;
3426
+ if (formRevision.revision > (typeof cachedFormRevision === "number" ? cachedFormRevision : -1)) {
3427
+ LATEST_FORM_REVISION_CACHE[formRevision.form] = formRevision;
3315
3428
  }
3316
3429
  }
3317
- function getLatestRevisionFromCache(formId2) {
3318
- return LATEST_REVISION_CACHE[formId2];
3430
+ function getLatestFormRevisionFromCache(formId2) {
3431
+ return LATEST_FORM_REVISION_CACHE[formId2];
3319
3432
  }
3320
- const initialState$3 = {
3321
- userForms: {},
3322
- revisions: {},
3323
- submissions: {},
3324
- submissionAttachments: {},
3325
- revisionAttachments: {}
3433
+ const initialState$5 = {
3434
+ formRevisions: {},
3435
+ attachments: {}
3326
3436
  };
3327
- const userFormSlice = toolkit.createSlice({
3328
- name: "userForms",
3329
- initialState: initialState$3,
3330
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
3437
+ const formRevisionsSlice = toolkit.createSlice({
3438
+ name: "formRevisions",
3439
+ initialState: initialState$5,
3440
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$5)),
3331
3441
  reducers: {
3332
- setUserForms: (state, action) => {
3333
- state.userForms = {};
3334
- action.payload.forEach((userForm) => {
3335
- state.userForms[userForm.offline_id] = userForm;
3336
- });
3337
- },
3338
- addUserForm: (state, action) => {
3339
- state.userForms[action.payload.offline_id] = action.payload;
3340
- },
3341
- addUserForms: (state, action) => {
3342
- action.payload.forEach((userForm) => {
3343
- state.userForms[userForm.offline_id] = userForm;
3344
- });
3345
- },
3346
- addUserFormRevisions: (state, action) => {
3347
- action.payload.forEach((userFormRevision) => {
3348
- state.revisions[userFormRevision.offline_id] = userFormRevision;
3349
- considerCachingRevision(userFormRevision);
3350
- });
3442
+ // revision related actions
3443
+ setFormRevision: (state, action) => {
3444
+ state.formRevisions[action.payload.offline_id] = action.payload;
3445
+ considerCachingFormRevision(action.payload);
3351
3446
  },
3352
- addUserFormRevision: (state, action) => {
3353
- state.revisions[action.payload.offline_id] = action.payload;
3354
- considerCachingRevision(action.payload);
3447
+ setFormRevisions: (state, action) => {
3448
+ state.formRevisions = {};
3449
+ for (const revision of action.payload) {
3450
+ state.formRevisions[revision.offline_id] = revision;
3451
+ considerCachingFormRevision(revision);
3452
+ }
3355
3453
  },
3356
- deleteUserFormRevision: (state, action) => {
3357
- delete state.revisions[action.payload];
3358
- delete LATEST_REVISION_CACHE[action.payload];
3454
+ addFormRevision: (state, action) => {
3455
+ if (state.formRevisions[action.payload.offline_id] !== void 0) {
3456
+ throw new Error(`Revision with offline_id ${action.payload.offline_id} already exists`);
3457
+ }
3458
+ state.formRevisions[action.payload.offline_id] = action.payload;
3459
+ considerCachingFormRevision(action.payload);
3359
3460
  },
3360
- deleteUserFormRevisions: (state, action) => {
3461
+ // TODO: @Audiopolis / Magnus - do we want to standardize using PayloadAction?
3462
+ addFormRevisions: (state, action) => {
3361
3463
  for (const userFormRevision of action.payload) {
3362
- delete state.revisions[userFormRevision.offline_id];
3363
- delete LATEST_REVISION_CACHE[userFormRevision.offline_id];
3464
+ if (state.formRevisions[userFormRevision.offline_id] !== void 0) {
3465
+ throw new Error(`Revision with offline_id ${userFormRevision.offline_id} already exists`);
3466
+ }
3467
+ }
3468
+ for (const userFormRevision of action.payload) {
3469
+ state.formRevisions[userFormRevision.offline_id] = userFormRevision;
3470
+ considerCachingFormRevision(userFormRevision);
3364
3471
  }
3365
3472
  },
3366
- updateOrCreateUserFormSubmission: (state, action) => {
3367
- state.submissions[action.payload.offline_id] = action.payload;
3368
- },
3369
- addUserFormSubmissionAttachment: (state, action) => {
3370
- const submissionId = action.payload.submission;
3371
- const submissionAttachments = state.submissionAttachments[submissionId];
3372
- if (submissionAttachments) {
3373
- submissionAttachments.push(action.payload);
3374
- } else {
3375
- state.submissionAttachments[submissionId] = [action.payload];
3473
+ // UserFormRevisions do not get updated
3474
+ deleteFormRevision: (state, action) => {
3475
+ if (state.formRevisions[action.payload] === void 0) {
3476
+ throw new Error(`Revision with offline_id ${action.payload} does not exist`);
3376
3477
  }
3478
+ delete state.formRevisions[action.payload];
3479
+ delete LATEST_FORM_REVISION_CACHE[action.payload];
3377
3480
  },
3378
- addUserFormRevisionAttachment: (state, action) => {
3379
- const revisionId = action.payload.revision;
3380
- const revisionAttachments = state.revisionAttachments[revisionId];
3381
- if (revisionAttachments) {
3382
- revisionAttachments.push(action.payload);
3383
- } else {
3384
- state.revisionAttachments[revisionId] = [action.payload];
3481
+ deleteFormRevisions: (state, action) => {
3482
+ for (const offlineId of action.payload) {
3483
+ if (state.formRevisions[offlineId] === void 0) {
3484
+ throw new Error(`Revision with offline_id ${offlineId} does not exist`);
3485
+ }
3486
+ }
3487
+ for (const offlineId of action.payload) {
3488
+ delete state.formRevisions[offlineId];
3489
+ delete LATEST_FORM_REVISION_CACHE[offlineId];
3385
3490
  }
3386
3491
  },
3387
- setUserFormSubmissionAttachments: (state, action) => {
3388
- state.submissionAttachments = {};
3492
+ // attachment related actions
3493
+ setFormRevisionAttachments: (state, action) => {
3494
+ state.attachments = {};
3389
3495
  for (const attachment of action.payload) {
3390
- const submissionId = attachment.submission;
3391
- const submissionAttachments = state.submissionAttachments[submissionId];
3392
- if (submissionAttachments) {
3393
- submissionAttachments.push(attachment);
3394
- } else {
3395
- state.submissionAttachments[submissionId] = [attachment];
3396
- }
3496
+ state.attachments[attachment.offline_id] = attachment;
3397
3497
  }
3398
3498
  },
3399
- setUserFormRevisionAttachments: (state, action) => {
3400
- state.revisionAttachments = {};
3499
+ addFormRevisionAttachment: (state, action) => {
3500
+ if (state.attachments[action.payload.offline_id] !== void 0) {
3501
+ throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
3502
+ }
3503
+ state.attachments[action.payload.offline_id] = action.payload;
3504
+ },
3505
+ addFormRevisionAttachments: (state, action) => {
3401
3506
  for (const attachment of action.payload) {
3402
- const revisionId = attachment.revision;
3403
- const revisionAttachments = state.revisionAttachments[revisionId];
3404
- if (revisionAttachments) {
3405
- revisionAttachments.push(attachment);
3406
- } else {
3407
- state.revisionAttachments[revisionId] = [attachment];
3507
+ if (state.attachments[attachment.offline_id] !== void 0) {
3508
+ throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
3408
3509
  }
3409
3510
  }
3511
+ for (const attachment of action.payload) {
3512
+ state.attachments[attachment.offline_id] = attachment;
3513
+ }
3410
3514
  },
3411
- deleteUserFormSubmission: (state, action) => {
3412
- delete state.submissions[action.payload];
3413
- },
3414
- deleteUserFormSubmissions: (state, action) => {
3415
- for (const userFormSubmission of action.payload) {
3416
- delete state.submissions[userFormSubmission.offline_id];
3515
+ deleteFormRevisionAttachment: (state, action) => {
3516
+ if (state.attachments[action.payload] === void 0) {
3517
+ throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
3417
3518
  }
3519
+ delete state.attachments[action.payload];
3418
3520
  },
3419
- addUserFormSubmissions: (state, action) => {
3420
- for (const submission of action.payload) {
3421
- state.submissions[submission.offline_id] = submission;
3521
+ deleteFormRevisionAttachments: (state, action) => {
3522
+ for (const offlineId of action.payload) {
3523
+ if (state.attachments[offlineId] === void 0) {
3524
+ throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
3525
+ }
3422
3526
  }
3527
+ for (const offlineId of action.payload) {
3528
+ delete state.attachments[offlineId];
3529
+ }
3530
+ }
3531
+ }
3532
+ });
3533
+ const {
3534
+ setFormRevision,
3535
+ setFormRevisions,
3536
+ addFormRevision,
3537
+ addFormRevisions,
3538
+ deleteFormRevision,
3539
+ deleteFormRevisions,
3540
+ setFormRevisionAttachments,
3541
+ addFormRevisionAttachment,
3542
+ addFormRevisionAttachments,
3543
+ deleteFormRevisionAttachment,
3544
+ deleteFormRevisionAttachments
3545
+ } = formRevisionsSlice.actions;
3546
+ const selectFormRevisionMapping = (state) => state.formRevisionReducer.formRevisions;
3547
+ const selectFormRevisions = toolkit.createSelector(
3548
+ [selectFormRevisionMapping],
3549
+ (formRevisions) => Object.values(formRevisions)
3550
+ );
3551
+ const selectUserFormRevision = (formRevisionId) => (state) => {
3552
+ return state.formRevisionReducer.formRevisions[formRevisionId];
3553
+ };
3554
+ const _selectLatestFormRevision = (formRevisions, formId2) => {
3555
+ let ret = null;
3556
+ for (const candidate of Object.values(formRevisions)) {
3557
+ if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
3558
+ ret = candidate;
3559
+ }
3560
+ }
3561
+ if (!ret) {
3562
+ throw new Error("No form revision found for form " + formId2);
3563
+ }
3564
+ return ret;
3565
+ };
3566
+ const selectLatestFormRevisionOfForm = restructureCreateSelectorWithArgs(
3567
+ toolkit.createSelector([selectFormRevisionMapping, (_state, formId2) => formId2], (revisions, formId2) => {
3568
+ if (!formId2) {
3569
+ throw new Error("formId is required");
3570
+ }
3571
+ return _selectLatestFormRevision(revisions, formId2);
3572
+ })
3573
+ );
3574
+ const selectFormRevisionsOfForm = restructureCreateSelectorWithArgs(
3575
+ toolkit.createSelector([selectFormRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
3576
+ return revisions.filter((revision) => {
3577
+ return revision.form === formId2;
3578
+ });
3579
+ })
3580
+ );
3581
+ const selectLatestFormRevisionsOfComponentTypes = restructureCreateSelectorWithArgs(
3582
+ toolkit.createSelector(
3583
+ [
3584
+ selectUserFormMapping,
3585
+ selectFormRevisionMapping,
3586
+ (_state, componentTypeIds) => componentTypeIds
3587
+ ],
3588
+ (userForms, revisions, componentTypeIds) => {
3589
+ const componentTypeIdsSet = new Set(componentTypeIds);
3590
+ const ret = {};
3591
+ for (const form of Object.values(userForms)) {
3592
+ if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
3593
+ ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
3594
+ }
3595
+ }
3596
+ return ret;
3597
+ }
3598
+ )
3599
+ );
3600
+ const selectLatestFormRevisionByForm = toolkit.createSelector([selectFormRevisionMapping], (revisions) => {
3601
+ const latestRevisions = {};
3602
+ for (const revision of Object.values(revisions)) {
3603
+ const formId2 = revision.form;
3604
+ const currentLatestRevision = latestRevisions[formId2];
3605
+ if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
3606
+ latestRevisions[formId2] = revision;
3607
+ }
3608
+ }
3609
+ return latestRevisions;
3610
+ });
3611
+ const selectUserFormRevisionAttachmentsMapping = (state) => {
3612
+ return state.formRevisionReducer.attachments;
3613
+ };
3614
+ const selectAttachmentsOfFormRevision = restructureCreateSelectorWithArgs(
3615
+ toolkit.createSelector(
3616
+ [selectUserFormRevisionAttachmentsMapping, (_state, revisionId) => revisionId],
3617
+ (attachments, revisionId) => {
3618
+ return Object.values(attachments).filter((attachment) => attachment.revision === revisionId);
3619
+ }
3620
+ )
3621
+ );
3622
+ const formRevisionReducer = formRevisionsSlice.reducer;
3623
+ const initialState$4 = {
3624
+ forms: {}
3625
+ };
3626
+ const userFormSlice = toolkit.createSlice({
3627
+ name: "userForms",
3628
+ initialState: initialState$4,
3629
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3630
+ reducers: {
3631
+ setForms: (state, action) => {
3632
+ state.forms = {};
3633
+ action.payload.forEach((userForm) => {
3634
+ state.forms[userForm.offline_id] = userForm;
3635
+ });
3423
3636
  },
3424
- setUserFormSubmissions: (state, action) => {
3425
- state.submissions = {};
3426
- action.payload.forEach((submission) => {
3427
- state.submissions[submission.offline_id] = submission;
3637
+ addForm: (state, action) => {
3638
+ state.forms[action.payload.offline_id] = action.payload;
3639
+ },
3640
+ addForms: (state, action) => {
3641
+ action.payload.forEach((userForm) => {
3642
+ state.forms[userForm.offline_id] = userForm;
3428
3643
  });
3429
3644
  },
3430
3645
  favoriteForm: (state, action) => {
3431
3646
  const { formId: formId2 } = action.payload;
3432
- const form = state.userForms[formId2];
3647
+ const form = state.forms[formId2];
3433
3648
  if (!form) {
3434
3649
  throw new Error("No form exists with the id " + formId2);
3435
3650
  }
@@ -3437,48 +3652,23 @@ var __publicField = (obj, key, value) => {
3437
3652
  },
3438
3653
  unfavoriteForm: (state, action) => {
3439
3654
  const { formId: formId2 } = action.payload;
3440
- const form = state.userForms[formId2];
3655
+ const form = state.forms[formId2];
3441
3656
  if (!form) {
3442
3657
  throw new Error("No form exists with the id " + formId2);
3443
3658
  }
3444
3659
  form.favorite = false;
3445
3660
  },
3446
- deleteUserForm: (state, action) => {
3447
- delete state.userForms[action.payload];
3661
+ deleteForm: (state, action) => {
3662
+ delete state.forms[action.payload];
3448
3663
  }
3449
3664
  }
3450
3665
  });
3451
- const {
3452
- addUserForm,
3453
- addUserForms,
3454
- addUserFormRevisions,
3455
- updateOrCreateUserFormSubmission,
3456
- addUserFormSubmissions,
3457
- deleteUserFormSubmission,
3458
- deleteUserFormSubmissions,
3459
- favoriteForm,
3460
- unfavoriteForm,
3461
- deleteUserForm,
3462
- deleteUserFormRevision,
3463
- deleteUserFormRevisions,
3464
- setUserFormSubmissions,
3465
- addUserFormRevision,
3466
- addUserFormSubmissionAttachment,
3467
- addUserFormRevisionAttachment,
3468
- setUserFormSubmissionAttachments,
3469
- setUserFormRevisionAttachments
3470
- } = userFormSlice.actions;
3471
- const selectSubmissionAttachments = (submissionId) => (state) => {
3472
- return state.userFormReducer.submissionAttachments[submissionId] || [];
3473
- };
3474
- const selectRevisionAttachments = (revisionId) => (state) => {
3475
- return state.userFormReducer.revisionAttachments[revisionId] || [];
3476
- };
3666
+ const { setForms, addForm, addForms, favoriteForm, unfavoriteForm, deleteForm } = userFormSlice.actions;
3477
3667
  const selectFilteredUserForms = restructureCreateSelectorWithArgs(
3478
3668
  toolkit.createSelector(
3479
3669
  [
3480
- (state) => state.userFormReducer.userForms,
3481
- (state) => state.userFormReducer.revisions,
3670
+ (state) => state.userFormReducer.forms,
3671
+ (state) => state.formRevisionReducer.formRevisions,
3482
3672
  (_state, search) => search
3483
3673
  ],
3484
3674
  (userForms, revisions, search) => {
@@ -3501,71 +3691,188 @@ var __publicField = (obj, key, value) => {
3501
3691
  regularMatches.push({ ...userForm, latestRevision });
3502
3692
  }
3503
3693
  }
3504
- if (favoriteMatches.length >= maxResults) {
3505
- break;
3694
+ if (favoriteMatches.length >= maxResults) {
3695
+ break;
3696
+ }
3697
+ }
3698
+ const maxRegularMatches = maxResults - favoriteMatches.length;
3699
+ return [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)];
3700
+ },
3701
+ // as the argument is an object, we check the first level of properties for equality
3702
+ { memoizeOptions: { equalityCheck: reactRedux.shallowEqual } }
3703
+ )
3704
+ );
3705
+ const selectUserForm = (formId2) => (state) => {
3706
+ return state.userFormReducer.forms[formId2];
3707
+ };
3708
+ const selectUserFormMapping = (state) => {
3709
+ return state.userFormReducer.forms;
3710
+ };
3711
+ const selectComponentTypeForm = restructureCreateSelectorWithArgs(
3712
+ toolkit.createSelector(
3713
+ [selectUserFormMapping, (_state, componentTypeId) => componentTypeId],
3714
+ (userForms, componentTypeId) => {
3715
+ return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
3716
+ }
3717
+ )
3718
+ );
3719
+ const selectNumberOfUserForms = toolkit.createSelector([selectUserFormMapping], (userForms) => {
3720
+ return Object.keys(userForms).length;
3721
+ });
3722
+ const selectNumberOfGeneralUserForms = toolkit.createSelector([selectUserFormMapping], (userForms) => {
3723
+ return Object.values(userForms).filter((form) => !form.component_type).length;
3724
+ });
3725
+ const userFormReducer = userFormSlice.reducer;
3726
+ const initialState$3 = {
3727
+ formSubmissions: {},
3728
+ attachments: {}
3729
+ };
3730
+ const formSubmissionSlice = toolkit.createSlice({
3731
+ name: "formSubmissions",
3732
+ initialState: initialState$3,
3733
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
3734
+ reducers: {
3735
+ setFormSubmission: (state, action) => {
3736
+ state.formSubmissions[action.payload.offline_id] = action.payload;
3737
+ },
3738
+ setFormSubmissions: (state, action) => {
3739
+ state.formSubmissions = {};
3740
+ for (const submission of action.payload) {
3741
+ state.formSubmissions[submission.offline_id] = submission;
3742
+ }
3743
+ },
3744
+ addFormSubmission: (state, action) => {
3745
+ if (state.formSubmissions[action.payload.offline_id] !== void 0) {
3746
+ throw new Error(`Submission with offline_id ${action.payload.offline_id} already exists`);
3747
+ }
3748
+ state.formSubmissions[action.payload.offline_id] = action.payload;
3749
+ },
3750
+ addFormSubmissions: (state, action) => {
3751
+ for (const submission of action.payload) {
3752
+ if (state.formSubmissions[submission.offline_id] !== void 0) {
3753
+ throw new Error(`Submission with offline_id ${submission.offline_id} already exists`);
3754
+ }
3755
+ }
3756
+ for (const submission of action.payload) {
3757
+ state.formSubmissions[submission.offline_id] = submission;
3758
+ }
3759
+ },
3760
+ updateFormSubmission: (state, action) => {
3761
+ if (state.formSubmissions[action.payload.offline_id] === void 0) {
3762
+ throw new Error(`Submission with offline_id ${action.payload.offline_id} does not exist`);
3763
+ }
3764
+ state.formSubmissions[action.payload.offline_id] = action.payload;
3765
+ },
3766
+ updateFormSubmissions: (state, action) => {
3767
+ for (const submission of action.payload) {
3768
+ if (state.formSubmissions[submission.offline_id] === void 0) {
3769
+ throw new Error(`Submission with offline_id ${submission.offline_id} does not exist`);
3770
+ }
3771
+ }
3772
+ for (const submission of action.payload) {
3773
+ state.formSubmissions[submission.offline_id] = submission;
3774
+ }
3775
+ },
3776
+ deleteFormSubmission: (state, action) => {
3777
+ if (state.formSubmissions[action.payload] === void 0) {
3778
+ throw new Error(`Submission with offline_id ${action.payload} does not exist`);
3779
+ }
3780
+ delete state.formSubmissions[action.payload];
3781
+ },
3782
+ deleteFormSubmissions: (state, action) => {
3783
+ for (const offlineId of action.payload) {
3784
+ if (state.formSubmissions[offlineId] === void 0) {
3785
+ throw new Error(`Submission with offline_id ${offlineId} does not exist`);
3786
+ }
3787
+ delete state.formSubmissions[offlineId];
3788
+ }
3789
+ for (const offlineId of action.payload) {
3790
+ delete state.formSubmissions[offlineId];
3791
+ }
3792
+ },
3793
+ // Attachments
3794
+ addFormSubmissionAttachment: (state, action) => {
3795
+ if (state.attachments[action.payload.offline_id] !== void 0) {
3796
+ throw new Error(`Attachment with offline_id ${action.payload.offline_id} already exists`);
3797
+ }
3798
+ state.attachments[action.payload.offline_id] = action.payload;
3799
+ },
3800
+ addFormSubmissionAttachments: (state, action) => {
3801
+ for (const attachment of action.payload) {
3802
+ if (state.attachments[attachment.offline_id] !== void 0) {
3803
+ throw new Error(`Attachment with offline_id ${attachment.offline_id} already exists`);
3506
3804
  }
3507
3805
  }
3508
- const maxRegularMatches = maxResults - favoriteMatches.length;
3509
- return [...favoriteMatches, ...regularMatches.slice(0, maxRegularMatches)];
3806
+ for (const attachment of action.payload) {
3807
+ state.attachments[attachment.offline_id] = attachment;
3808
+ }
3510
3809
  },
3511
- // as the argument is an object, we check the first level of properties for equality
3512
- { memoizeOptions: { equalityCheck: reactRedux.shallowEqual } }
3513
- )
3514
- );
3515
- const selectFormRevision = (revisionId) => (state) => {
3516
- return state.userFormReducer.revisions[revisionId];
3517
- };
3518
- const _selectLatestFormRevision = (revisions, formId2) => {
3519
- let ret = null;
3520
- for (const candidate of Object.values(revisions)) {
3521
- if (candidate.form === formId2 && (!ret || ret.revision < candidate.revision)) {
3522
- ret = candidate;
3810
+ // We only need a multi set for attachments because they are not updated, only added and deleted
3811
+ setFormSubmissionAttachments: (state, action) => {
3812
+ state.attachments = {};
3813
+ for (const attachment of action.payload) {
3814
+ state.attachments[attachment.offline_id] = attachment;
3815
+ }
3816
+ },
3817
+ // The delete actions for UserFormSubmissionAttachments are not used in the app, but are included for completeness
3818
+ // Could be used if editing a submission is ever supported, will be applicable for supporting tip tap content in submissions
3819
+ deleteFormSubmissionAttachment: (state, action) => {
3820
+ if (state.attachments[action.payload] === void 0) {
3821
+ throw new Error(`Attachment with offline_id ${action.payload} does not exist`);
3822
+ }
3823
+ delete state.attachments[action.payload];
3824
+ },
3825
+ deleteFormSubmissionAttachments: (state, action) => {
3826
+ for (const offlineId of action.payload) {
3827
+ if (state.attachments[offlineId] === void 0) {
3828
+ throw new Error(`Attachment with offline_id ${offlineId} does not exist`);
3829
+ }
3830
+ delete state.attachments[offlineId];
3831
+ }
3523
3832
  }
3524
3833
  }
3525
- if (!ret) {
3526
- throw new Error("No revision found for form " + formId2);
3834
+ });
3835
+ const {
3836
+ setFormSubmission,
3837
+ setFormSubmissions,
3838
+ addFormSubmission,
3839
+ addFormSubmissions,
3840
+ updateFormSubmission,
3841
+ updateFormSubmissions,
3842
+ deleteFormSubmission,
3843
+ deleteFormSubmissions,
3844
+ addFormSubmissionAttachment,
3845
+ addFormSubmissionAttachments,
3846
+ setFormSubmissionAttachments,
3847
+ deleteFormSubmissionAttachment,
3848
+ deleteFormSubmissionAttachments
3849
+ } = formSubmissionSlice.actions;
3850
+ const selectFormSubmissionsMapping = (state) => {
3851
+ return state.formSubmissionReducer.formSubmissions;
3852
+ };
3853
+ const selectFormSubmissions = toolkit.createSelector(
3854
+ [selectFormSubmissionsMapping],
3855
+ (submissions) => {
3856
+ return Object.values(submissions);
3527
3857
  }
3528
- return ret;
3529
- };
3530
- const selectLatestFormRevision = restructureCreateSelectorWithArgs(
3531
- toolkit.createSelector(
3532
- [(state) => state.userFormReducer.revisions, (_state, formId2) => formId2],
3533
- (revisions, formId2) => {
3534
- if (!formId2) {
3535
- throw new Error("formId is required");
3536
- }
3537
- return _selectLatestFormRevision(revisions, formId2);
3538
- }
3539
- )
3540
3858
  );
3541
- const selectUserForm = (formId2) => (state) => {
3542
- return state.userFormReducer.userForms[formId2];
3543
- };
3544
- const selectSubmissionMapping = (state) => state.userFormReducer.submissions;
3545
- const selectSubmissions = toolkit.createSelector([selectSubmissionMapping], (submissions) => Object.values(submissions));
3546
- const selectRevisionMapping = (state) => state.userFormReducer.revisions;
3547
- const selectRevisions = toolkit.createSelector([selectRevisionMapping], (revisions) => Object.values(revisions));
3548
- const selectRevisionsForForm = restructureCreateSelectorWithArgs(
3549
- toolkit.createSelector([selectRevisions, (_state, formId2) => formId2], (revisions, formId2) => {
3550
- return revisions.filter((revision) => {
3551
- return revision.form === formId2;
3552
- });
3553
- })
3554
- );
3555
- const selectSubmissionsForForm = restructureCreateSelectorWithArgs(
3859
+ const selectFormSubmission = (submissionId) => (state) => {
3860
+ return state.formSubmissionReducer.formSubmissions[submissionId];
3861
+ };
3862
+ const selectFormSubmissionsOfForm = restructureCreateSelectorWithArgs(
3556
3863
  toolkit.createSelector(
3557
- [selectSubmissions, selectRevisionMapping, (_state, formId2) => formId2],
3864
+ [selectFormSubmissions, selectFormRevisionMapping, (_state, formId2) => formId2],
3558
3865
  (submissions, revisionMapping, formId2) => {
3559
- return Object.values(submissions).filter((submission) => {
3866
+ return submissions.filter((submission) => {
3560
3867
  const revision = revisionMapping[submission.form_revision];
3561
3868
  return (revision == null ? void 0 : revision.form) === formId2;
3562
3869
  });
3563
3870
  }
3564
3871
  )
3565
3872
  );
3566
- const selectSubmissionsForIssue = restructureCreateSelectorWithArgs(
3873
+ const selectFormSubmissionsOfIssue = restructureCreateSelectorWithArgs(
3567
3874
  toolkit.createSelector(
3568
- [(state) => state.userFormReducer.submissions, (_state, issueId) => issueId],
3875
+ [selectFormSubmissions, (_state, issueId) => issueId],
3569
3876
  (submissions, issueId) => {
3570
3877
  return Object.values(submissions).filter((submission) => {
3571
3878
  return submission.issue === issueId;
@@ -3573,9 +3880,9 @@ var __publicField = (obj, key, value) => {
3573
3880
  }
3574
3881
  )
3575
3882
  );
3576
- const selectSubmissionsForComponent = restructureCreateSelectorWithArgs(
3883
+ const selectFormSubmissionsOfComponent = restructureCreateSelectorWithArgs(
3577
3884
  toolkit.createSelector(
3578
- [selectSubmissions, (_state, componentId) => componentId],
3885
+ [selectFormSubmissions, (_state, componentId) => componentId],
3579
3886
  (submissions, componentId) => {
3580
3887
  return submissions.filter((submission) => {
3581
3888
  return submission.component === componentId;
@@ -3583,54 +3890,35 @@ var __publicField = (obj, key, value) => {
3583
3890
  }
3584
3891
  )
3585
3892
  );
3586
- const selectUserFormMapping = (state) => {
3587
- return state.userFormReducer.userForms;
3588
- };
3589
- const selectComponentTypeForm = restructureCreateSelectorWithArgs(
3590
- toolkit.createSelector(
3591
- [selectUserFormMapping, (_state, componentTypeId) => componentTypeId],
3592
- (userForms, componentTypeId) => {
3593
- return Object.values(userForms).find((userForm) => userForm.component_type === componentTypeId);
3893
+ const selectFormSubmissionsByComponents = toolkit.createSelector(
3894
+ [selectFormSubmissionsMapping, selectComponentsMapping],
3895
+ (submissions, components) => {
3896
+ var _a2;
3897
+ const componentSubmissionMapping = {};
3898
+ for (const componentId in components) {
3899
+ componentSubmissionMapping[componentId] = [];
3594
3900
  }
3595
- )
3901
+ for (const submissionId in submissions) {
3902
+ const submission = submissions[submissionId];
3903
+ if (submission.component) {
3904
+ (_a2 = componentSubmissionMapping[submission.component]) == null ? void 0 : _a2.push(submission);
3905
+ }
3906
+ }
3907
+ return componentSubmissionMapping;
3908
+ }
3596
3909
  );
3597
- const selectLatestRevisionsFromComponentTypeIds = restructureCreateSelectorWithArgs(
3910
+ const selectFormSubmissionAttachmentsMapping = (state) => {
3911
+ return state.formSubmissionReducer.attachments;
3912
+ };
3913
+ const selectAttachmentsOfFormSubmission = restructureCreateSelectorWithArgs(
3598
3914
  toolkit.createSelector(
3599
- [
3600
- selectUserFormMapping,
3601
- selectRevisionMapping,
3602
- (_state, componentTypeIds) => componentTypeIds
3603
- ],
3604
- (userForms, revisions, componentTypeIds) => {
3605
- const componentTypeIdsSet = new Set(componentTypeIds);
3606
- const ret = {};
3607
- for (const form of Object.values(userForms)) {
3608
- if (form.component_type && componentTypeIdsSet.has(form.component_type)) {
3609
- ret[form.component_type] = _selectLatestFormRevision(revisions, form.offline_id);
3610
- }
3611
- }
3612
- return ret;
3915
+ [selectFormSubmissionAttachmentsMapping, (_state, submissionId) => submissionId],
3916
+ (attachmentsMapping, submissionId) => {
3917
+ return Object.values(attachmentsMapping).filter((attachment) => attachment.submission === submissionId);
3613
3918
  }
3614
3919
  )
3615
3920
  );
3616
- const selectLatestRevisionByFormId = toolkit.createSelector([selectRevisionMapping], (revisions) => {
3617
- const latestRevisions = {};
3618
- for (const revision of Object.values(revisions)) {
3619
- const formId2 = revision.form;
3620
- const currentLatestRevision = latestRevisions[formId2];
3621
- if (!currentLatestRevision || currentLatestRevision.revision < revision.revision) {
3622
- latestRevisions[formId2] = revision;
3623
- }
3624
- }
3625
- return latestRevisions;
3626
- });
3627
- const selectNumberOfUserForms = toolkit.createSelector([selectUserFormMapping], (userForms) => {
3628
- return Object.keys(userForms).length;
3629
- });
3630
- const selectNumberOfGeneralUserForms = toolkit.createSelector([selectUserFormMapping], (userForms) => {
3631
- return Object.values(userForms).filter((form) => !form.component_type).length;
3632
- });
3633
- const userFormReducer = userFormSlice.reducer;
3921
+ const formSubmissionReducer = formSubmissionSlice.reducer;
3634
3922
  const initialState$2 = {
3635
3923
  emailDomains: {}
3636
3924
  };
@@ -3877,6 +4165,8 @@ var __publicField = (obj, key, value) => {
3877
4165
  rehydratedReducer,
3878
4166
  settingReducer,
3879
4167
  userFormReducer,
4168
+ formRevisionReducer,
4169
+ formSubmissionReducer,
3880
4170
  userReducer,
3881
4171
  workspaceReducer,
3882
4172
  emailDomainsReducer,
@@ -3929,7 +4219,7 @@ var __publicField = (obj, key, value) => {
3929
4219
  throw new Error(`Failed to update index_workspace of issue ${issue.offline_id} to main workspace`);
3930
4220
  }
3931
4221
  }
3932
- const indexedForms = Object.values(draft.userFormReducer.userForms).filter(
4222
+ const indexedForms = Object.values(draft.userFormReducer.forms).filter(
3933
4223
  (form) => form.index_workspace === workspaceId
3934
4224
  );
3935
4225
  for (const form of indexedForms) {
@@ -4428,7 +4718,7 @@ var __publicField = (obj, key, value) => {
4428
4718
  }
4429
4719
  // Attachments aren't models, so we use the OptimisticGenericResult type instead
4430
4720
  async addIssueAttachment(attachmentPayload) {
4431
- const { description: description2, issue, file_sha1, offline_id } = attachmentPayload;
4721
+ const { issue, file_sha1, offline_id } = attachmentPayload;
4432
4722
  if (!attachmentPayload.file.objectURL) {
4433
4723
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4434
4724
  }
@@ -4436,7 +4726,9 @@ var __publicField = (obj, key, value) => {
4436
4726
  ...attachmentPayload,
4437
4727
  file: attachmentPayload.file.objectURL,
4438
4728
  file_name: attachmentPayload.file.name,
4439
- file_type: attachmentPayload.file.type
4729
+ file_type: attachmentPayload.file.type,
4730
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4731
+ created_by: this.client.store.getState().userReducer.currentUser.id
4440
4732
  };
4441
4733
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4442
4734
  this.client.store.dispatch(addIssueAttachment(offlineAttachment));
@@ -4448,10 +4740,7 @@ var __publicField = (obj, key, value) => {
4448
4740
  blocks: [offline_id, issue],
4449
4741
  blockers: [file_sha1],
4450
4742
  payload: {
4451
- offline_id,
4452
- issue,
4453
- description: description2 ?? "",
4454
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4743
+ ...offlineAttachment,
4455
4744
  ...fileProps
4456
4745
  }
4457
4746
  });
@@ -4462,7 +4751,7 @@ var __publicField = (obj, key, value) => {
4462
4751
  return [offlineAttachment, promise];
4463
4752
  }
4464
4753
  async addComponentAttachment(attachmentPayload) {
4465
- const { description: description2, component, file_sha1, offline_id } = attachmentPayload;
4754
+ const { component, file_sha1, offline_id } = attachmentPayload;
4466
4755
  if (!attachmentPayload.file.objectURL) {
4467
4756
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4468
4757
  }
@@ -4470,7 +4759,9 @@ var __publicField = (obj, key, value) => {
4470
4759
  ...attachmentPayload,
4471
4760
  file: attachmentPayload.file.objectURL,
4472
4761
  file_name: attachmentPayload.file.name,
4473
- file_type: attachmentPayload.file.type
4762
+ file_type: attachmentPayload.file.type,
4763
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4764
+ created_by: this.client.store.getState().userReducer.currentUser.id
4474
4765
  };
4475
4766
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4476
4767
  this.client.store.dispatch(addComponentAttachment(offlineAttachment));
@@ -4482,10 +4773,7 @@ var __publicField = (obj, key, value) => {
4482
4773
  blocks: [offline_id, component],
4483
4774
  blockers: [file_sha1],
4484
4775
  payload: {
4485
- offline_id,
4486
- component,
4487
- description: description2 ?? "",
4488
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4776
+ ...offlineAttachment,
4489
4777
  ...fileProps
4490
4778
  }
4491
4779
  });
@@ -4496,7 +4784,7 @@ var __publicField = (obj, key, value) => {
4496
4784
  return [offlineAttachment, promise];
4497
4785
  }
4498
4786
  async addComponentTypeAttachment(attachmentPayload) {
4499
- const { description: description2, component_type, file_sha1, offline_id } = attachmentPayload;
4787
+ const { component_type, file_sha1, offline_id } = attachmentPayload;
4500
4788
  if (!attachmentPayload.file.objectURL) {
4501
4789
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4502
4790
  }
@@ -4504,7 +4792,9 @@ var __publicField = (obj, key, value) => {
4504
4792
  ...attachmentPayload,
4505
4793
  file: attachmentPayload.file.objectURL,
4506
4794
  file_name: attachmentPayload.file.name,
4507
- file_type: attachmentPayload.file.type
4795
+ file_type: attachmentPayload.file.type,
4796
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4797
+ created_by: this.client.store.getState().userReducer.currentUser.id
4508
4798
  };
4509
4799
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4510
4800
  this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
@@ -4516,10 +4806,7 @@ var __publicField = (obj, key, value) => {
4516
4806
  blocks: [offline_id, component_type],
4517
4807
  blockers: [file_sha1],
4518
4808
  payload: {
4519
- offline_id,
4520
- component_type,
4521
- description: description2 ?? "",
4522
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4809
+ ...offlineAttachment,
4523
4810
  ...fileProps
4524
4811
  }
4525
4812
  });
@@ -4538,7 +4825,9 @@ var __publicField = (obj, key, value) => {
4538
4825
  ...attachmentPayload,
4539
4826
  file: attachmentPayload.file.objectURL,
4540
4827
  file_name: attachmentPayload.file.name,
4541
- file_type: attachmentPayload.file.type
4828
+ file_type: attachmentPayload.file.type,
4829
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4830
+ created_by: this.client.store.getState().userReducer.currentUser.id
4542
4831
  };
4543
4832
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4544
4833
  this.client.store.dispatch(addProjectAttachment(offlineAttachment));
@@ -4578,7 +4867,9 @@ var __publicField = (obj, key, value) => {
4578
4867
  file_name: file2.name,
4579
4868
  file_type: file2.type,
4580
4869
  issue: issueId,
4581
- file_sha1: hash
4870
+ file_sha1: hash,
4871
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4872
+ created_by: this.client.store.getState().userReducer.currentUser.id
4582
4873
  });
4583
4874
  return this.addIssueAttachment(attachment);
4584
4875
  };
@@ -4597,7 +4888,9 @@ var __publicField = (obj, key, value) => {
4597
4888
  file_name: file2.name,
4598
4889
  file_type: file2.type,
4599
4890
  component: componentId,
4600
- file_sha1: hash
4891
+ file_sha1: hash,
4892
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4893
+ created_by: this.client.store.getState().userReducer.currentUser.id
4601
4894
  });
4602
4895
  return this.addComponentAttachment(attachment);
4603
4896
  };
@@ -4616,7 +4909,9 @@ var __publicField = (obj, key, value) => {
4616
4909
  file_name: file2.name,
4617
4910
  file_type: file2.type,
4618
4911
  component_type: componentTypeId,
4619
- file_sha1: hash
4912
+ file_sha1: hash,
4913
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4914
+ created_by: this.client.store.getState().userReducer.currentUser.id
4620
4915
  });
4621
4916
  return this.addComponentTypeAttachment(attachment);
4622
4917
  };
@@ -4635,7 +4930,9 @@ var __publicField = (obj, key, value) => {
4635
4930
  file_name: file2.name,
4636
4931
  file_type: file2.type,
4637
4932
  project: projectId,
4638
- file_sha1: hash
4933
+ file_sha1: hash,
4934
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4935
+ created_by: this.client.store.getState().userReducer.currentUser.id
4639
4936
  });
4640
4937
  return this.addProjectAttachment(attachment);
4641
4938
  };
@@ -5712,49 +6009,35 @@ var __publicField = (obj, key, value) => {
5712
6009
  }
5713
6010
  }
5714
6011
  class IssueCommentService extends BaseApiService {
6012
+ // Omit author and submitted_at since these will always be set internally
5715
6013
  add(comment) {
5716
- const offlinePayload = offline(comment);
5717
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5718
6014
  const { store } = this.client;
5719
- const offlineComment = {
5720
- ...offlinePayload,
6015
+ const offlineComment = offline({
6016
+ ...comment,
5721
6017
  author: store.getState().userReducer.currentUser.id,
5722
- created_at: submittedAt
5723
- };
5724
- store.dispatch(addOrReplaceIssueComment(offlineComment));
6018
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString()
6019
+ });
6020
+ store.dispatch(addIssueComment(offlineComment));
5725
6021
  const promise = this.enqueueRequest({
5726
6022
  description: `${truncate(comment.content, 80)}`,
5727
6023
  method: HttpMethod.POST,
5728
6024
  url: `/issues/${comment.issue}/comment/`,
5729
- payload: { ...offlinePayload, submitted_at: submittedAt },
6025
+ payload: offlineComment,
5730
6026
  blockers: [comment.issue],
5731
- blocks: [offlinePayload.offline_id]
6027
+ blocks: [offlineComment.offline_id]
6028
+ });
6029
+ promise.catch(() => {
6030
+ store.dispatch(removeIssueComment(offlineComment.offline_id));
5732
6031
  });
5733
6032
  return [offlineComment, promise];
5734
6033
  }
5735
- async refreshStore() {
6034
+ update(comment) {
5736
6035
  const { store } = this.client;
5737
- const result = await this.enqueueRequest({
5738
- description: "Get comments",
5739
- method: HttpMethod.GET,
5740
- // TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
5741
- url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
5742
- blockers: [],
5743
- blocks: []
5744
- });
5745
- let filteredResult = result.filter(onlyUniqueOfflineIds);
5746
- filteredResult = filteredResult.map((comment) => {
5747
- return { ...comment };
5748
- });
5749
- if (result.length !== filteredResult.length) {
5750
- console.error(
5751
- `Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
5752
- );
6036
+ const commentToUpdate = store.getState().issueReducer.comments[comment.offline_id];
6037
+ if (!commentToUpdate) {
6038
+ throw new Error(`Comment with offline_id ${comment.offline_id} not found in store`);
5753
6039
  }
5754
- store.dispatch(setIssueComments(filteredResult));
5755
- }
5756
- update(comment) {
5757
- this.client.store.dispatch(addOrReplaceIssueComment(comment));
6040
+ store.dispatch(setIssueComment(comment));
5758
6041
  const promise = this.enqueueRequest({
5759
6042
  description: `Edit comment: ${truncate(comment.content, 80)}`,
5760
6043
  method: HttpMethod.PATCH,
@@ -5763,17 +6046,62 @@ var __publicField = (obj, key, value) => {
5763
6046
  blockers: [comment.issue],
5764
6047
  blocks: [comment.offline_id]
5765
6048
  });
6049
+ promise.catch(() => {
6050
+ store.dispatch(setIssueComment(commentToUpdate));
6051
+ });
5766
6052
  return [comment, promise];
5767
6053
  }
5768
6054
  remove(offline_id) {
6055
+ const commentToRemove = this.client.store.getState().issueReducer.comments[offline_id];
6056
+ if (!commentToRemove) {
6057
+ throw new Error(`Comment with offline_id ${offline_id} not found in store`);
6058
+ }
5769
6059
  this.client.store.dispatch(removeIssueComment(offline_id));
5770
- return this.enqueueRequest({
6060
+ const promise = this.enqueueRequest({
5771
6061
  description: "Delete comment",
5772
6062
  method: HttpMethod.DELETE,
5773
6063
  url: `/issues/comments/${offline_id}/`,
5774
6064
  blockers: [offline_id],
5775
6065
  blocks: []
5776
6066
  });
6067
+ promise.catch(() => {
6068
+ this.client.store.dispatch(addIssueComment(commentToRemove));
6069
+ });
6070
+ return promise;
6071
+ }
6072
+ async refreshStore() {
6073
+ const { store } = this.client;
6074
+ const result = await this.enqueueRequest({
6075
+ description: "Get comments",
6076
+ method: HttpMethod.GET,
6077
+ // TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
6078
+ url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
6079
+ blockers: [],
6080
+ blocks: []
6081
+ });
6082
+ store.dispatch(setIssueComments(result));
6083
+ }
6084
+ }
6085
+ class IssueUpdateService extends BaseApiService {
6086
+ async refreshStore() {
6087
+ const { store } = this.client;
6088
+ const result = await this.enqueueRequest({
6089
+ description: "Get issue updates",
6090
+ method: HttpMethod.GET,
6091
+ url: `/projects/${store.getState().projectReducer.activeProjectId}/issues/updates/`,
6092
+ blockers: [],
6093
+ blocks: []
6094
+ });
6095
+ let filteredResult = result.filter(onlyUniqueOfflineIds);
6096
+ filteredResult = filteredResult.map((comment) => {
6097
+ return { ...comment };
6098
+ });
6099
+ if (result.length !== filteredResult.length) {
6100
+ console.error(
6101
+ `Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
6102
+ );
6103
+ }
6104
+ store.dispatch(setIssueUpdates(filteredResult));
5777
6105
  }
5778
6106
  }
5779
6107
  class IssueService extends BaseApiService {
@@ -5854,7 +6182,83 @@ var __publicField = (obj, key, value) => {
5854
6182
  return [offlineIssues, promise];
5855
6183
  }
5856
6184
  update(issue) {
6185
+ const state = this.client.store.getState();
6186
+ const issueToBeUpdated = state.issueReducer.issues[issue.offline_id];
6187
+ if (!issueToBeUpdated) {
6188
+ throw new Error(
6189
+ `Attempting to update an issue with offline_id ${issue.offline_id} that doesn't exist in the store`
6190
+ );
6191
+ }
5857
6192
  this.client.store.dispatch(updateIssue(issue));
6193
+ const changes = {};
6194
+ for (const issueUpdateChange of [
6195
+ IssueUpdateChange.TITLE,
6196
+ IssueUpdateChange.DESCRIPTION,
6197
+ IssueUpdateChange.STATUS,
6198
+ IssueUpdateChange.CATEGORY,
6199
+ IssueUpdateChange.PRIORITY,
6200
+ IssueUpdateChange.ASSIGNED_TO,
6201
+ IssueUpdateChange.DUE_DATE
6202
+ ]) {
6203
+ if (issueUpdateChange in issue && issue[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {
6204
+ switch (issueUpdateChange) {
6205
+ case "category": {
6206
+ let categoryOrNull = null;
6207
+ const categoryIdOrNull = issue[issueUpdateChange];
6208
+ if (categoryIdOrNull) {
6209
+ categoryOrNull = state.categoryReducer.categories[categoryIdOrNull] ?? null;
6210
+ if (!categoryOrNull)
6211
+ throw new Error(
6212
+ `Trying to update issue category to ${categoryIdOrNull} which does not exist in store`
6213
+ );
6214
+ }
6215
+ changes[issueUpdateChange] = categoryOrNull ? {
6216
+ name: categoryOrNull.name,
6217
+ color: categoryOrNull.color,
6218
+ offline_id: categoryOrNull.offline_id
6219
+ } : null;
6220
+ break;
6221
+ }
6222
+ case "assigned_to": {
6223
+ let userOrNull = null;
6224
+ const userIdOrNull = issue[issueUpdateChange];
6225
+ if (userIdOrNull) {
6226
+ userOrNull = state.userReducer.users[userIdOrNull] ?? null;
6227
+ if (!userOrNull)
6228
+ throw new Error(
6229
+ `Trying to update issue assigned_to to ${userIdOrNull} which does not exist in store`
6230
+ );
6231
+ }
6232
+ changes[issueUpdateChange] = userOrNull ? {
6233
+ full_name: userOrNull.username,
6234
+ id: userOrNull.id
6235
+ } : null;
6236
+ break;
6237
+ }
6238
+ case "description":
6239
+ changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
6240
+ break;
6241
+ case "title":
6242
+ changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
6243
+ break;
6244
+ case "priority":
6245
+ changes[issueUpdateChange] = issue[issueUpdateChange];
6246
+ break;
6247
+ case "status":
6248
+ changes[issueUpdateChange] = issue[issueUpdateChange];
6249
+ break;
6250
+ case "due_date":
6251
+ changes[issueUpdateChange] = issue[issueUpdateChange] ? issue[issueUpdateChange] : null;
6252
+ }
6253
+ }
6254
+ }
6255
+ const offlineIssueUpdate = offline({
6256
+ created_by: state.userReducer.currentUser.id,
6257
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
6258
+ issue: issueToBeUpdated.offline_id,
6259
+ changes
6260
+ });
6261
+ this.client.store.dispatch(addIssueUpdate(offlineIssueUpdate));
5858
6262
  const promise = this.enqueueRequest({
5859
6263
  description: "Edit issue",
5860
6264
  method: HttpMethod.PATCH,
@@ -5863,23 +6267,30 @@ var __publicField = (obj, key, value) => {
5863
6267
  blockers: [issue.offline_id],
5864
6268
  blocks: [issue.offline_id]
5865
6269
  });
6270
+ promise.catch(() => {
6271
+ this.client.store.dispatch(updateIssue(issueToBeUpdated));
6272
+ this.client.store.dispatch(removeIssueUpdate(offlineIssueUpdate.offline_id));
6273
+ });
5866
6274
  const fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id];
5867
6275
  return [fullIssue, promise];
5868
6276
  }
5869
6277
  async remove(id) {
5870
6278
  const { store } = this.client;
5871
6279
  const state = store.getState();
6280
+ const dispatch = store.dispatch;
5872
6281
  const backup = state.issueReducer.issues[id];
5873
6282
  if (!backup) {
5874
6283
  throw new Error(`No issue with id ${id} found in the store`);
5875
6284
  }
5876
6285
  const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue === id);
5877
6286
  const attachmentsOfIssue = selectAttachmentsOfIssue(id)(state);
5878
- this.client.store.dispatch(removeIssue(id));
5879
- store.dispatch(addActiveProjectIssuesCount(-1));
5880
- if (attachmentsOfIssue.length > 0) {
5881
- this.client.store.dispatch(removeAttachmentsOfIssue(id));
5882
- }
6287
+ const updatesOfIssue = selectIssueUpdatesOfIssue(id)(state);
6288
+ dispatch(removeIssue(id));
6289
+ dispatch(addActiveProjectIssuesCount(-1));
6290
+ if (attachmentsOfIssue.length > 0)
6291
+ dispatch(removeAttachmentsOfIssue(id));
6292
+ if (updatesOfIssue.length > 0)
6293
+ dispatch(removeIssueUpdates(updatesOfIssue.map(({ offline_id }) => offline_id)));
5883
6294
  try {
5884
6295
  return await this.enqueueRequest({
5885
6296
  description: "Delete issue",
@@ -5889,9 +6300,10 @@ var __publicField = (obj, key, value) => {
5889
6300
  blocks: []
5890
6301
  });
5891
6302
  } catch (e) {
5892
- this.client.store.dispatch(addIssue(backup));
5893
- this.client.store.dispatch(addIssueAttachments(attachments));
5894
- store.dispatch(addActiveProjectIssuesCount(1));
6303
+ dispatch(addIssue(backup));
6304
+ dispatch(addIssueAttachments(attachments));
6305
+ dispatch(addIssueUpdates(updatesOfIssue));
6306
+ dispatch(addActiveProjectIssuesCount(1));
5895
6307
  throw e;
5896
6308
  }
5897
6309
  }
@@ -6073,6 +6485,7 @@ var __publicField = (obj, key, value) => {
6073
6485
  store.dispatch(setProjectAttachments(project_attachments));
6074
6486
  });
6075
6487
  void this.client.documents.refreshStore();
6488
+ void this.client.issueUpdates.refreshStore();
6076
6489
  }
6077
6490
  store.dispatch(setIsFetchingInitialData(false));
6078
6491
  if (overwrite) {
@@ -6437,7 +6850,7 @@ var __publicField = (obj, key, value) => {
6437
6850
  ...revisionAttachmentPayload,
6438
6851
  file: URL.createObjectURL(image)
6439
6852
  };
6440
- store.dispatch(addUserFormRevisionAttachment(offlinePayload));
6853
+ store.dispatch(addFormRevisionAttachment(offlinePayload));
6441
6854
  return attach;
6442
6855
  });
6443
6856
  });
@@ -6471,8 +6884,8 @@ var __publicField = (obj, key, value) => {
6471
6884
  revision: 0
6472
6885
  };
6473
6886
  const { store } = this.client;
6474
- store.dispatch(addUserForm(retForm));
6475
- store.dispatch(addUserFormRevision(retRevision));
6887
+ store.dispatch(addForm(retForm));
6888
+ store.dispatch(addFormRevision(retRevision));
6476
6889
  const formPromise = this.enqueueRequest({
6477
6890
  description: "Create form",
6478
6891
  method: HttpMethod.POST,
@@ -6490,8 +6903,8 @@ var __publicField = (obj, key, value) => {
6490
6903
  });
6491
6904
  const attachImagesPromises = this.getAttachImagePromises(images, offlineRevisionPayload.offline_id);
6492
6905
  void formPromise.catch((e) => {
6493
- store.dispatch(deleteUserForm(retForm.offline_id));
6494
- store.dispatch(deleteUserFormRevision(retRevision.offline_id));
6906
+ store.dispatch(deleteForm(retForm.offline_id));
6907
+ store.dispatch(deleteFormRevision(retRevision.offline_id));
6495
6908
  throw e;
6496
6909
  });
6497
6910
  const settledPromise = Promise.all([formPromise, ...attachImagesPromises]).then(() => formPromise);
@@ -6533,7 +6946,7 @@ var __publicField = (obj, key, value) => {
6533
6946
  revision: "Pending",
6534
6947
  form: formId2
6535
6948
  };
6536
- store.dispatch(addUserFormRevision(fullRevision));
6949
+ store.dispatch(addFormRevision(fullRevision));
6537
6950
  const promise = this.enqueueRequest({
6538
6951
  description: "Create form revision",
6539
6952
  method: HttpMethod.PATCH,
@@ -6547,9 +6960,9 @@ var __publicField = (obj, key, value) => {
6547
6960
  });
6548
6961
  const attachImagesPromises = this.getAttachImagePromises(images, offlineRevision.offline_id);
6549
6962
  void promise.then((result) => {
6550
- store.dispatch(addUserFormRevision(result));
6963
+ store.dispatch(setFormRevision(result));
6551
6964
  }).catch(() => {
6552
- store.dispatch(deleteUserFormRevision(fullRevision.offline_id));
6965
+ store.dispatch(deleteFormRevision(fullRevision.offline_id));
6553
6966
  });
6554
6967
  const settledPromise = Promise.all([promise, ...attachImagesPromises]).then(() => promise);
6555
6968
  return [fullRevision, settledPromise];
@@ -6595,15 +7008,15 @@ var __publicField = (obj, key, value) => {
6595
7008
  if (!userForm) {
6596
7009
  throw new Error("Expected userForm to exist");
6597
7010
  }
6598
- const userFormSubmissions = selectSubmissionsForForm(formId2)(state);
7011
+ const userFormSubmissions = selectFormSubmissionsOfForm(formId2)(state);
6599
7012
  if (userFormSubmissions && userFormSubmissions.length > 0) {
6600
- store.dispatch(deleteUserFormSubmissions(userFormSubmissions));
7013
+ store.dispatch(deleteFormSubmissions(userFormSubmissions.map(({ offline_id }) => offline_id)));
6601
7014
  }
6602
- const userFormRevisions = selectRevisionsForForm(formId2)(state);
7015
+ const userFormRevisions = selectFormRevisionsOfForm(formId2)(state);
6603
7016
  if (userFormRevisions && userFormRevisions.length > 0) {
6604
- store.dispatch(deleteUserFormRevisions(userFormRevisions));
7017
+ store.dispatch(deleteFormRevisions(userFormRevisions.map(({ offline_id }) => offline_id)));
6605
7018
  }
6606
- store.dispatch(deleteUserForm(formId2));
7019
+ store.dispatch(deleteForm(formId2));
6607
7020
  try {
6608
7021
  return await this.enqueueRequest({
6609
7022
  description: "Delete form",
@@ -6613,12 +7026,12 @@ var __publicField = (obj, key, value) => {
6613
7026
  blocks: []
6614
7027
  });
6615
7028
  } catch (e) {
6616
- store.dispatch(addUserForm(userForm));
7029
+ store.dispatch(addForm(userForm));
6617
7030
  if (userFormRevisions && userFormRevisions.length > 0) {
6618
- store.dispatch(addUserFormRevisions(userFormRevisions));
7031
+ store.dispatch(addFormRevisions(userFormRevisions));
6619
7032
  }
6620
7033
  if (userFormSubmissions && userFormSubmissions.length > 0) {
6621
- store.dispatch(addUserFormSubmissions(userFormSubmissions));
7034
+ store.dispatch(addFormSubmissions(userFormSubmissions));
6622
7035
  }
6623
7036
  throw e;
6624
7037
  }
@@ -6632,16 +7045,15 @@ var __publicField = (obj, key, value) => {
6632
7045
  blockers: [],
6633
7046
  blocks: []
6634
7047
  });
6635
- store.dispatch(addUserForms(Object.values(result.forms)));
6636
- store.dispatch(addUserFormRevisions(Object.values(result.revisions)));
6637
- store.dispatch(setUserFormRevisionAttachments(Object.values(result.attachments)));
7048
+ store.dispatch(setForms(Object.values(result.forms)));
7049
+ store.dispatch(setFormRevisions(Object.values(result.revisions)));
7050
+ store.dispatch(setFormRevisionAttachments(Object.values(result.attachments)));
6638
7051
  }
6639
7052
  }
6640
7053
  const isArrayOfFiles = (value) => {
6641
7054
  return Array.isArray(value) && value[0] instanceof File;
6642
7055
  };
6643
- const separateFilesFromValues = (payload) => {
6644
- const { values } = payload;
7056
+ const separateFilesFromValues = (values) => {
6645
7057
  const files = {};
6646
7058
  const newValues = {};
6647
7059
  for (const key in values) {
@@ -6656,17 +7068,13 @@ var __publicField = (obj, key, value) => {
6656
7068
  newValues[key] = value;
6657
7069
  }
6658
7070
  }
6659
- const payloadWithoutFiles = {
6660
- ...payload,
6661
- values: newValues
6662
- };
6663
- return { payloadWithoutFiles, files };
7071
+ return { values: newValues, files };
6664
7072
  };
6665
7073
  class UserFormSubmissionService extends BaseApiService {
6666
7074
  constructor() {
6667
7075
  super(...arguments);
6668
7076
  // Attach files to submission, after uploading them to S3
6669
- __publicField(this, "getAttachFilesPromises", (files, payload) => {
7077
+ __publicField(this, "getAttachFilesPromises", (files, submission) => {
6670
7078
  const { store } = this.client;
6671
7079
  return Object.entries(files).map(async ([key, fileArray]) => {
6672
7080
  const attachResults = [];
@@ -6676,24 +7084,27 @@ var __publicField = (obj, key, value) => {
6676
7084
  const [fileProps] = await this.client.files.uploadFileToS3(sha1);
6677
7085
  const submissionAttachmentPayload = offline({
6678
7086
  ...fileProps,
6679
- submission: payload.offline_id,
7087
+ submission: submission.offline_id,
6680
7088
  field_identifier: key
6681
7089
  });
6682
7090
  const attach = await this.enqueueRequest({
6683
7091
  description: "Attach file to form submission",
6684
7092
  method: HttpMethod.POST,
6685
- url: `/forms/submission/${payload.offline_id}/attachments/`,
7093
+ url: `/forms/submission/${submission.offline_id}/attachments/`,
6686
7094
  payload: submissionAttachmentPayload,
6687
- blockers: [payload.component, payload.component_stage, payload.issue, payload.form_revision].filter(
6688
- (x) => x !== void 0
6689
- ),
7095
+ blockers: [
7096
+ submission.component,
7097
+ submission.component_stage,
7098
+ submission.issue,
7099
+ submission.form_revision
7100
+ ].filter((x) => x !== void 0),
6690
7101
  blocks: [submissionAttachmentPayload.offline_id]
6691
7102
  });
6692
7103
  const offlinePayload = {
6693
7104
  ...submissionAttachmentPayload,
6694
7105
  file: URL.createObjectURL(file)
6695
7106
  };
6696
- store.dispatch(addUserFormSubmissionAttachment(offlinePayload));
7107
+ store.dispatch(addFormSubmissionAttachment(offlinePayload));
6697
7108
  attachResults.push(attach);
6698
7109
  }
6699
7110
  return attachResults;
@@ -6707,70 +7118,113 @@ var __publicField = (obj, key, value) => {
6707
7118
  if (!activeProjectId) {
6708
7119
  throw new Error("Expected an active project");
6709
7120
  }
6710
- const { payloadWithoutFiles, files } = separateFilesFromValues(payload);
7121
+ const { values, files } = separateFilesFromValues(payload.values);
7122
+ const offlineSubmission = {
7123
+ ...payload,
7124
+ values,
7125
+ created_by: state.userReducer.currentUser.id,
7126
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString()
7127
+ };
6711
7128
  const promise = this.enqueueRequest({
6712
7129
  description: "Respond to form",
6713
7130
  method: HttpMethod.POST,
6714
7131
  url: `/forms/revisions/${payload.form_revision}/respond/`,
6715
- payload: { ...payloadWithoutFiles, project: activeProjectId },
7132
+ payload: { ...offlineSubmission, project: activeProjectId },
6716
7133
  blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
6717
7134
  (x) => x !== void 0
6718
7135
  ),
6719
7136
  blocks: [payload.offline_id]
6720
7137
  });
6721
- const attachFilesPromises = this.getAttachFilesPromises(files, payload);
6722
- const now = (/* @__PURE__ */ new Date()).toISOString();
6723
- const fullOfflineResult = {
6724
- ...payload,
6725
- created_by: state.userReducer.currentUser.id,
6726
- created_at: now,
6727
- updated_at: now
6728
- };
6729
- const offlineResultWithoutFiles = {
6730
- ...fullOfflineResult,
6731
- ...payloadWithoutFiles
6732
- };
6733
- store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
7138
+ const attachFilesPromises = this.getAttachFilesPromises(files, offlineSubmission);
7139
+ store.dispatch(addFormSubmission(offlineSubmission));
6734
7140
  void promise.then((result) => {
6735
7141
  store.dispatch(addActiveProjectFormSubmissionsCount(1));
6736
- store.dispatch(updateOrCreateUserFormSubmission(result));
7142
+ store.dispatch(setFormSubmission(result));
6737
7143
  return result;
6738
7144
  }).catch(() => {
6739
- store.dispatch(deleteUserFormSubmission(payload.offline_id));
7145
+ store.dispatch(deleteFormSubmission(payload.offline_id));
6740
7146
  store.dispatch(addActiveProjectFormSubmissionsCount(-1));
6741
7147
  });
6742
7148
  const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
6743
- return [fullOfflineResult, settledPromise];
7149
+ return [offlineSubmission, settledPromise];
6744
7150
  }
6745
- update(submission) {
7151
+ // Note currently the bulkAdd method is specific to form submissions for components
7152
+ // TODO: adapt the support bulk adding to any model type
7153
+ bulkAdd(args) {
7154
+ const { form_revision, values: argsValues, component_offline_ids } = args;
6746
7155
  const { store } = this.client;
6747
- const { payloadWithoutFiles, files } = separateFilesFromValues(submission);
6748
- if (!("created_by" in payloadWithoutFiles) || !("created_at" in payloadWithoutFiles)) {
6749
- throw new Error("Expected payloadWithoutFiles to have created_by and created_at fields.");
7156
+ const submissions = [];
7157
+ const submissionOfflineIds = [];
7158
+ const offline_ids_to_component_ids = [];
7159
+ let attachFilesPromises = [];
7160
+ const { values, files } = separateFilesFromValues(argsValues);
7161
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
7162
+ const createdBy = store.getState().userReducer.currentUser.id;
7163
+ for (const component_id of component_offline_ids) {
7164
+ const submission = offline({
7165
+ form_revision,
7166
+ values,
7167
+ created_by: createdBy,
7168
+ submitted_at: submittedAt,
7169
+ component: component_id
7170
+ });
7171
+ attachFilesPromises = attachFilesPromises.concat(this.getAttachFilesPromises(files, submission));
7172
+ submissionOfflineIds.push(submission.offline_id);
7173
+ offline_ids_to_component_ids.push([submission.offline_id, component_id]);
7174
+ submissions.push(submission);
6750
7175
  }
7176
+ store.dispatch(addFormSubmissions(submissions));
7177
+ const promise = this.enqueueRequest({
7178
+ description: "Bulk add form submissions",
7179
+ method: HttpMethod.POST,
7180
+ url: `/forms/revisions/${form_revision}/bulk-respond/`,
7181
+ payload: {
7182
+ form_data: values,
7183
+ submitted_at: submittedAt,
7184
+ offline_ids_to_component_ids
7185
+ },
7186
+ blockers: component_offline_ids,
7187
+ blocks: submissionOfflineIds
7188
+ });
7189
+ promise.then((createdSubmissions) => {
7190
+ store.dispatch(updateFormSubmissions(createdSubmissions));
7191
+ }).catch(() => {
7192
+ store.dispatch(deleteFormSubmissions(submissionOfflineIds));
7193
+ });
7194
+ return [submissions, promise.then(() => Promise.all(attachFilesPromises).then(() => promise))];
7195
+ }
7196
+ update(submission) {
7197
+ const { store } = this.client;
7198
+ const { values, files } = separateFilesFromValues(submission.values);
6751
7199
  const attachFilesPromises = this.getAttachFilesPromises(files, submission);
6752
- const fullResult = {
6753
- ...payloadWithoutFiles,
6754
- updated_at: (/* @__PURE__ */ new Date()).toISOString()
7200
+ const offlineSubmission = {
7201
+ ...submission,
7202
+ values
6755
7203
  };
6756
- store.dispatch(updateOrCreateUserFormSubmission(fullResult));
7204
+ const submissionToBeUpdated = store.getState().formSubmissionReducer.formSubmissions[submission.offline_id];
7205
+ store.dispatch(updateFormSubmission(offlineSubmission));
6757
7206
  const promise = this.enqueueRequest({
6758
7207
  description: "Patch form submission",
6759
7208
  method: HttpMethod.PATCH,
6760
7209
  url: `/forms/submissions/${submission.offline_id}/`,
6761
- payload: fullResult,
6762
- blockers: [fullResult.issue, fullResult.component, fullResult.component_stage].filter(
7210
+ payload: offlineSubmission,
7211
+ blockers: [offlineSubmission.issue, offlineSubmission.component, offlineSubmission.component_stage].filter(
6763
7212
  (x) => x !== void 0
6764
7213
  ),
6765
- blocks: [fullResult.offline_id]
7214
+ blocks: [offlineSubmission.offline_id]
7215
+ });
7216
+ promise.then((createdSubmission) => {
7217
+ store.dispatch(setFormSubmission(createdSubmission));
7218
+ }).catch(() => {
7219
+ store.dispatch(setFormSubmission(submissionToBeUpdated));
6766
7220
  });
6767
- return Promise.all([promise, ...attachFilesPromises]).then(() => promise);
7221
+ return [offlineSubmission, Promise.all([promise, ...attachFilesPromises]).then(() => promise)];
6768
7222
  }
6769
7223
  async delete(submissionId) {
6770
7224
  const { store } = this.client;
6771
7225
  const state = store.getState();
6772
- const submission = state.userFormReducer.submissions[submissionId];
6773
- store.dispatch(deleteUserFormSubmission(submissionId));
7226
+ const submission = state.formSubmissionReducer.formSubmissions[submissionId];
7227
+ store.dispatch(deleteFormSubmission(submissionId));
6774
7228
  store.dispatch(addActiveProjectFormSubmissionsCount(-1));
6775
7229
  try {
6776
7230
  return await this.enqueueRequest({
@@ -6781,10 +7235,8 @@ var __publicField = (obj, key, value) => {
6781
7235
  blocks: []
6782
7236
  });
6783
7237
  } catch (e) {
6784
- if (submission) {
6785
- store.dispatch(addActiveProjectFormSubmissionsCount(1));
6786
- store.dispatch(updateOrCreateUserFormSubmission(submission));
6787
- }
7238
+ store.dispatch(addActiveProjectFormSubmissionsCount(1));
7239
+ store.dispatch(addFormSubmission(submission));
6788
7240
  throw e;
6789
7241
  }
6790
7242
  }
@@ -6798,7 +7250,7 @@ var __publicField = (obj, key, value) => {
6798
7250
  blockers: [],
6799
7251
  blocks: []
6800
7252
  });
6801
- store.dispatch(setUserFormSubmissions(submissions));
7253
+ store.dispatch(setFormSubmissions(submissions));
6802
7254
  const attachments = await this.enqueueRequest({
6803
7255
  description: "Fetch form attachments",
6804
7256
  method: HttpMethod.GET,
@@ -6806,7 +7258,7 @@ var __publicField = (obj, key, value) => {
6806
7258
  blockers: [],
6807
7259
  blocks: []
6808
7260
  });
6809
- store.dispatch(setUserFormSubmissionAttachments(attachments));
7261
+ store.dispatch(setFormSubmissionAttachments(attachments));
6810
7262
  }
6811
7263
  }
6812
7264
  class WorkspaceService extends BaseApiService {
@@ -7540,6 +7992,7 @@ var __publicField = (obj, key, value) => {
7540
7992
  __publicField(this, "organizationAccess", new OrganizationAccessService(this));
7541
7993
  __publicField(this, "issues", new IssueService(this));
7542
7994
  __publicField(this, "issueComments", new IssueCommentService(this));
7995
+ __publicField(this, "issueUpdates", new IssueUpdateService(this));
7543
7996
  __publicField(this, "workspaces", new WorkspaceService(this));
7544
7997
  __publicField(this, "main", new MainService(this));
7545
7998
  __publicField(this, "components", new ComponentService(this));
@@ -13013,52 +13466,54 @@ var __publicField = (obj, key, value) => {
13013
13466
  Footer,
13014
13467
  Loading
13015
13468
  };
13016
- const ImageCard = React.memo((props) => {
13017
- const { file, alt, error: error2, size, rightSlot, className, truncateLength, ...rest } = props;
13018
- const fileCardRef = React.useRef(null);
13019
- const imageInsetRef = React.useRef(null);
13020
- const fileCardSize = blocks.useSize(fileCardRef);
13021
- React.useLayoutEffect(() => {
13022
- if (!imageInsetRef.current || !fileCardSize)
13023
- return;
13024
- imageInsetRef.current.style.height = `${fileCardSize.height * 4}px`;
13025
- }, [fileCardSize]);
13026
- const fileName2 = React.useMemo(() => {
13027
- if (!file)
13028
- return;
13029
- return truncateLength !== void 0 ? truncate(file.name, truncateLength) : file.name;
13030
- }, [file, truncateLength]);
13031
- return /* @__PURE__ */ jsxRuntime.jsxs(
13032
- Flex,
13033
- {
13034
- className: classNames$1(className, styles$4.ImageCard),
13035
- width: "100%",
13036
- direction: "column",
13037
- position: "relative",
13038
- height: "max-content",
13039
- gap: "0",
13040
- ...rest,
13041
- children: [
13042
- !file && !error2 && /* @__PURE__ */ jsxRuntime.jsx(Flex, { width: "100%", height: "100%", align: "center", justify: "center", position: "absolute", children: /* @__PURE__ */ jsxRuntime.jsx(blocks.Spinner, {}) }),
13043
- /* @__PURE__ */ jsxRuntime.jsx(Inset, { className: styles$4.ImageInset, ref: imageInsetRef, clip: "padding-box", side: "y", pb: "0", children: file && !error2 && /* @__PURE__ */ jsxRuntime.jsx("img", { className: styles$4.Image, src: URL.createObjectURL(file), alt: alt ?? file.name }) }),
13044
- /* @__PURE__ */ jsxRuntime.jsx(
13045
- blocks.OvermapItem,
13046
- {
13047
- className: classNames$1(styles$4.Footer, {
13048
- [styles$4.Loading]: !file
13049
- }),
13050
- size,
13051
- ref: fileCardRef,
13052
- leftSlot: error2 ? /* @__PURE__ */ jsxRuntime.jsx(blocks.RiIcon, { icon: "RiFileWarningLine" }) : file && /* @__PURE__ */ jsxRuntime.jsx(FileIcon, { fileType: file.type }),
13053
- rightSlot,
13054
- children: error2 ?? fileName2
13055
- }
13056
- )
13057
- ]
13058
- }
13059
- );
13060
- });
13061
- ImageCard.displayName = "ImageCard";
13469
+ const ImageCard = React.memo(
13470
+ React.forwardRef((props, forwardedRef) => {
13471
+ const { file, alt, error: error2, size, rightSlot, className, truncateLength, ...rest } = props;
13472
+ const fileCardRef = React.useRef(null);
13473
+ const imageInsetRef = React.useRef(null);
13474
+ const fileCardSize = blocks.useSize(fileCardRef);
13475
+ React.useLayoutEffect(() => {
13476
+ if (!imageInsetRef.current || !fileCardSize)
13477
+ return;
13478
+ imageInsetRef.current.style.height = `${fileCardSize.height * 4}px`;
13479
+ }, [fileCardSize]);
13480
+ const fileName2 = React.useMemo(() => {
13481
+ if (!file)
13482
+ return;
13483
+ return truncateLength !== void 0 ? truncate(file.name, truncateLength) : file.name;
13484
+ }, [file, truncateLength]);
13485
+ return /* @__PURE__ */ jsxRuntime.jsxs(
13486
+ Flex,
13487
+ {
13488
+ className: classNames$1(className, styles$4.ImageCard),
13489
+ width: "100%",
13490
+ direction: "column",
13491
+ position: "relative",
13492
+ height: "max-content",
13493
+ gap: "0",
13494
+ ref: forwardedRef,
13495
+ ...rest,
13496
+ children: [
13497
+ !file && !error2 && /* @__PURE__ */ jsxRuntime.jsx(Flex, { width: "100%", height: "100%", align: "center", justify: "center", position: "absolute", children: /* @__PURE__ */ jsxRuntime.jsx(blocks.Spinner, {}) }),
13498
+ /* @__PURE__ */ jsxRuntime.jsx(Inset, { className: styles$4.ImageInset, ref: imageInsetRef, clip: "padding-box", side: "y", pb: "0", children: file && !error2 && /* @__PURE__ */ jsxRuntime.jsx("img", { className: styles$4.Image, src: URL.createObjectURL(file), alt: alt ?? file.name }) }),
13499
+ /* @__PURE__ */ jsxRuntime.jsx(
13500
+ blocks.OvermapItem,
13501
+ {
13502
+ className: classNames$1(styles$4.Footer, {
13503
+ [styles$4.Loading]: !file
13504
+ }),
13505
+ size,
13506
+ ref: fileCardRef,
13507
+ leftSlot: error2 ? /* @__PURE__ */ jsxRuntime.jsx(blocks.RiIcon, { icon: "RiFileWarningLine" }) : file && /* @__PURE__ */ jsxRuntime.jsx(FileIcon, { fileType: file.type }),
13508
+ rightSlot,
13509
+ children: error2 ?? fileName2
13510
+ }
13511
+ )
13512
+ ]
13513
+ }
13514
+ );
13515
+ })
13516
+ );
13062
13517
  const UploadInput = React.memo((props) => {
13063
13518
  var _a2;
13064
13519
  const [{ inputId, labelId, size, severity, helpText, showInputOnly, field, fieldProps }, rest] = useFormikInput(props);
@@ -13657,7 +14112,7 @@ var __publicField = (obj, key, value) => {
13657
14112
  };
13658
14113
  const useAttachImagesToFormRevisionFields = (revision) => {
13659
14114
  const { sdk } = useSDK();
13660
- const attachments = useAppSelector(selectRevisionAttachments((revision == null ? void 0 : revision.offline_id) ?? ""));
14115
+ const attachments = useAppSelector(selectAttachmentsOfFormRevision((revision == null ? void 0 : revision.offline_id) ?? ""));
13661
14116
  return React.useMemo(() => {
13662
14117
  if (!revision || !attachments)
13663
14118
  return revision;
@@ -13739,7 +14194,7 @@ var __publicField = (obj, key, value) => {
13739
14194
  const FormSubmissionViewer = React.memo(
13740
14195
  React.forwardRef((props, ref) => {
13741
14196
  const { submission, showFormDescription = false, showFormTitle = true } = props;
13742
- const revision = useAppSelector(selectFormRevision(submission.form_revision));
14197
+ const revision = useAppSelector(selectUserFormRevision(submission.form_revision));
13743
14198
  const { sdk } = useSDK();
13744
14199
  if (!revision) {
13745
14200
  throw new Error(
@@ -13754,7 +14209,7 @@ var __publicField = (obj, key, value) => {
13754
14209
  return formRevisionToSchema(revisionWithImages, { readonly: true });
13755
14210
  }, [revisionWithImages]);
13756
14211
  const submissionValuesWithAttachments = React.useMemo(() => {
13757
- const attachments = selectSubmissionAttachments(submission.offline_id)(sdk.store.getState()) ?? [];
14212
+ const attachments = selectAttachmentsOfFormSubmission(submission.offline_id)(sdk.store.getState()) ?? [];
13758
14213
  const downloadedAttachments = {};
13759
14214
  for (const attachment of attachments) {
13760
14215
  const promise = sdk.files.fetchFileFromUrl(attachment.file, attachment.file_sha1, attachment.file_name);
@@ -13932,16 +14387,13 @@ var __publicField = (obj, key, value) => {
13932
14387
  const { submission, onSubmissionClick, compact, labelType, rowDecorator } = props;
13933
14388
  const currentUser = useAppSelector(selectCurrentUser);
13934
14389
  const createdBy = useAppSelector(selectUser("created_by" in submission ? submission.created_by : currentUser.id));
13935
- const dateToUse = getCreatedAtOrSubmittedAtDate(submission);
13936
- const formattedDateTime = isToday(dateToUse) ? dateToUse.toLocaleTimeString([], {
13937
- hour: "2-digit",
13938
- minute: "2-digit"
13939
- }) : getLocalDateString(dateToUse);
13940
- const revision = useAppSelector(selectFormRevision(submission.form_revision));
14390
+ const dateToUse = submission.submitted_at;
14391
+ const formattedDateTime = getLocalDateString(dateToUse);
14392
+ const revision = useAppSelector(selectUserFormRevision(submission.form_revision));
13941
14393
  if (!revision) {
13942
14394
  throw new Error(`Could not find revision ${submission.form_revision} for submission ${submission.offline_id}.`);
13943
14395
  }
13944
- const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevision(revision.form))) == null ? void 0 : _a2.revision;
14396
+ const latestRevisionNumber = (_a2 = useAppSelector(selectLatestFormRevisionOfForm(revision.form))) == null ? void 0 : _a2.revision;
13945
14397
  const creatorProfileSrc = useFileSrc({
13946
14398
  file: (createdBy == null ? void 0 : createdBy.profile.file) ?? null,
13947
14399
  fileSha1: (createdBy == null ? void 0 : createdBy.profile.file_sha1) ?? null
@@ -13972,10 +14424,6 @@ var __publicField = (obj, key, value) => {
13972
14424
  return row;
13973
14425
  });
13974
14426
  FormSubmissionBrowserEntry.displayName = "FormSubmissionBrowserEntry";
13975
- const getCreatedAtOrSubmittedAtDate = (submission) => {
13976
- const date = "created_at" in submission ? submission.created_at : submission.submitted_at;
13977
- return new Date(date);
13978
- };
13979
14427
  const FormSubmissionBrowser = React.memo((props) => {
13980
14428
  const {
13981
14429
  formId: formId2,
@@ -13989,10 +14437,10 @@ var __publicField = (obj, key, value) => {
13989
14437
  if (!!formId2 === !!propSubmissions) {
13990
14438
  throw new Error("Either formId or submissions must be provided, but not both.");
13991
14439
  }
13992
- const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectSubmissionsForForm(formId2));
14440
+ const submissions = useAppSelector(propSubmissions ? () => propSubmissions : selectFormSubmissionsOfForm(formId2));
13993
14441
  const sortedSubmissions = React.useMemo(
13994
14442
  () => submissions == null ? void 0 : submissions.sort((a, b) => {
13995
- return getCreatedAtOrSubmittedAtDate(b).getTime() - getCreatedAtOrSubmittedAtDate(a).getTime();
14443
+ return a.submitted_at.localeCompare(b.submitted_at);
13996
14444
  }),
13997
14445
  [submissions]
13998
14446
  );
@@ -14195,17 +14643,15 @@ var __publicField = (obj, key, value) => {
14195
14643
  Action.key
14196
14644
  )) }),
14197
14645
  /* @__PURE__ */ jsxRuntime.jsx(Box, { display: forMobile(true, "block"), children: /* @__PURE__ */ jsxRuntime.jsx(
14198
- blocks.DropdownItemMenu,
14646
+ blocks.OvermapDropdownMenu,
14199
14647
  {
14200
14648
  trigger: /* @__PURE__ */ jsxRuntime.jsx(blocks.IconButton, { variant: "ghost", "aria-label": "Actions menu", children: /* @__PURE__ */ jsxRuntime.jsx(blocks.RiIcon, { icon: "RiMore2Line" }) }),
14201
14649
  items: actions.map((Action) => {
14202
14650
  var _a2;
14203
14651
  return {
14204
- content: /* @__PURE__ */ jsxRuntime.jsxs(blocks.Flex, { gap: "2", align: "center", children: [
14205
- /* @__PURE__ */ jsxRuntime.jsx(Action.Icon, {}),
14206
- Action.text
14207
- ] }, Action.key),
14208
- onSelect: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
14652
+ leftSlot: /* @__PURE__ */ jsxRuntime.jsx(Action.Icon, {}),
14653
+ children: Action.text,
14654
+ onClick: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
14209
14655
  };
14210
14656
  })
14211
14657
  }
@@ -14263,10 +14709,8 @@ var __publicField = (obj, key, value) => {
14263
14709
  const field = FieldTypeToClsMapping[identifier];
14264
14710
  const Icon = field.Icon;
14265
14711
  return {
14266
- content: /* @__PURE__ */ jsxRuntime.jsxs(blocks.Flex, { align: "center", gap: "2", children: [
14267
- /* @__PURE__ */ jsxRuntime.jsx(Icon, {}),
14268
- /* @__PURE__ */ jsxRuntime.jsx(blocks.Text, { children: field.fieldTypeName })
14269
- ] }, identifier),
14712
+ children: field.fieldTypeName,
14713
+ leftSlot: /* @__PURE__ */ jsxRuntime.jsx(Icon, {}),
14270
14714
  value: identifier,
14271
14715
  onSelect: () => {
14272
14716
  onSelect(identifier);
@@ -14470,7 +14914,7 @@ var __publicField = (obj, key, value) => {
14470
14914
  }
14471
14915
  ),
14472
14916
  /* @__PURE__ */ jsxRuntime.jsxs(blocks.Flex, { align: "center", gap: "3", children: [
14473
- /* @__PURE__ */ jsxRuntime.jsx(blocks.Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.content }),
14917
+ /* @__PURE__ */ jsxRuntime.jsx(blocks.Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.children }),
14474
14918
  showPopoverInputs && /* @__PURE__ */ jsxRuntime.jsx(FieldSettingsPopover, { popoverInputs, hasError: popoverHasErrors })
14475
14919
  ] }),
14476
14920
  resolvedImage && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
@@ -14831,7 +15275,7 @@ var __publicField = (obj, key, value) => {
14831
15275
  )),
14832
15276
  droppableProvided.placeholder,
14833
15277
  /* @__PURE__ */ jsxRuntime.jsx(
14834
- blocks.DropdownItemMenu,
15278
+ blocks.OvermapDropdownMenu,
14835
15279
  {
14836
15280
  trigger: /* @__PURE__ */ jsxRuntime.jsxs(blocks.Button, { type: "button", variant: "soft", children: [
14837
15281
  /* @__PURE__ */ jsxRuntime.jsx(blocks.RiIcon, { icon: "RiAddLine" }),
@@ -15266,6 +15710,8 @@ var __publicField = (obj, key, value) => {
15266
15710
  exports2.IssuePriority = IssuePriority;
15267
15711
  exports2.IssueService = IssueService;
15268
15712
  exports2.IssueStatus = IssueStatus;
15713
+ exports2.IssueUpdateChange = IssueUpdateChange;
15714
+ exports2.IssueUpdateService = IssueUpdateService;
15269
15715
  exports2.LicenseLevel = LicenseLevel;
15270
15716
  exports2.LicenseService = LicenseService;
15271
15717
  exports2.LicenseStatus = LicenseStatus;
@@ -15311,6 +15757,7 @@ var __publicField = (obj, key, value) => {
15311
15757
  exports2.VerificationCodeType = VerificationCodeType;
15312
15758
  exports2.WorkspaceService = WorkspaceService;
15313
15759
  exports2.YELLOW = YELLOW;
15760
+ exports2._selectLatestFormRevision = _selectLatestFormRevision;
15314
15761
  exports2._setLatestRetryTime = _setLatestRetryTime;
15315
15762
  exports2.acceptProjectInvite = acceptProjectInvite;
15316
15763
  exports2.addActiveProjectFormSubmissionsCount = addActiveProjectFormSubmissionsCount;
@@ -15326,9 +15773,23 @@ var __publicField = (obj, key, value) => {
15326
15773
  exports2.addDocuments = addDocuments;
15327
15774
  exports2.addEmailDomain = addEmailDomain;
15328
15775
  exports2.addFavouriteProjectId = addFavouriteProjectId;
15776
+ exports2.addForm = addForm;
15777
+ exports2.addFormRevision = addFormRevision;
15778
+ exports2.addFormRevisionAttachment = addFormRevisionAttachment;
15779
+ exports2.addFormRevisionAttachments = addFormRevisionAttachments;
15780
+ exports2.addFormRevisions = addFormRevisions;
15781
+ exports2.addFormSubmission = addFormSubmission;
15782
+ exports2.addFormSubmissionAttachment = addFormSubmissionAttachment;
15783
+ exports2.addFormSubmissionAttachments = addFormSubmissionAttachments;
15784
+ exports2.addFormSubmissions = addFormSubmissions;
15785
+ exports2.addForms = addForms;
15329
15786
  exports2.addIssue = addIssue;
15330
15787
  exports2.addIssueAttachment = addIssueAttachment;
15331
15788
  exports2.addIssueAttachments = addIssueAttachments;
15789
+ exports2.addIssueComment = addIssueComment;
15790
+ exports2.addIssueComments = addIssueComments;
15791
+ exports2.addIssueUpdate = addIssueUpdate;
15792
+ exports2.addIssueUpdates = addIssueUpdates;
15332
15793
  exports2.addLicenses = addLicenses;
15333
15794
  exports2.addOrReplaceCategories = addOrReplaceCategories;
15334
15795
  exports2.addOrReplaceIssueComment = addOrReplaceIssueComment;
@@ -15342,13 +15803,6 @@ var __publicField = (obj, key, value) => {
15342
15803
  exports2.addStageCompletions = addStageCompletions;
15343
15804
  exports2.addStages = addStages;
15344
15805
  exports2.addToRecentIssues = addToRecentIssues;
15345
- exports2.addUserForm = addUserForm;
15346
- exports2.addUserFormRevision = addUserFormRevision;
15347
- exports2.addUserFormRevisionAttachment = addUserFormRevisionAttachment;
15348
- exports2.addUserFormRevisions = addUserFormRevisions;
15349
- exports2.addUserFormSubmissionAttachment = addUserFormSubmissionAttachment;
15350
- exports2.addUserFormSubmissions = addUserFormSubmissions;
15351
- exports2.addUserForms = addUserForms;
15352
15806
  exports2.addUsers = addUsers;
15353
15807
  exports2.addWorkspace = addWorkspace;
15354
15808
  exports2.areArraysEqual = areArraysEqual;
@@ -15379,12 +15833,16 @@ var __publicField = (obj, key, value) => {
15379
15833
  exports2.defaultBadgeColor = defaultBadgeColor;
15380
15834
  exports2.defaultStore = defaultStore;
15381
15835
  exports2.deleteComponentType = deleteComponentType;
15836
+ exports2.deleteForm = deleteForm;
15837
+ exports2.deleteFormRevision = deleteFormRevision;
15838
+ exports2.deleteFormRevisionAttachment = deleteFormRevisionAttachment;
15839
+ exports2.deleteFormRevisionAttachments = deleteFormRevisionAttachments;
15840
+ exports2.deleteFormRevisions = deleteFormRevisions;
15841
+ exports2.deleteFormSubmission = deleteFormSubmission;
15842
+ exports2.deleteFormSubmissionAttachment = deleteFormSubmissionAttachment;
15843
+ exports2.deleteFormSubmissionAttachments = deleteFormSubmissionAttachments;
15844
+ exports2.deleteFormSubmissions = deleteFormSubmissions;
15382
15845
  exports2.deleteProject = deleteProject;
15383
- exports2.deleteUserForm = deleteUserForm;
15384
- exports2.deleteUserFormRevision = deleteUserFormRevision;
15385
- exports2.deleteUserFormRevisions = deleteUserFormRevisions;
15386
- exports2.deleteUserFormSubmission = deleteUserFormSubmission;
15387
- exports2.deleteUserFormSubmissions = deleteUserFormSubmissions;
15388
15846
  exports2.dequeue = dequeue;
15389
15847
  exports2.deserialize = deserialize;
15390
15848
  exports2.deserializeField = deserializeField;
@@ -15413,7 +15871,11 @@ var __publicField = (obj, key, value) => {
15413
15871
  exports2.fileSlice = fileSlice;
15414
15872
  exports2.fileToBlob = fileToBlob;
15415
15873
  exports2.flipCoordinates = flipCoordinates;
15874
+ exports2.formRevisionReducer = formRevisionReducer;
15416
15875
  exports2.formRevisionToSchema = formRevisionToSchema;
15876
+ exports2.formRevisionsSlice = formRevisionsSlice;
15877
+ exports2.formSubmissionReducer = formSubmissionReducer;
15878
+ exports2.formSubmissionSlice = formSubmissionSlice;
15417
15879
  exports2.forms = index;
15418
15880
  exports2.fullComponentMarkerSize = fullComponentMarkerSize;
15419
15881
  exports2.generateBadgeColors = generateBadgeColors;
@@ -15488,6 +15950,9 @@ var __publicField = (obj, key, value) => {
15488
15950
  exports2.removeIssue = removeIssue;
15489
15951
  exports2.removeIssueAttachment = removeIssueAttachment;
15490
15952
  exports2.removeIssueComment = removeIssueComment;
15953
+ exports2.removeIssueComments = removeIssueComments;
15954
+ exports2.removeIssueUpdate = removeIssueUpdate;
15955
+ exports2.removeIssueUpdates = removeIssueUpdates;
15491
15956
  exports2.removeOrganizationAccess = removeOrganizationAccess;
15492
15957
  exports2.removeProjectAccess = removeProjectAccess;
15493
15958
  exports2.removeProjectAccessesOfProject = removeProjectAccessesOfProject;
@@ -15533,6 +15998,8 @@ var __publicField = (obj, key, value) => {
15533
15998
  exports2.selectAttachmentsOfComponentByType = selectAttachmentsOfComponentByType;
15534
15999
  exports2.selectAttachmentsOfComponentType = selectAttachmentsOfComponentType;
15535
16000
  exports2.selectAttachmentsOfComponentTypeByType = selectAttachmentsOfComponentTypeByType;
16001
+ exports2.selectAttachmentsOfFormRevision = selectAttachmentsOfFormRevision;
16002
+ exports2.selectAttachmentsOfFormSubmission = selectAttachmentsOfFormSubmission;
15536
16003
  exports2.selectAttachmentsOfIssue = selectAttachmentsOfIssue;
15537
16004
  exports2.selectAttachmentsOfIssueByType = selectAttachmentsOfIssueByType;
15538
16005
  exports2.selectAttachmentsOfProject = selectAttachmentsOfProject;
@@ -15554,6 +16021,7 @@ var __publicField = (obj, key, value) => {
15554
16021
  exports2.selectComponentTypeForm = selectComponentTypeForm;
15555
16022
  exports2.selectComponentTypeFromComponent = selectComponentTypeFromComponent;
15556
16023
  exports2.selectComponentTypeFromComponents = selectComponentTypeFromComponents;
16024
+ exports2.selectComponentTypeStagesMapping = selectComponentTypeStagesMapping;
15557
16025
  exports2.selectComponentTypes = selectComponentTypes;
15558
16026
  exports2.selectComponentTypesByName = selectComponentTypesByName;
15559
16027
  exports2.selectComponentTypesFromIds = selectComponentTypesFromIds;
@@ -15561,6 +16029,7 @@ var __publicField = (obj, key, value) => {
15561
16029
  exports2.selectComponents = selectComponents;
15562
16030
  exports2.selectComponentsByType = selectComponentsByType;
15563
16031
  exports2.selectComponentsFromComponentType = selectComponentsFromComponentType;
16032
+ exports2.selectComponentsMapping = selectComponentsMapping;
15564
16033
  exports2.selectCreateProjectType = selectCreateProjectType;
15565
16034
  exports2.selectCurrentUser = selectCurrentUser;
15566
16035
  exports2.selectDeletedRequests = selectDeletedRequests;
@@ -15578,7 +16047,17 @@ var __publicField = (obj, key, value) => {
15578
16047
  exports2.selectFavouriteProjects = selectFavouriteProjects;
15579
16048
  exports2.selectFileAttachmentsOfIssue = selectFileAttachmentsOfIssue;
15580
16049
  exports2.selectFilteredUserForms = selectFilteredUserForms;
15581
- exports2.selectFormRevision = selectFormRevision;
16050
+ exports2.selectFormRevisionMapping = selectFormRevisionMapping;
16051
+ exports2.selectFormRevisions = selectFormRevisions;
16052
+ exports2.selectFormRevisionsOfForm = selectFormRevisionsOfForm;
16053
+ exports2.selectFormSubmission = selectFormSubmission;
16054
+ exports2.selectFormSubmissionAttachmentsMapping = selectFormSubmissionAttachmentsMapping;
16055
+ exports2.selectFormSubmissions = selectFormSubmissions;
16056
+ exports2.selectFormSubmissionsByComponents = selectFormSubmissionsByComponents;
16057
+ exports2.selectFormSubmissionsMapping = selectFormSubmissionsMapping;
16058
+ exports2.selectFormSubmissionsOfComponent = selectFormSubmissionsOfComponent;
16059
+ exports2.selectFormSubmissionsOfForm = selectFormSubmissionsOfForm;
16060
+ exports2.selectFormSubmissionsOfIssue = selectFormSubmissionsOfIssue;
15582
16061
  exports2.selectHiddenCategoryCount = selectHiddenCategoryCount;
15583
16062
  exports2.selectHiddenComponentTypeIds = selectHiddenComponentTypeIds;
15584
16063
  exports2.selectIsFetchingInitialData = selectIsFetchingInitialData;
@@ -15589,11 +16068,13 @@ var __publicField = (obj, key, value) => {
15589
16068
  exports2.selectIssueAttachmentMapping = selectIssueAttachmentMapping;
15590
16069
  exports2.selectIssueAttachments = selectIssueAttachments;
15591
16070
  exports2.selectIssueMapping = selectIssueMapping;
16071
+ exports2.selectIssueUpdateMapping = selectIssueUpdateMapping;
16072
+ exports2.selectIssueUpdatesOfIssue = selectIssueUpdatesOfIssue;
15592
16073
  exports2.selectIssues = selectIssues;
15593
- exports2.selectLatestFormRevision = selectLatestFormRevision;
16074
+ exports2.selectLatestFormRevisionByForm = selectLatestFormRevisionByForm;
16075
+ exports2.selectLatestFormRevisionOfForm = selectLatestFormRevisionOfForm;
16076
+ exports2.selectLatestFormRevisionsOfComponentTypes = selectLatestFormRevisionsOfComponentTypes;
15594
16077
  exports2.selectLatestRetryTime = selectLatestRetryTime;
15595
- exports2.selectLatestRevisionByFormId = selectLatestRevisionByFormId;
15596
- exports2.selectLatestRevisionsFromComponentTypeIds = selectLatestRevisionsFromComponentTypeIds;
15597
16078
  exports2.selectLicense = selectLicense;
15598
16079
  exports2.selectLicenseForProject = selectLicenseForProject;
15599
16080
  exports2.selectLicenses = selectLicenses;
@@ -15631,8 +16112,6 @@ var __publicField = (obj, key, value) => {
15631
16112
  exports2.selectRecentIssuesAsSearchResults = selectRecentIssuesAsSearchResults;
15632
16113
  exports2.selectRecentProjects = selectRecentProjects;
15633
16114
  exports2.selectRehydrated = selectRehydrated;
15634
- exports2.selectRevisionAttachments = selectRevisionAttachments;
15635
- exports2.selectRevisionsForForm = selectRevisionsForForm;
15636
16115
  exports2.selectRootDocuments = selectRootDocuments;
15637
16116
  exports2.selectShowTooltips = selectShowTooltips;
15638
16117
  exports2.selectSortedEmailDomains = selectSortedEmailDomains;
@@ -15640,21 +16119,20 @@ var __publicField = (obj, key, value) => {
15640
16119
  exports2.selectSortedOrganizationUsers = selectSortedOrganizationUsers;
15641
16120
  exports2.selectSortedProjectUsers = selectSortedProjectUsers;
15642
16121
  exports2.selectSortedProjects = selectSortedProjects;
16122
+ exports2.selectStage = selectStage;
15643
16123
  exports2.selectStageFormIdsFromStageIds = selectStageFormIdsFromStageIds;
15644
16124
  exports2.selectStageMapping = selectStageMapping;
15645
16125
  exports2.selectStages = selectStages;
15646
16126
  exports2.selectStagesFromComponentType = selectStagesFromComponentType;
15647
16127
  exports2.selectStagesFromComponentTypeIds = selectStagesFromComponentTypeIds;
15648
16128
  exports2.selectStagesFromStageIds = selectStagesFromStageIds;
15649
- exports2.selectSubmissionAttachments = selectSubmissionAttachments;
15650
- exports2.selectSubmissionsForComponent = selectSubmissionsForComponent;
15651
- exports2.selectSubmissionsForForm = selectSubmissionsForForm;
15652
- exports2.selectSubmissionsForIssue = selectSubmissionsForIssue;
15653
16129
  exports2.selectUploadUrl = selectUploadUrl;
15654
16130
  exports2.selectUsedColors = selectUsedColors;
15655
16131
  exports2.selectUser = selectUser;
15656
16132
  exports2.selectUserForm = selectUserForm;
15657
16133
  exports2.selectUserFormMapping = selectUserFormMapping;
16134
+ exports2.selectUserFormRevision = selectUserFormRevision;
16135
+ exports2.selectUserFormRevisionAttachmentsMapping = selectUserFormRevisionAttachmentsMapping;
15658
16136
  exports2.selectUsersAsMapping = selectUsersAsMapping;
15659
16137
  exports2.selectVisibleStatuses = selectVisibleStatuses;
15660
16138
  exports2.selectVisibleUserIds = selectVisibleUserIds;
@@ -15680,11 +16158,20 @@ var __publicField = (obj, key, value) => {
15680
16158
  exports2.setEnableClustering = setEnableClustering;
15681
16159
  exports2.setEnableDuplicateIssues = setEnableDuplicateIssues;
15682
16160
  exports2.setEnablePlacementMode = setEnablePlacementMode;
16161
+ exports2.setFormRevision = setFormRevision;
16162
+ exports2.setFormRevisionAttachments = setFormRevisionAttachments;
16163
+ exports2.setFormRevisions = setFormRevisions;
16164
+ exports2.setFormSubmission = setFormSubmission;
16165
+ exports2.setFormSubmissionAttachments = setFormSubmissionAttachments;
16166
+ exports2.setFormSubmissions = setFormSubmissions;
16167
+ exports2.setForms = setForms;
15683
16168
  exports2.setIsFetchingInitialData = setIsFetchingInitialData;
15684
16169
  exports2.setIsImportingProjectFile = setIsImportingProjectFile;
15685
16170
  exports2.setIsLoading = setIsLoading;
15686
16171
  exports2.setIssueAttachments = setIssueAttachments;
16172
+ exports2.setIssueComment = setIssueComment;
15687
16173
  exports2.setIssueComments = setIssueComments;
16174
+ exports2.setIssueUpdates = setIssueUpdates;
15688
16175
  exports2.setIssues = setIssues;
15689
16176
  exports2.setLicenses = setLicenses;
15690
16177
  exports2.setLoggedIn = setLoggedIn;
@@ -15702,9 +16189,6 @@ var __publicField = (obj, key, value) => {
15702
16189
  exports2.setTokens = setTokens;
15703
16190
  exports2.setTourStep = setTourStep;
15704
16191
  exports2.setUploadUrl = setUploadUrl;
15705
- exports2.setUserFormRevisionAttachments = setUserFormRevisionAttachments;
15706
- exports2.setUserFormSubmissionAttachments = setUserFormSubmissionAttachments;
15707
- exports2.setUserFormSubmissions = setUserFormSubmissions;
15708
16192
  exports2.setUsers = setUsers;
15709
16193
  exports2.setVisibleStatuses = setVisibleStatuses;
15710
16194
  exports2.setVisibleUserIds = setVisibleUserIds;
@@ -15728,11 +16212,12 @@ var __publicField = (obj, key, value) => {
15728
16212
  exports2.updateComponentAttachment = updateComponentAttachment;
15729
16213
  exports2.updateComponentTypeAttachment = updateComponentTypeAttachment;
15730
16214
  exports2.updateDocuments = updateDocuments;
16215
+ exports2.updateFormSubmission = updateFormSubmission;
16216
+ exports2.updateFormSubmissions = updateFormSubmissions;
15731
16217
  exports2.updateIssue = updateIssue;
15732
16218
  exports2.updateIssueAttachment = updateIssueAttachment;
15733
16219
  exports2.updateLicense = updateLicense;
15734
16220
  exports2.updateOrCreateProject = updateOrCreateProject;
15735
- exports2.updateOrCreateUserFormSubmission = updateOrCreateUserFormSubmission;
15736
16221
  exports2.updateOrganizationAccess = updateOrganizationAccess;
15737
16222
  exports2.updateProjectAccess = updateProjectAccess;
15738
16223
  exports2.updateProjectAttachment = updateProjectAttachment;