@overmap-ai/core 1.0.48-add-agent-response-rating.2 → 1.0.48-add-teams.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ var _a;
8
8
  import * as React from "react";
9
9
  import React__default, { useState, useEffect, useRef, memo, useMemo, useCallback, createContext, createElement, useContext, forwardRef, Children, isValidElement, cloneElement, Fragment as Fragment$1, useLayoutEffect, useReducer, lazy, Suspense } from "react";
10
10
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
11
- import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, useViewportSize, Overlay, ButtonGroup, Spinner, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, Button, ButtonList, divButtonProps, DropdownItemMenu, Input, useAlertDialog } from "@overmap-ai/blocks";
11
+ import { unsafeShowToast, AlertDialogProvider, ToastProvider, DefaultTheme, Flex as Flex$1, IconButton, RiIcon, Text as Text$1, useSeverityColor, Checkbox, TextArea, Select, useToast, Badge, MultiSelect, useViewportSize, Overlay, ButtonGroup, Spinner, IconColorUtility, Tooltip, Popover, useSize, ToggleButton, Separator, OvermapItem, Button, ButtonList, divButtonProps, OvermapDropdownMenu, Input, useAlertDialog } from "@overmap-ai/blocks";
12
12
  import { DepGraph } from "dependency-graph";
13
13
  import { offline as offline$1 } from "@redux-offline/redux-offline";
14
14
  import offlineConfig from "@redux-offline/redux-offline/lib/defaults";
@@ -631,15 +631,15 @@ const wrapMigration = (migrator) => (state) => {
631
631
  };
632
632
  const migrations = [initialVersioning, signOut, signOut, createOutboxState];
633
633
  const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
634
- const initialState$n = {
634
+ const initialState$o = {
635
635
  accessToken: "",
636
636
  refreshToken: "",
637
637
  isLoggedIn: false
638
638
  };
639
639
  const authSlice = createSlice({
640
640
  name: "auth",
641
- initialState: initialState$n,
642
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
641
+ initialState: initialState$o,
642
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$o)),
643
643
  reducers: {
644
644
  setTokens: (state, action) => {
645
645
  state.accessToken = action.payload.accessToken;
@@ -1370,7 +1370,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
1370
1370
  return getLocalDateString(date);
1371
1371
  return relative.format(days, "days");
1372
1372
  });
1373
- const initialState$m = {
1373
+ const initialState$n = {
1374
1374
  categories: {},
1375
1375
  usedCategoryColors: [],
1376
1376
  categoryVisibility: {
@@ -1380,8 +1380,8 @@ const initialState$m = {
1380
1380
  };
1381
1381
  const categorySlice = createSlice({
1382
1382
  name: "categories",
1383
- initialState: initialState$m,
1384
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1383
+ initialState: initialState$n,
1384
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$n)),
1385
1385
  reducers: {
1386
1386
  setCategories: (state, action) => {
1387
1387
  if (!Array.isArray(action.payload))
@@ -1549,14 +1549,14 @@ function removeAttachments(state, action) {
1549
1549
  delete state.attachments[attachmentId];
1550
1550
  }
1551
1551
  }
1552
- const initialState$l = {
1552
+ const initialState$m = {
1553
1553
  components: {},
1554
1554
  attachments: {}
1555
1555
  };
1556
1556
  const componentSlice = createSlice({
1557
1557
  name: "components",
1558
- initialState: initialState$l,
1559
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1558
+ initialState: initialState$m,
1559
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
1560
1560
  reducers: {
1561
1561
  addComponent: (state, action) => {
1562
1562
  state.components[action.payload.offline_id] = action.payload;
@@ -1610,6 +1610,7 @@ const selectComponents = (state) => {
1610
1610
  }
1611
1611
  return prevComponents;
1612
1612
  };
1613
+ const selectComponentsMapping = (state) => state.componentReducer.components;
1613
1614
  const selectComponentsFromComponentType = (componentTypeId) => (state) => {
1614
1615
  if (!componentTypeId)
1615
1616
  return [];
@@ -1640,16 +1641,14 @@ const selectComponentTypeFromComponents = (state) => {
1640
1641
  }
1641
1642
  return ret;
1642
1643
  };
1643
- const selectComponentsByType = (componentTypeId) => (state) => {
1644
- const components = state.componentReducer.components;
1645
- const componentsOfType = [];
1646
- for (const component of Object.values(components)) {
1647
- if (component.component_type === componentTypeId) {
1648
- componentsOfType.push(component);
1644
+ const selectComponentsByType = restructureCreateSelectorWithArgs(
1645
+ createSelector(
1646
+ [selectComponents, (_state, componentTypeId) => componentTypeId],
1647
+ (components, componentTypeId) => {
1648
+ return components.filter((component) => component.component_type === componentTypeId);
1649
1649
  }
1650
- }
1651
- return componentsOfType;
1652
- };
1650
+ )
1651
+ );
1653
1652
  const selectNumberOfComponentsOfComponentType = (componentTypeId) => (state) => {
1654
1653
  var _a2;
1655
1654
  if (!componentTypeId)
@@ -1710,13 +1709,13 @@ const {
1710
1709
  removeAllComponentsOfType
1711
1710
  } = componentSlice.actions;
1712
1711
  const componentReducer = componentSlice.reducer;
1713
- const initialState$k = {
1712
+ const initialState$l = {
1714
1713
  completionsByComponentId: {}
1715
1714
  };
1716
1715
  const componentStageCompletionSlice = createSlice({
1717
1716
  name: "componentStageCompletions",
1718
- initialState: initialState$k,
1719
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1717
+ initialState: initialState$l,
1718
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1720
1719
  reducers: {
1721
1720
  addStageCompletion: (state, action) => {
1722
1721
  let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
@@ -1767,13 +1766,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
1767
1766
  return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
1768
1767
  };
1769
1768
  const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
1770
- const initialState$j = {
1769
+ const initialState$k = {
1771
1770
  stages: {}
1772
1771
  };
1773
1772
  const componentStageSlice = createSlice({
1774
1773
  name: "componentStages",
1775
- initialState: initialState$j,
1776
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1774
+ initialState: initialState$k,
1775
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1777
1776
  reducers: {
1778
1777
  addStages: (state, action) => {
1779
1778
  Object.assign(state.stages, toOfflineIdRecord(action.payload));
@@ -1807,6 +1806,11 @@ const componentStageSlice = createSlice({
1807
1806
  }
1808
1807
  });
1809
1808
  const selectStageMapping = (state) => state.componentStageReducer.stages;
1809
+ const selectStage = restructureCreateSelectorWithArgs(
1810
+ createSelector([selectStageMapping, (_state, stageId) => stageId], (stageMapping, stageId) => {
1811
+ return stageMapping[stageId];
1812
+ })
1813
+ );
1810
1814
  const selectStages = createSelector(
1811
1815
  [selectStageMapping],
1812
1816
  (stageMapping) => {
@@ -1834,6 +1838,20 @@ const selectStagesFromComponentTypeIds = restructureCreateSelectorWithArgs(
1834
1838
  }
1835
1839
  )
1836
1840
  );
1841
+ const selectComponentTypeStagesMapping = restructureCreateSelectorWithArgs(
1842
+ createSelector(
1843
+ [selectStageMapping, (_state, componentTypeId) => componentTypeId],
1844
+ (stagesMapping, componentTypeId) => {
1845
+ const componentTypeStagesMapping = {};
1846
+ for (const [stageId, stage] of Object.entries(stagesMapping)) {
1847
+ if (stage.component_type === componentTypeId) {
1848
+ componentTypeStagesMapping[stageId] = stage;
1849
+ }
1850
+ }
1851
+ return componentTypeStagesMapping;
1852
+ }
1853
+ )
1854
+ );
1837
1855
  const selectStagesFromComponentType = restructureCreateSelectorWithArgs(
1838
1856
  createSelector(
1839
1857
  [selectStages, (_state, componentTypeId) => componentTypeId],
@@ -1864,15 +1882,15 @@ const selectStageFormIdsFromStageIds = restructureCreateSelectorWithArgs(
1864
1882
  );
1865
1883
  const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
1866
1884
  const componentStageReducer = componentStageSlice.reducer;
1867
- const initialState$i = {
1885
+ const initialState$j = {
1868
1886
  componentTypes: {},
1869
1887
  hiddenComponentTypeIds: {},
1870
1888
  attachments: {}
1871
1889
  };
1872
1890
  const componentTypeSlice = createSlice({
1873
1891
  name: "componentTypes",
1874
- initialState: initialState$i,
1875
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1892
+ initialState: initialState$j,
1893
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1876
1894
  reducers: {
1877
1895
  addComponentType: (state, action) => {
1878
1896
  state.componentTypes[action.payload.offline_id] = action.payload;
@@ -1980,13 +1998,13 @@ const {
1980
1998
  deleteComponentType
1981
1999
  } = componentTypeSlice.actions;
1982
2000
  const componentTypeReducer = componentTypeSlice.reducer;
1983
- const initialState$h = {
2001
+ const initialState$i = {
1984
2002
  workspaces: {},
1985
2003
  activeWorkspaceId: null
1986
2004
  };
1987
2005
  const workspaceSlice = createSlice({
1988
2006
  name: "workspace",
1989
- initialState: initialState$h,
2007
+ initialState: initialState$i,
1990
2008
  // The `reducers` field lets us define reducers and generate associated actions
1991
2009
  reducers: {
1992
2010
  setWorkspaces: (state, action) => {
@@ -2043,10 +2061,11 @@ const selectPermittedWorkspaceIds = createSelector(
2043
2061
  );
2044
2062
  const workspaceReducer = workspaceSlice.reducer;
2045
2063
  const maxRecentIssues = 10;
2046
- const initialState$g = {
2064
+ const initialState$h = {
2047
2065
  issues: {},
2048
2066
  attachments: {},
2049
2067
  comments: {},
2068
+ updates: {},
2050
2069
  visibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],
2051
2070
  visibleUserIds: null,
2052
2071
  recentIssueIds: [],
@@ -2054,9 +2073,9 @@ const initialState$g = {
2054
2073
  };
2055
2074
  const issueSlice = createSlice({
2056
2075
  name: "issues",
2057
- initialState: initialState$g,
2076
+ initialState: initialState$h,
2058
2077
  extraReducers: (builder) => builder.addCase("RESET", (state) => {
2059
- Object.assign(state, initialState$g);
2078
+ Object.assign(state, initialState$h);
2060
2079
  }),
2061
2080
  reducers: {
2062
2081
  setIssues: (state, action) => {
@@ -2068,6 +2087,16 @@ const issueSlice = createSlice({
2068
2087
  });
2069
2088
  },
2070
2089
  setIssueAttachments: setAttachments,
2090
+ setIssueUpdates: (state, action) => {
2091
+ if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2092
+ throw new Error("Tried to use setIssues reducer with duplicate ID's");
2093
+ }
2094
+ const newUpdates = {};
2095
+ for (const update of action.payload) {
2096
+ newUpdates[update.offline_id] = update;
2097
+ }
2098
+ state.updates = newUpdates;
2099
+ },
2071
2100
  setActiveIssueId: (state, action) => {
2072
2101
  state.activeIssueId = action.payload;
2073
2102
  },
@@ -2079,6 +2108,17 @@ const issueSlice = createSlice({
2079
2108
  },
2080
2109
  addIssueAttachment: addAttachment,
2081
2110
  addIssueAttachments: addAttachments,
2111
+ addIssueUpdate: (state, action) => {
2112
+ if (action.payload.offline_id in state.updates) {
2113
+ throw new Error(`Tried to add duplicate issue update with offline_id: ${action.payload.offline_id}`);
2114
+ }
2115
+ state.updates[action.payload.offline_id] = action.payload;
2116
+ },
2117
+ addIssueUpdates: (state, action) => {
2118
+ for (const update of action.payload) {
2119
+ state.updates[update.offline_id] = update;
2120
+ }
2121
+ },
2082
2122
  updateIssue: (state, action) => {
2083
2123
  if (action.payload.offline_id in state.issues) {
2084
2124
  state.issues[action.payload.offline_id] = {
@@ -2098,6 +2138,18 @@ const issueSlice = createSlice({
2098
2138
  }
2099
2139
  },
2100
2140
  removeIssueAttachment: removeAttachment,
2141
+ removeIssueUpdate: (state, action) => {
2142
+ if (action.payload in state.updates) {
2143
+ delete state.updates[action.payload];
2144
+ } else {
2145
+ throw new Error(`Failed to remove issue update because offline_id doesn't exist: ${action.payload}`);
2146
+ }
2147
+ },
2148
+ removeIssueUpdates: (state, action) => {
2149
+ for (const updateId of action.payload) {
2150
+ delete state.updates[updateId];
2151
+ }
2152
+ },
2101
2153
  removeAttachmentsOfIssue: (state, action) => {
2102
2154
  const attachments = Object.values(state.attachments).filter((a) => a.issue === action.payload);
2103
2155
  for (const attachment of attachments) {
@@ -2110,20 +2162,55 @@ const issueSlice = createSlice({
2110
2162
  setVisibleUserIds: (state, action) => {
2111
2163
  state.visibleUserIds = [...new Set(action.payload)];
2112
2164
  },
2113
- setIssueComments: (state, action) => {
2165
+ // Comments
2166
+ addIssueComment: (state, action) => {
2167
+ if (action.payload.offline_id in state.comments) {
2168
+ throw new Error(
2169
+ `Tried to add issue comment with offline_id: ${action.payload.offline_id} that already exists`
2170
+ );
2171
+ }
2172
+ state.comments[action.payload.offline_id] = action.payload;
2173
+ },
2174
+ addIssueComments: (state, action) => {
2175
+ for (const comment of action.payload) {
2176
+ if (comment.offline_id in state.comments) {
2177
+ throw new Error(
2178
+ `Tried to add issue comment with offline_id: ${comment.offline_id} that already exists`
2179
+ );
2180
+ }
2181
+ }
2114
2182
  for (const comment of action.payload) {
2115
2183
  state.comments[comment.offline_id] = comment;
2116
2184
  }
2117
2185
  },
2186
+ setIssueComment: (state, action) => {
2187
+ state.comments[action.payload.offline_id] = action.payload;
2188
+ },
2189
+ setIssueComments: (state, action) => {
2190
+ const newComments = {};
2191
+ for (const comment of action.payload) {
2192
+ newComments[comment.offline_id] = comment;
2193
+ }
2194
+ state.comments = newComments;
2195
+ },
2118
2196
  addOrReplaceIssueComment: (state, action) => {
2119
2197
  state.comments[action.payload.offline_id] = action.payload;
2120
2198
  },
2121
2199
  removeIssueComment: (state, action) => {
2122
- if (action.payload in state.comments) {
2123
- delete state.comments[action.payload];
2124
- } else {
2200
+ if (!(action.payload in state.comments)) {
2125
2201
  throw new Error(`Failed to remove issue comment because ID doesn't exist: ${action.payload}`);
2126
2202
  }
2203
+ delete state.comments[action.payload];
2204
+ },
2205
+ removeIssueComments: (state, action) => {
2206
+ for (const commentId of action.payload) {
2207
+ if (!(commentId in state.comments)) {
2208
+ throw new Error(`Failed to remove issue comment because ID doesn't exist: ${commentId}`);
2209
+ }
2210
+ }
2211
+ for (const commentId of action.payload) {
2212
+ delete state.comments[commentId];
2213
+ }
2127
2214
  },
2128
2215
  cleanRecentIssues: (state) => {
2129
2216
  state.recentIssueIds = state.recentIssueIds.filter((recentIssue) => state.issues[recentIssue.offlineId]);
@@ -2154,23 +2241,33 @@ const {
2154
2241
  addIssueAttachment,
2155
2242
  addIssueAttachments,
2156
2243
  addIssue,
2244
+ addIssueUpdate,
2245
+ addIssueUpdates,
2157
2246
  addOrReplaceIssueComment,
2158
2247
  addToRecentIssues,
2159
2248
  cleanRecentIssues,
2160
2249
  removeIssueAttachment,
2161
2250
  removeAttachmentsOfIssue,
2162
2251
  removeIssue,
2163
- removeIssueComment,
2252
+ removeIssueUpdate,
2253
+ removeIssueUpdates,
2164
2254
  removeRecentIssue,
2165
2255
  resetRecentIssues,
2166
2256
  setActiveIssueId,
2167
2257
  setIssueAttachments,
2168
- setIssueComments,
2258
+ setIssueUpdates,
2169
2259
  setIssues,
2170
2260
  setVisibleStatuses,
2171
2261
  setVisibleUserIds,
2172
2262
  updateIssueAttachment,
2173
- updateIssue
2263
+ updateIssue,
2264
+ // Commments
2265
+ addIssueComment,
2266
+ addIssueComments,
2267
+ setIssueComment,
2268
+ setIssueComments,
2269
+ removeIssueComment,
2270
+ removeIssueComments
2174
2271
  } = issueSlice.actions;
2175
2272
  const selectIssueMapping = (state) => state.issueReducer.issues;
2176
2273
  const selectRecentIssueIds = (state) => state.issueReducer.recentIssueIds;
@@ -2241,6 +2338,12 @@ const selectCommentsOfIssue = restructureCreateSelectorWithArgs(
2241
2338
  return Object.values(commentMapping).filter((comment) => comment.issue === issueId);
2242
2339
  })
2243
2340
  );
2341
+ const selectIssueUpdateMapping = (state) => state.issueReducer.updates;
2342
+ const selectIssueUpdatesOfIssue = restructureCreateSelectorWithArgs(
2343
+ createSelector([selectIssueUpdateMapping, (_state, issueId) => issueId], (updates, issueId) => {
2344
+ return Object.values(updates).filter((update) => update.issue === issueId);
2345
+ })
2346
+ );
2244
2347
  const selectAttachmentsOfIssue = restructureCreateSelectorWithArgs(
2245
2348
  createSelector(
2246
2349
  [selectIssueAttachments, (_state, issueId) => issueId],
@@ -2377,15 +2480,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
2377
2480
  }
2378
2481
  );
2379
2482
  const issueReducer = issueSlice.reducer;
2380
- const initialState$f = {
2483
+ const initialState$g = {
2381
2484
  s3Urls: {}
2382
2485
  };
2383
2486
  const msPerHour = 1e3 * 60 * 60;
2384
2487
  const msPerWeek = msPerHour * 24 * 7;
2385
2488
  const fileSlice = createSlice({
2386
2489
  name: "file",
2387
- initialState: initialState$f,
2388
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2490
+ initialState: initialState$g,
2491
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
2389
2492
  reducers: {
2390
2493
  setUploadUrl: (state, action) => {
2391
2494
  const { url, fields, sha1 } = action.payload;
@@ -2412,7 +2515,7 @@ const selectUploadUrl = (sha1) => (state) => {
2412
2515
  return url;
2413
2516
  };
2414
2517
  const fileReducer = fileSlice.reducer;
2415
- const initialState$e = {
2518
+ const initialState$f = {
2416
2519
  // TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
2417
2520
  mapStyle: MapStyle.SATELLITE,
2418
2521
  showTooltips: false,
@@ -2420,8 +2523,8 @@ const initialState$e = {
2420
2523
  };
2421
2524
  const mapSlice = createSlice({
2422
2525
  name: "map",
2423
- initialState: initialState$e,
2424
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2526
+ initialState: initialState$f,
2527
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
2425
2528
  reducers: {
2426
2529
  setMapStyle: (state, action) => {
2427
2530
  state.mapStyle = action.payload;
@@ -2449,6 +2552,16 @@ var OrganizationAccessLevel = /* @__PURE__ */ ((OrganizationAccessLevel2) => {
2449
2552
  OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
2450
2553
  return OrganizationAccessLevel2;
2451
2554
  })(OrganizationAccessLevel || {});
2555
+ var IssueUpdateChange = /* @__PURE__ */ ((IssueUpdateChange2) => {
2556
+ IssueUpdateChange2["STATUS"] = "status";
2557
+ IssueUpdateChange2["PRIORITY"] = "priority";
2558
+ IssueUpdateChange2["CATEGORY"] = "category";
2559
+ IssueUpdateChange2["DESCRIPTION"] = "description";
2560
+ IssueUpdateChange2["TITLE"] = "title";
2561
+ IssueUpdateChange2["ASSIGNED_TO"] = "assigned_to";
2562
+ IssueUpdateChange2["DUE_DATE"] = "due_date";
2563
+ return IssueUpdateChange2;
2564
+ })(IssueUpdateChange || {});
2452
2565
  var ProjectType = /* @__PURE__ */ ((ProjectType2) => {
2453
2566
  ProjectType2[ProjectType2["PERSONAL"] = 0] = "PERSONAL";
2454
2567
  ProjectType2[ProjectType2["ORGANIZATION"] = 2] = "ORGANIZATION";
@@ -2480,7 +2593,7 @@ var LicenseStatus = /* @__PURE__ */ ((LicenseStatus2) => {
2480
2593
  LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
2481
2594
  return LicenseStatus2;
2482
2595
  })(LicenseStatus || {});
2483
- const initialState$d = {
2596
+ const initialState$e = {
2484
2597
  users: {},
2485
2598
  currentUser: {
2486
2599
  id: 0,
@@ -2491,8 +2604,8 @@ const initialState$d = {
2491
2604
  };
2492
2605
  const userSlice = createSlice({
2493
2606
  name: "users",
2494
- initialState: initialState$d,
2495
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2607
+ initialState: initialState$e,
2608
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2496
2609
  reducers: {
2497
2610
  setUsers: (state, action) => {
2498
2611
  const usersMapping = {};
@@ -2554,13 +2667,13 @@ const selectUser = (userId) => (state) => {
2554
2667
  const selectUsersAsMapping = (state) => state.userReducer.users;
2555
2668
  const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
2556
2669
  const userReducer = userSlice.reducer;
2557
- const initialState$c = {
2670
+ const initialState$d = {
2558
2671
  organizationAccesses: {}
2559
2672
  };
2560
2673
  const organizationAccessSlice = createSlice({
2561
2674
  name: "organizationAccess",
2562
- initialState: initialState$c,
2563
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2675
+ initialState: initialState$d,
2676
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2564
2677
  reducers: {
2565
2678
  setOrganizationAccesses: (state, action) => {
2566
2679
  if (!Array.isArray(action.payload))
@@ -2623,13 +2736,13 @@ const selectOrganizationAccessUserMapping = (state) => {
2623
2736
  return organizationAccesses;
2624
2737
  };
2625
2738
  const organizationAccessReducer = organizationAccessSlice.reducer;
2626
- const initialState$b = {
2739
+ const initialState$c = {
2627
2740
  licenses: {}
2628
2741
  };
2629
2742
  const licenseSlice = createSlice({
2630
2743
  name: "license",
2631
- initialState: initialState$b,
2632
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2744
+ initialState: initialState$c,
2745
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2633
2746
  reducers: {
2634
2747
  setLicenses: (state, action) => {
2635
2748
  if (!Array.isArray(action.payload))
@@ -2674,13 +2787,13 @@ const selectLicensesForProjectsMapping = createSelector(
2674
2787
  (licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
2675
2788
  );
2676
2789
  const licenseReducer = licenseSlice.reducer;
2677
- const initialState$a = {
2790
+ const initialState$b = {
2678
2791
  projectAccesses: {}
2679
2792
  };
2680
2793
  const projectAccessSlice = createSlice({
2681
2794
  name: "projectAccess",
2682
- initialState: initialState$a,
2683
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2795
+ initialState: initialState$b,
2796
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2684
2797
  reducers: {
2685
2798
  setProjectAccesses: (state, action) => {
2686
2799
  if (!Array.isArray(action.payload))
@@ -2748,7 +2861,7 @@ const selectProjectAccessUserMapping = (state) => {
2748
2861
  return projectAccesses;
2749
2862
  };
2750
2863
  const projectAccessReducer = projectAccessSlice.reducer;
2751
- const initialState$9 = {
2864
+ const initialState$a = {
2752
2865
  projects: {},
2753
2866
  activeProjectId: null,
2754
2867
  recentProjectIds: [],
@@ -2758,7 +2871,7 @@ const initialState$9 = {
2758
2871
  };
2759
2872
  const projectSlice = createSlice({
2760
2873
  name: "projects",
2761
- initialState: initialState$9,
2874
+ initialState: initialState$a,
2762
2875
  reducers: {
2763
2876
  setProjects: (state, action) => {
2764
2877
  const projectsMap = {};
@@ -2945,14 +3058,14 @@ const selectAttachmentsOfProjectByType = restructureCreateSelectorWithArgs(
2945
3058
  }
2946
3059
  )
2947
3060
  );
2948
- const initialState$8 = {
3061
+ const initialState$9 = {
2949
3062
  organizations: {},
2950
3063
  activeOrganizationId: null
2951
3064
  };
2952
3065
  const organizationSlice = createSlice({
2953
3066
  name: "organizations",
2954
- initialState: initialState$8,
2955
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3067
+ initialState: initialState$9,
3068
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
2956
3069
  reducers: {
2957
3070
  setOrganizations: (state, action) => {
2958
3071
  for (const org of action.payload) {
@@ -3071,14 +3184,14 @@ const createOfflineAction = (request2, baseUrl) => {
3071
3184
  }
3072
3185
  };
3073
3186
  };
3074
- const initialState$7 = {
3187
+ const initialState$8 = {
3075
3188
  deletedRequests: [],
3076
3189
  latestRetryTime: 0
3077
3190
  };
3078
3191
  const outboxSlice = createSlice({
3079
3192
  name: "outbox",
3080
- initialState: initialState$7,
3081
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
3193
+ initialState: initialState$8,
3194
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
3082
3195
  reducers: {
3083
3196
  // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
3084
3197
  // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
@@ -3110,7 +3223,7 @@ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
3110
3223
  const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
3111
3224
  const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
3112
3225
  const outboxReducer = outboxSlice.reducer;
3113
- const initialState$6 = {
3226
+ const initialState$7 = {
3114
3227
  projectFiles: {},
3115
3228
  activeProjectFileId: null,
3116
3229
  isImportingProjectFile: false,
@@ -3118,8 +3231,8 @@ const initialState$6 = {
3118
3231
  };
3119
3232
  const projectFileSlice = createSlice({
3120
3233
  name: "projectFiles",
3121
- initialState: initialState$6,
3122
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
3234
+ initialState: initialState$7,
3235
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
3123
3236
  reducers: {
3124
3237
  addOrReplaceProjectFiles: (state, action) => {
3125
3238
  for (let fileObj of action.payload) {
@@ -3220,12 +3333,12 @@ const selectProjectFiles = createSelector(
3220
3333
  const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
3221
3334
  const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
3222
3335
  const projectFileReducer = projectFileSlice.reducer;
3223
- const initialState$5 = {
3336
+ const initialState$6 = {
3224
3337
  isRehydrated: false
3225
3338
  };
3226
3339
  const rehydratedSlice = createSlice({
3227
3340
  name: "rehydrated",
3228
- initialState: initialState$5,
3341
+ initialState: initialState$6,
3229
3342
  // The `reducers` field lets us define reducers and generate associated actions
3230
3343
  reducers: {
3231
3344
  setRehydrated: (state, action) => {
@@ -3235,7 +3348,7 @@ const rehydratedSlice = createSlice({
3235
3348
  });
3236
3349
  const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
3237
3350
  const rehydratedReducer = rehydratedSlice.reducer;
3238
- const initialState$4 = {
3351
+ const initialState$5 = {
3239
3352
  useIssueTemplate: false,
3240
3353
  placementMode: false,
3241
3354
  enableClustering: false,
@@ -3252,8 +3365,8 @@ const initialState$4 = {
3252
3365
  };
3253
3366
  const settingSlice = createSlice({
3254
3367
  name: "settings",
3255
- initialState: initialState$4,
3256
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3368
+ initialState: initialState$5,
3369
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$5)),
3257
3370
  reducers: {
3258
3371
  setEnableDuplicateIssues: (state, action) => {
3259
3372
  state.useIssueTemplate = action.payload;
@@ -3326,7 +3439,7 @@ function considerCachingRevision(revision, formId2, preferPending = false) {
3326
3439
  function getLatestRevisionFromCache(formId2) {
3327
3440
  return LATEST_REVISION_CACHE[formId2];
3328
3441
  }
3329
- const initialState$3 = {
3442
+ const initialState$4 = {
3330
3443
  userForms: {},
3331
3444
  revisions: {},
3332
3445
  submissions: {},
@@ -3335,8 +3448,8 @@ const initialState$3 = {
3335
3448
  };
3336
3449
  const userFormSlice = createSlice({
3337
3450
  name: "userForms",
3338
- initialState: initialState$3,
3339
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
3451
+ initialState: initialState$4,
3452
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
3340
3453
  reducers: {
3341
3454
  setUserForms: (state, action) => {
3342
3455
  state.userForms = {};
@@ -3551,6 +3664,9 @@ const selectUserForm = (formId2) => (state) => {
3551
3664
  return state.userFormReducer.userForms[formId2];
3552
3665
  };
3553
3666
  const selectSubmissionMapping = (state) => state.userFormReducer.submissions;
3667
+ const selectUserFormSubmission = (submissionId) => (state) => {
3668
+ return state.userFormReducer.submissions[submissionId];
3669
+ };
3554
3670
  const selectSubmissions = createSelector([selectSubmissionMapping], (submissions) => Object.values(submissions));
3555
3671
  const selectRevisionMapping = (state) => state.userFormReducer.revisions;
3556
3672
  const selectRevisions = createSelector([selectRevisionMapping], (revisions) => Object.values(revisions));
@@ -3592,6 +3708,23 @@ const selectSubmissionsForComponent = restructureCreateSelectorWithArgs(
3592
3708
  }
3593
3709
  )
3594
3710
  );
3711
+ const selectComponentSubmissionMapping = createSelector(
3712
+ [selectSubmissionMapping, selectComponentsMapping],
3713
+ (submissions, components) => {
3714
+ var _a2;
3715
+ const componentSubmissionMapping = {};
3716
+ for (const componentId in components) {
3717
+ componentSubmissionMapping[componentId] = [];
3718
+ }
3719
+ for (const submissionId in submissions) {
3720
+ const submission = submissions[submissionId];
3721
+ if (submission.component) {
3722
+ (_a2 = componentSubmissionMapping[submission.component]) == null ? void 0 : _a2.push(submission);
3723
+ }
3724
+ }
3725
+ return componentSubmissionMapping;
3726
+ }
3727
+ );
3595
3728
  const selectUserFormMapping = (state) => {
3596
3729
  return state.userFormReducer.userForms;
3597
3730
  };
@@ -3640,12 +3773,12 @@ const selectNumberOfGeneralUserForms = createSelector([selectUserFormMapping], (
3640
3773
  return Object.values(userForms).filter((form) => !form.component_type).length;
3641
3774
  });
3642
3775
  const userFormReducer = userFormSlice.reducer;
3643
- const initialState$2 = {
3776
+ const initialState$3 = {
3644
3777
  emailDomains: {}
3645
3778
  };
3646
3779
  const emailDomainsSlice = createSlice({
3647
3780
  name: "emailDomains",
3648
- initialState: initialState$2,
3781
+ initialState: initialState$3,
3649
3782
  reducers: {
3650
3783
  setEmailDomains: (state, action) => {
3651
3784
  const emailDomains = {};
@@ -3672,14 +3805,14 @@ const selectSortedEmailDomains = (state) => Object.values(state.emailDomainsRedu
3672
3805
  (ed1, ed2) => ed1.domain.localeCompare(ed2.domain)
3673
3806
  );
3674
3807
  const emailDomainsReducer = emailDomainsSlice.reducer;
3675
- const initialState$1 = {
3808
+ const initialState$2 = {
3676
3809
  documents: {}
3677
3810
  };
3678
3811
  const documentSlice = createSlice({
3679
3812
  name: "documents",
3680
- initialState: initialState$1,
3813
+ initialState: initialState$2,
3681
3814
  extraReducers: (builder) => builder.addCase("RESET", (state) => {
3682
- Object.assign(state, initialState$1);
3815
+ Object.assign(state, initialState$2);
3683
3816
  }),
3684
3817
  reducers: {
3685
3818
  setDocuments: (state, action) => {
@@ -3844,6 +3977,59 @@ const selectRootDocuments = createSelector(
3844
3977
  (documents) => documents.filter((document2) => !document2.parent_document)
3845
3978
  );
3846
3979
  const documentsReducer = documentSlice.reducer;
3980
+ const initialState$1 = {
3981
+ teams: {}
3982
+ };
3983
+ const teamSlice = createSlice({
3984
+ name: "teams",
3985
+ initialState: initialState$1,
3986
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$1)),
3987
+ reducers: {
3988
+ setTeam: (state, action) => {
3989
+ state.teams[action.payload.offline_id] = action.payload;
3990
+ },
3991
+ setTeams: (state, action) => {
3992
+ state.teams = {};
3993
+ for (const team of action.payload) {
3994
+ state.teams[team.offline_id] = team;
3995
+ }
3996
+ },
3997
+ addTeam: (state, action) => {
3998
+ if (state.teams[action.payload.offline_id]) {
3999
+ throw new Error(`Team with offline_id ${action.payload.offline_id} already exists`);
4000
+ }
4001
+ state.teams[action.payload.offline_id] = action.payload;
4002
+ },
4003
+ updateTeam: (state, action) => {
4004
+ if (!state.teams[action.payload.offline_id]) {
4005
+ throw new Error(`Team with offline_id ${action.payload.offline_id} does not exist`);
4006
+ }
4007
+ state.teams[action.payload.offline_id] = action.payload;
4008
+ },
4009
+ deleteTeam: (state, action) => {
4010
+ delete state.teams[action.payload];
4011
+ }
4012
+ }
4013
+ });
4014
+ const { setTeam, setTeams, addTeam, updateTeam, deleteTeam } = teamSlice.actions;
4015
+ const selectTeamsMapping = (state) => state.teamReducer.teams;
4016
+ const selectTeams = createSelector([selectTeamsMapping], (teams) => {
4017
+ return Object.values(teams);
4018
+ });
4019
+ const selectTeamsOfOrganization = restructureCreateSelectorWithArgs(
4020
+ createSelector(
4021
+ [selectTeams, (_state, organizationId) => organizationId],
4022
+ (teams, organizationId) => {
4023
+ return teams.filter((team) => team.organization === organizationId);
4024
+ }
4025
+ )
4026
+ );
4027
+ const selectTeamsOfUser = restructureCreateSelectorWithArgs(
4028
+ createSelector([selectTeams, (_state, userId) => userId], (teams, userId) => {
4029
+ return teams.filter((team) => team.members.includes(userId));
4030
+ })
4031
+ );
4032
+ const teamReducer = teamSlice.reducer;
3847
4033
  const initialState = {
3848
4034
  version: 0
3849
4035
  };
@@ -3890,7 +4076,8 @@ const overmapReducers = {
3890
4076
  workspaceReducer,
3891
4077
  emailDomainsReducer,
3892
4078
  licenseReducer,
3893
- documentsReducer
4079
+ documentsReducer,
4080
+ teamReducer
3894
4081
  };
3895
4082
  const overmapReducer = combineReducers(overmapReducers);
3896
4083
  const resetStore = "RESET";
@@ -4437,7 +4624,7 @@ class AttachmentService extends BaseApiService {
4437
4624
  }
4438
4625
  // Attachments aren't models, so we use the OptimisticGenericResult type instead
4439
4626
  async addIssueAttachment(attachmentPayload) {
4440
- const { description: description2, issue, file_sha1, offline_id } = attachmentPayload;
4627
+ const { issue, file_sha1, offline_id } = attachmentPayload;
4441
4628
  if (!attachmentPayload.file.objectURL) {
4442
4629
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4443
4630
  }
@@ -4445,7 +4632,9 @@ class AttachmentService extends BaseApiService {
4445
4632
  ...attachmentPayload,
4446
4633
  file: attachmentPayload.file.objectURL,
4447
4634
  file_name: attachmentPayload.file.name,
4448
- file_type: attachmentPayload.file.type
4635
+ file_type: attachmentPayload.file.type,
4636
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4637
+ created_by: this.client.store.getState().userReducer.currentUser.id
4449
4638
  };
4450
4639
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4451
4640
  this.client.store.dispatch(addIssueAttachment(offlineAttachment));
@@ -4457,10 +4646,7 @@ class AttachmentService extends BaseApiService {
4457
4646
  blocks: [offline_id, issue],
4458
4647
  blockers: [file_sha1],
4459
4648
  payload: {
4460
- offline_id,
4461
- issue,
4462
- description: description2 ?? "",
4463
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4649
+ ...offlineAttachment,
4464
4650
  ...fileProps
4465
4651
  }
4466
4652
  });
@@ -4471,7 +4657,7 @@ class AttachmentService extends BaseApiService {
4471
4657
  return [offlineAttachment, promise];
4472
4658
  }
4473
4659
  async addComponentAttachment(attachmentPayload) {
4474
- const { description: description2, component, file_sha1, offline_id } = attachmentPayload;
4660
+ const { component, file_sha1, offline_id } = attachmentPayload;
4475
4661
  if (!attachmentPayload.file.objectURL) {
4476
4662
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4477
4663
  }
@@ -4479,7 +4665,9 @@ class AttachmentService extends BaseApiService {
4479
4665
  ...attachmentPayload,
4480
4666
  file: attachmentPayload.file.objectURL,
4481
4667
  file_name: attachmentPayload.file.name,
4482
- file_type: attachmentPayload.file.type
4668
+ file_type: attachmentPayload.file.type,
4669
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4670
+ created_by: this.client.store.getState().userReducer.currentUser.id
4483
4671
  };
4484
4672
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4485
4673
  this.client.store.dispatch(addComponentAttachment(offlineAttachment));
@@ -4491,10 +4679,7 @@ class AttachmentService extends BaseApiService {
4491
4679
  blocks: [offline_id, component],
4492
4680
  blockers: [file_sha1],
4493
4681
  payload: {
4494
- offline_id,
4495
- component,
4496
- description: description2 ?? "",
4497
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4682
+ ...offlineAttachment,
4498
4683
  ...fileProps
4499
4684
  }
4500
4685
  });
@@ -4505,7 +4690,7 @@ class AttachmentService extends BaseApiService {
4505
4690
  return [offlineAttachment, promise];
4506
4691
  }
4507
4692
  async addComponentTypeAttachment(attachmentPayload) {
4508
- const { description: description2, component_type, file_sha1, offline_id } = attachmentPayload;
4693
+ const { component_type, file_sha1, offline_id } = attachmentPayload;
4509
4694
  if (!attachmentPayload.file.objectURL) {
4510
4695
  throw new Error("Expected attachmentPayload.file.objectURL to be defined.");
4511
4696
  }
@@ -4513,7 +4698,9 @@ class AttachmentService extends BaseApiService {
4513
4698
  ...attachmentPayload,
4514
4699
  file: attachmentPayload.file.objectURL,
4515
4700
  file_name: attachmentPayload.file.name,
4516
- file_type: attachmentPayload.file.type
4701
+ file_type: attachmentPayload.file.type,
4702
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4703
+ created_by: this.client.store.getState().userReducer.currentUser.id
4517
4704
  };
4518
4705
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4519
4706
  this.client.store.dispatch(addComponentTypeAttachment(offlineAttachment));
@@ -4525,10 +4712,7 @@ class AttachmentService extends BaseApiService {
4525
4712
  blocks: [offline_id, component_type],
4526
4713
  blockers: [file_sha1],
4527
4714
  payload: {
4528
- offline_id,
4529
- component_type,
4530
- description: description2 ?? "",
4531
- submitted_at: (/* @__PURE__ */ new Date()).getTime() / 1e3,
4715
+ ...offlineAttachment,
4532
4716
  ...fileProps
4533
4717
  }
4534
4718
  });
@@ -4547,7 +4731,9 @@ class AttachmentService extends BaseApiService {
4547
4731
  ...attachmentPayload,
4548
4732
  file: attachmentPayload.file.objectURL,
4549
4733
  file_name: attachmentPayload.file.name,
4550
- file_type: attachmentPayload.file.type
4734
+ file_type: attachmentPayload.file.type,
4735
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4736
+ created_by: this.client.store.getState().userReducer.currentUser.id
4551
4737
  };
4552
4738
  await this.client.files.addCache(attachmentPayload.file, file_sha1);
4553
4739
  this.client.store.dispatch(addProjectAttachment(offlineAttachment));
@@ -4587,7 +4773,9 @@ class AttachmentService extends BaseApiService {
4587
4773
  file_name: file2.name,
4588
4774
  file_type: file2.type,
4589
4775
  issue: issueId,
4590
- file_sha1: hash
4776
+ file_sha1: hash,
4777
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4778
+ created_by: this.client.store.getState().userReducer.currentUser.id
4591
4779
  });
4592
4780
  return this.addIssueAttachment(attachment);
4593
4781
  };
@@ -4606,7 +4794,9 @@ class AttachmentService extends BaseApiService {
4606
4794
  file_name: file2.name,
4607
4795
  file_type: file2.type,
4608
4796
  component: componentId,
4609
- file_sha1: hash
4797
+ file_sha1: hash,
4798
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4799
+ created_by: this.client.store.getState().userReducer.currentUser.id
4610
4800
  });
4611
4801
  return this.addComponentAttachment(attachment);
4612
4802
  };
@@ -4625,7 +4815,9 @@ class AttachmentService extends BaseApiService {
4625
4815
  file_name: file2.name,
4626
4816
  file_type: file2.type,
4627
4817
  component_type: componentTypeId,
4628
- file_sha1: hash
4818
+ file_sha1: hash,
4819
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4820
+ created_by: this.client.store.getState().userReducer.currentUser.id
4629
4821
  });
4630
4822
  return this.addComponentTypeAttachment(attachment);
4631
4823
  };
@@ -4644,7 +4836,9 @@ class AttachmentService extends BaseApiService {
4644
4836
  file_name: file2.name,
4645
4837
  file_type: file2.type,
4646
4838
  project: projectId,
4647
- file_sha1: hash
4839
+ file_sha1: hash,
4840
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
4841
+ created_by: this.client.store.getState().userReducer.currentUser.id
4648
4842
  });
4649
4843
  return this.addProjectAttachment(attachment);
4650
4844
  };
@@ -5721,49 +5915,35 @@ class ComponentTypeService extends BaseApiService {
5721
5915
  }
5722
5916
  }
5723
5917
  class IssueCommentService extends BaseApiService {
5918
+ // Omit author and submitted_at since these will always be set internally
5724
5919
  add(comment) {
5725
- const offlinePayload = offline(comment);
5726
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
5727
5920
  const { store } = this.client;
5728
- const offlineComment = {
5729
- ...offlinePayload,
5921
+ const offlineComment = offline({
5922
+ ...comment,
5730
5923
  author: store.getState().userReducer.currentUser.id,
5731
- created_at: submittedAt
5732
- };
5733
- store.dispatch(addOrReplaceIssueComment(offlineComment));
5924
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString()
5925
+ });
5926
+ store.dispatch(addIssueComment(offlineComment));
5734
5927
  const promise = this.enqueueRequest({
5735
5928
  description: `${truncate(comment.content, 80)}`,
5736
5929
  method: HttpMethod.POST,
5737
5930
  url: `/issues/${comment.issue}/comment/`,
5738
- payload: { ...offlinePayload, submitted_at: submittedAt },
5931
+ payload: offlineComment,
5739
5932
  blockers: [comment.issue],
5740
- blocks: [offlinePayload.offline_id]
5933
+ blocks: [offlineComment.offline_id]
5934
+ });
5935
+ promise.catch(() => {
5936
+ store.dispatch(removeIssueComment(offlineComment.offline_id));
5741
5937
  });
5742
5938
  return [offlineComment, promise];
5743
5939
  }
5744
- async refreshStore() {
5940
+ update(comment) {
5745
5941
  const { store } = this.client;
5746
- const result = await this.enqueueRequest({
5747
- description: "Get comments",
5748
- method: HttpMethod.GET,
5749
- // TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
5750
- url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
5751
- blockers: [],
5752
- blocks: []
5753
- });
5754
- let filteredResult = result.filter(onlyUniqueOfflineIds);
5755
- filteredResult = filteredResult.map((comment) => {
5756
- return { ...comment };
5757
- });
5758
- if (result.length !== filteredResult.length) {
5759
- console.error(
5760
- `Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
5761
- );
5942
+ const commentToUpdate = store.getState().issueReducer.comments[comment.offline_id];
5943
+ if (!commentToUpdate) {
5944
+ throw new Error(`Comment with offline_id ${comment.offline_id} not found in store`);
5762
5945
  }
5763
- store.dispatch(setIssueComments(filteredResult));
5764
- }
5765
- update(comment) {
5766
- this.client.store.dispatch(addOrReplaceIssueComment(comment));
5946
+ store.dispatch(setIssueComment(comment));
5767
5947
  const promise = this.enqueueRequest({
5768
5948
  description: `Edit comment: ${truncate(comment.content, 80)}`,
5769
5949
  method: HttpMethod.PATCH,
@@ -5772,17 +5952,62 @@ class IssueCommentService extends BaseApiService {
5772
5952
  blockers: [comment.issue],
5773
5953
  blocks: [comment.offline_id]
5774
5954
  });
5955
+ promise.catch(() => {
5956
+ store.dispatch(setIssueComment(commentToUpdate));
5957
+ });
5775
5958
  return [comment, promise];
5776
5959
  }
5777
5960
  remove(offline_id) {
5961
+ const commentToRemove = this.client.store.getState().issueReducer.comments[offline_id];
5962
+ if (!commentToRemove) {
5963
+ throw new Error(`Comment with offline_id ${offline_id} not found in store`);
5964
+ }
5778
5965
  this.client.store.dispatch(removeIssueComment(offline_id));
5779
- return this.enqueueRequest({
5966
+ const promise = this.enqueueRequest({
5780
5967
  description: "Delete comment",
5781
5968
  method: HttpMethod.DELETE,
5782
5969
  url: `/issues/comments/${offline_id}/`,
5783
5970
  blockers: [offline_id],
5784
5971
  blocks: []
5785
5972
  });
5973
+ promise.catch(() => {
5974
+ this.client.store.dispatch(addIssueComment(commentToRemove));
5975
+ });
5976
+ return promise;
5977
+ }
5978
+ async refreshStore() {
5979
+ const { store } = this.client;
5980
+ const result = await this.enqueueRequest({
5981
+ description: "Get comments",
5982
+ method: HttpMethod.GET,
5983
+ // TODO: Choose between /issues/comments/in-project/${projectId}/ and /projects/${projectId}/issue-comments/
5984
+ url: `/projects/${store.getState().projectReducer.activeProjectId}/comments/`,
5985
+ blockers: [],
5986
+ blocks: []
5987
+ });
5988
+ store.dispatch(setIssueComments(result));
5989
+ }
5990
+ }
5991
+ class IssueUpdateService extends BaseApiService {
5992
+ async refreshStore() {
5993
+ const { store } = this.client;
5994
+ const result = await this.enqueueRequest({
5995
+ description: "Get issue updates",
5996
+ method: HttpMethod.GET,
5997
+ url: `/projects/${store.getState().projectReducer.activeProjectId}/issues/updates/`,
5998
+ blockers: [],
5999
+ blocks: []
6000
+ });
6001
+ let filteredResult = result.filter(onlyUniqueOfflineIds);
6002
+ filteredResult = filteredResult.map((comment) => {
6003
+ return { ...comment };
6004
+ });
6005
+ if (result.length !== filteredResult.length) {
6006
+ console.error(
6007
+ `Received duplicate comments from the API (new length ${filteredResult.length}); filtered in browser.`
6008
+ );
6009
+ }
6010
+ store.dispatch(setIssueUpdates(filteredResult));
5786
6011
  }
5787
6012
  }
5788
6013
  class IssueService extends BaseApiService {
@@ -5863,7 +6088,83 @@ class IssueService extends BaseApiService {
5863
6088
  return [offlineIssues, promise];
5864
6089
  }
5865
6090
  update(issue) {
6091
+ const state = this.client.store.getState();
6092
+ const issueToBeUpdated = state.issueReducer.issues[issue.offline_id];
6093
+ if (!issueToBeUpdated) {
6094
+ throw new Error(
6095
+ `Attempting to update an issue with offline_id ${issue.offline_id} that doesn't exist in the store`
6096
+ );
6097
+ }
5866
6098
  this.client.store.dispatch(updateIssue(issue));
6099
+ const changes = {};
6100
+ for (const issueUpdateChange of [
6101
+ IssueUpdateChange.TITLE,
6102
+ IssueUpdateChange.DESCRIPTION,
6103
+ IssueUpdateChange.STATUS,
6104
+ IssueUpdateChange.CATEGORY,
6105
+ IssueUpdateChange.PRIORITY,
6106
+ IssueUpdateChange.ASSIGNED_TO,
6107
+ IssueUpdateChange.DUE_DATE
6108
+ ]) {
6109
+ if (issueUpdateChange in issue && issue[issueUpdateChange] !== issueToBeUpdated[issueUpdateChange]) {
6110
+ switch (issueUpdateChange) {
6111
+ case "category": {
6112
+ let categoryOrNull = null;
6113
+ const categoryIdOrNull = issue[issueUpdateChange];
6114
+ if (categoryIdOrNull) {
6115
+ categoryOrNull = state.categoryReducer.categories[categoryIdOrNull] ?? null;
6116
+ if (!categoryOrNull)
6117
+ throw new Error(
6118
+ `Trying to update issue category to ${categoryIdOrNull} which does not exist in store`
6119
+ );
6120
+ }
6121
+ changes[issueUpdateChange] = categoryOrNull ? {
6122
+ name: categoryOrNull.name,
6123
+ color: categoryOrNull.color,
6124
+ offline_id: categoryOrNull.offline_id
6125
+ } : null;
6126
+ break;
6127
+ }
6128
+ case "assigned_to": {
6129
+ let userOrNull = null;
6130
+ const userIdOrNull = issue[issueUpdateChange];
6131
+ if (userIdOrNull) {
6132
+ userOrNull = state.userReducer.users[userIdOrNull] ?? null;
6133
+ if (!userOrNull)
6134
+ throw new Error(
6135
+ `Trying to update issue assigned_to to ${userIdOrNull} which does not exist in store`
6136
+ );
6137
+ }
6138
+ changes[issueUpdateChange] = userOrNull ? {
6139
+ full_name: userOrNull.username,
6140
+ id: userOrNull.id
6141
+ } : null;
6142
+ break;
6143
+ }
6144
+ case "description":
6145
+ changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
6146
+ break;
6147
+ case "title":
6148
+ changes[issueUpdateChange] = issue[issueUpdateChange] ?? null;
6149
+ break;
6150
+ case "priority":
6151
+ changes[issueUpdateChange] = issue[issueUpdateChange];
6152
+ break;
6153
+ case "status":
6154
+ changes[issueUpdateChange] = issue[issueUpdateChange];
6155
+ break;
6156
+ case "due_date":
6157
+ changes[issueUpdateChange] = issue[issueUpdateChange] ? issue[issueUpdateChange] : null;
6158
+ }
6159
+ }
6160
+ }
6161
+ const offlineIssueUpdate = offline({
6162
+ created_by: state.userReducer.currentUser.id,
6163
+ submitted_at: (/* @__PURE__ */ new Date()).toISOString(),
6164
+ issue: issueToBeUpdated.offline_id,
6165
+ changes
6166
+ });
6167
+ this.client.store.dispatch(addIssueUpdate(offlineIssueUpdate));
5867
6168
  const promise = this.enqueueRequest({
5868
6169
  description: "Edit issue",
5869
6170
  method: HttpMethod.PATCH,
@@ -5872,23 +6173,30 @@ class IssueService extends BaseApiService {
5872
6173
  blockers: [issue.offline_id],
5873
6174
  blocks: [issue.offline_id]
5874
6175
  });
6176
+ promise.catch(() => {
6177
+ this.client.store.dispatch(updateIssue(issueToBeUpdated));
6178
+ this.client.store.dispatch(removeIssueUpdate(offlineIssueUpdate.offline_id));
6179
+ });
5875
6180
  const fullIssue = this.client.store.getState().issueReducer.issues[issue.offline_id];
5876
6181
  return [fullIssue, promise];
5877
6182
  }
5878
6183
  async remove(id) {
5879
6184
  const { store } = this.client;
5880
6185
  const state = store.getState();
6186
+ const dispatch = store.dispatch;
5881
6187
  const backup = state.issueReducer.issues[id];
5882
6188
  if (!backup) {
5883
6189
  throw new Error(`No issue with id ${id} found in the store`);
5884
6190
  }
5885
6191
  const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue === id);
5886
6192
  const attachmentsOfIssue = selectAttachmentsOfIssue(id)(state);
5887
- this.client.store.dispatch(removeIssue(id));
5888
- store.dispatch(addActiveProjectIssuesCount(-1));
5889
- if (attachmentsOfIssue.length > 0) {
5890
- this.client.store.dispatch(removeAttachmentsOfIssue(id));
5891
- }
6193
+ const updatesOfIssue = selectIssueUpdatesOfIssue(id)(state);
6194
+ dispatch(removeIssue(id));
6195
+ dispatch(addActiveProjectIssuesCount(-1));
6196
+ if (attachmentsOfIssue.length > 0)
6197
+ dispatch(removeAttachmentsOfIssue(id));
6198
+ if (updatesOfIssue.length > 0)
6199
+ dispatch(removeIssueUpdates(updatesOfIssue.map(({ offline_id }) => offline_id)));
5892
6200
  try {
5893
6201
  return await this.enqueueRequest({
5894
6202
  description: "Delete issue",
@@ -5898,9 +6206,10 @@ class IssueService extends BaseApiService {
5898
6206
  blocks: []
5899
6207
  });
5900
6208
  } catch (e) {
5901
- this.client.store.dispatch(addIssue(backup));
5902
- this.client.store.dispatch(addIssueAttachments(attachments));
5903
- store.dispatch(addActiveProjectIssuesCount(1));
6209
+ dispatch(addIssue(backup));
6210
+ dispatch(addIssueAttachments(attachments));
6211
+ dispatch(addIssueUpdates(updatesOfIssue));
6212
+ dispatch(addActiveProjectIssuesCount(1));
5904
6213
  throw e;
5905
6214
  }
5906
6215
  }
@@ -6017,6 +6326,7 @@ class MainService extends BaseApiService {
6017
6326
  }
6018
6327
  if (currentOrgId) {
6019
6328
  await this.client.organizations.fetchInitialOrganizationData(currentOrgId, false);
6329
+ void this.client.teams.refreshStore();
6020
6330
  }
6021
6331
  if (!isProjectIdValid) {
6022
6332
  if (validProjects.length !== 0) {
@@ -6082,6 +6392,7 @@ class MainService extends BaseApiService {
6082
6392
  store.dispatch(setProjectAttachments(project_attachments));
6083
6393
  });
6084
6394
  void this.client.documents.refreshStore();
6395
+ void this.client.issueUpdates.refreshStore();
6085
6396
  }
6086
6397
  store.dispatch(setIsFetchingInitialData(false));
6087
6398
  if (overwrite) {
@@ -7535,6 +7846,142 @@ class AgentService extends BaseApiService {
7535
7846
  });
7536
7847
  }
7537
7848
  }
7849
+ class TeamService extends BaseApiService {
7850
+ add(teamPayload) {
7851
+ const { store } = this.client;
7852
+ const state = store.getState();
7853
+ const activeOrganizationId = state.organizationReducer.activeOrganizationId;
7854
+ if (!activeOrganizationId) {
7855
+ throw new Error(`Expected active organization to be set, got ${activeOrganizationId}`);
7856
+ }
7857
+ const offlineTeam = offline({
7858
+ ...teamPayload,
7859
+ organization: activeOrganizationId
7860
+ // TODO: uncomment once supported
7861
+ // submitted_at: new Date().toISOString(),
7862
+ // created_by: state.userReducer.currentUser.id,
7863
+ });
7864
+ store.dispatch(addTeam(offlineTeam));
7865
+ const promise = this.enqueueRequest({
7866
+ description: "Create team",
7867
+ method: HttpMethod.POST,
7868
+ url: `/organizations/${activeOrganizationId}/teams/`,
7869
+ payload: offlineTeam,
7870
+ // No blocks since users and organizations are not offline
7871
+ blockers: [],
7872
+ blocks: [offlineTeam.offline_id]
7873
+ });
7874
+ promise.then((createdTeam) => {
7875
+ store.dispatch(setTeam(createdTeam));
7876
+ }).catch(() => {
7877
+ store.dispatch(deleteTeam(offlineTeam.offline_id));
7878
+ });
7879
+ return [offlineTeam, promise];
7880
+ }
7881
+ // TODO: @Audiopolis / Magnus - should we pass a offline_id as one arg and a UpdatedTeamProps as a second arg instead of this set up?
7882
+ update(team) {
7883
+ const { store } = this.client;
7884
+ const teamToBeUpdated = store.getState().teamReducer.teams[team.offline_id];
7885
+ const offlineUpdatedTeam = {
7886
+ ...teamToBeUpdated,
7887
+ ...team
7888
+ };
7889
+ store.dispatch(updateTeam(offlineUpdatedTeam));
7890
+ const promise = this.enqueueRequest({
7891
+ description: "Update team",
7892
+ method: HttpMethod.PATCH,
7893
+ url: `/organizations/teams/${team.offline_id}/`,
7894
+ payload: offlineUpdatedTeam,
7895
+ blockers: [team.offline_id],
7896
+ blocks: [team.offline_id]
7897
+ });
7898
+ promise.then((updatedTeam) => {
7899
+ store.dispatch(setTeam(updatedTeam));
7900
+ }).catch(() => {
7901
+ store.dispatch(setTeam(teamToBeUpdated));
7902
+ });
7903
+ return [offlineUpdatedTeam, promise];
7904
+ }
7905
+ async delete(teamId) {
7906
+ const { store } = this.client;
7907
+ const state = store.getState();
7908
+ const team = state.teamReducer.teams[teamId];
7909
+ if (!team) {
7910
+ throw new Error(`Expected team with id ${teamId} to exist`);
7911
+ }
7912
+ store.dispatch(deleteTeam(teamId));
7913
+ try {
7914
+ return await this.enqueueRequest({
7915
+ description: "Delete team",
7916
+ method: HttpMethod.DELETE,
7917
+ url: `/organizations/teams/${teamId}/`,
7918
+ blockers: [teamId],
7919
+ blocks: [teamId]
7920
+ });
7921
+ } catch (e) {
7922
+ store.dispatch(setTeam(team));
7923
+ throw e;
7924
+ }
7925
+ }
7926
+ async setMembers(teamId, members) {
7927
+ const { store } = this.client;
7928
+ const team = store.getState().teamReducer.teams[teamId];
7929
+ if (!team) {
7930
+ throw new Error(`Expected team with id ${teamId} to exist`);
7931
+ }
7932
+ if (members.length !== new Set(members).size) {
7933
+ throw new Error("Duplicate members found in the list");
7934
+ }
7935
+ store.dispatch(updateTeam({ ...team, members }));
7936
+ const promise = this.enqueueRequest({
7937
+ description: "Set team members",
7938
+ method: HttpMethod.PUT,
7939
+ url: `/organizations/teams/${teamId}/set-members/`,
7940
+ payload: {
7941
+ members
7942
+ },
7943
+ blockers: [teamId],
7944
+ blocks: [teamId]
7945
+ });
7946
+ promise.catch(() => {
7947
+ store.dispatch(setTeam(team));
7948
+ });
7949
+ return promise;
7950
+ }
7951
+ async addMembers(teamId, members) {
7952
+ const { store } = this.client;
7953
+ const team = store.getState().teamReducer.teams[teamId];
7954
+ if (!team) {
7955
+ throw new Error(`Expected team with id ${teamId} to exist`);
7956
+ }
7957
+ const newMembers = [...team.members, ...members];
7958
+ return this.setMembers(teamId, newMembers);
7959
+ }
7960
+ async removeMembers(teamId, members) {
7961
+ const { store } = this.client;
7962
+ const team = store.getState().teamReducer.teams[teamId];
7963
+ if (!team) {
7964
+ throw new Error(`Expected team with id ${teamId} to exist`);
7965
+ }
7966
+ const newMembers = team.members.filter((member) => !members.includes(member));
7967
+ return this.setMembers(teamId, newMembers);
7968
+ }
7969
+ async refreshStore() {
7970
+ const { store } = this.client;
7971
+ const activeOrganizationId = store.getState().organizationReducer.activeOrganizationId;
7972
+ if (!activeOrganizationId) {
7973
+ throw new Error(`Expected active organization to be set, got ${activeOrganizationId}`);
7974
+ }
7975
+ const result = await this.enqueueRequest({
7976
+ description: "Fetch teams",
7977
+ method: HttpMethod.GET,
7978
+ url: `/organizations/${activeOrganizationId}/teams/`,
7979
+ blockers: [],
7980
+ blocks: []
7981
+ });
7982
+ store.dispatch(setTeams(result));
7983
+ }
7984
+ }
7538
7985
  class OvermapSDK {
7539
7986
  constructor(apiUrl, store) {
7540
7987
  __publicField(this, "API_URL");
@@ -7549,6 +7996,7 @@ class OvermapSDK {
7549
7996
  __publicField(this, "organizationAccess", new OrganizationAccessService(this));
7550
7997
  __publicField(this, "issues", new IssueService(this));
7551
7998
  __publicField(this, "issueComments", new IssueCommentService(this));
7999
+ __publicField(this, "issueUpdates", new IssueUpdateService(this));
7552
8000
  __publicField(this, "workspaces", new WorkspaceService(this));
7553
8001
  __publicField(this, "main", new MainService(this));
7554
8002
  __publicField(this, "components", new ComponentService(this));
@@ -7563,6 +8011,7 @@ class OvermapSDK {
7563
8011
  __publicField(this, "emailDomains", new EmailDomainsService(this));
7564
8012
  __publicField(this, "licenses", new LicenseService(this));
7565
8013
  __publicField(this, "documents", new DocumentService(this));
8014
+ __publicField(this, "teams", new TeamService(this));
7566
8015
  this.API_URL = apiUrl;
7567
8016
  this.store = store;
7568
8017
  }
@@ -12004,8 +12453,7 @@ class BaseSelectField extends BaseField {
12004
12453
  description: "List possible options for the user to select from.",
12005
12454
  required: true,
12006
12455
  identifier: `${path}options`,
12007
- minimum_length: 2,
12008
- maximum_length: 20
12456
+ minimum_length: 2
12009
12457
  }),
12010
12458
  showDirectly: true
12011
12459
  }
@@ -13022,52 +13470,54 @@ const styles$4 = {
13022
13470
  Footer,
13023
13471
  Loading
13024
13472
  };
13025
- const ImageCard = memo((props) => {
13026
- const { file, alt, error: error2, size, rightSlot, className, truncateLength, ...rest } = props;
13027
- const fileCardRef = useRef(null);
13028
- const imageInsetRef = useRef(null);
13029
- const fileCardSize = useSize(fileCardRef);
13030
- useLayoutEffect(() => {
13031
- if (!imageInsetRef.current || !fileCardSize)
13032
- return;
13033
- imageInsetRef.current.style.height = `${fileCardSize.height * 4}px`;
13034
- }, [fileCardSize]);
13035
- const fileName2 = useMemo(() => {
13036
- if (!file)
13037
- return;
13038
- return truncateLength !== void 0 ? truncate(file.name, truncateLength) : file.name;
13039
- }, [file, truncateLength]);
13040
- return /* @__PURE__ */ jsxs(
13041
- Flex,
13042
- {
13043
- className: classNames$1(className, styles$4.ImageCard),
13044
- width: "100%",
13045
- direction: "column",
13046
- position: "relative",
13047
- height: "max-content",
13048
- gap: "0",
13049
- ...rest,
13050
- children: [
13051
- !file && !error2 && /* @__PURE__ */ jsx(Flex, { width: "100%", height: "100%", align: "center", justify: "center", position: "absolute", children: /* @__PURE__ */ jsx(Spinner, {}) }),
13052
- /* @__PURE__ */ jsx(Inset, { className: styles$4.ImageInset, ref: imageInsetRef, clip: "padding-box", side: "y", pb: "0", children: file && !error2 && /* @__PURE__ */ jsx("img", { className: styles$4.Image, src: URL.createObjectURL(file), alt: alt ?? file.name }) }),
13053
- /* @__PURE__ */ jsx(
13054
- OvermapItem,
13055
- {
13056
- className: classNames$1(styles$4.Footer, {
13057
- [styles$4.Loading]: !file
13058
- }),
13059
- size,
13060
- ref: fileCardRef,
13061
- leftSlot: error2 ? /* @__PURE__ */ jsx(RiIcon, { icon: "RiFileWarningLine" }) : file && /* @__PURE__ */ jsx(FileIcon, { fileType: file.type }),
13062
- rightSlot,
13063
- children: error2 ?? fileName2
13064
- }
13065
- )
13066
- ]
13067
- }
13068
- );
13069
- });
13070
- ImageCard.displayName = "ImageCard";
13473
+ const ImageCard = memo(
13474
+ forwardRef((props, forwardedRef) => {
13475
+ const { file, alt, error: error2, size, rightSlot, className, truncateLength, ...rest } = props;
13476
+ const fileCardRef = useRef(null);
13477
+ const imageInsetRef = useRef(null);
13478
+ const fileCardSize = useSize(fileCardRef);
13479
+ useLayoutEffect(() => {
13480
+ if (!imageInsetRef.current || !fileCardSize)
13481
+ return;
13482
+ imageInsetRef.current.style.height = `${fileCardSize.height * 4}px`;
13483
+ }, [fileCardSize]);
13484
+ const fileName2 = useMemo(() => {
13485
+ if (!file)
13486
+ return;
13487
+ return truncateLength !== void 0 ? truncate(file.name, truncateLength) : file.name;
13488
+ }, [file, truncateLength]);
13489
+ return /* @__PURE__ */ jsxs(
13490
+ Flex,
13491
+ {
13492
+ className: classNames$1(className, styles$4.ImageCard),
13493
+ width: "100%",
13494
+ direction: "column",
13495
+ position: "relative",
13496
+ height: "max-content",
13497
+ gap: "0",
13498
+ ref: forwardedRef,
13499
+ ...rest,
13500
+ children: [
13501
+ !file && !error2 && /* @__PURE__ */ jsx(Flex, { width: "100%", height: "100%", align: "center", justify: "center", position: "absolute", children: /* @__PURE__ */ jsx(Spinner, {}) }),
13502
+ /* @__PURE__ */ jsx(Inset, { className: styles$4.ImageInset, ref: imageInsetRef, clip: "padding-box", side: "y", pb: "0", children: file && !error2 && /* @__PURE__ */ jsx("img", { className: styles$4.Image, src: URL.createObjectURL(file), alt: alt ?? file.name }) }),
13503
+ /* @__PURE__ */ jsx(
13504
+ OvermapItem,
13505
+ {
13506
+ className: classNames$1(styles$4.Footer, {
13507
+ [styles$4.Loading]: !file
13508
+ }),
13509
+ size,
13510
+ ref: fileCardRef,
13511
+ leftSlot: error2 ? /* @__PURE__ */ jsx(RiIcon, { icon: "RiFileWarningLine" }) : file && /* @__PURE__ */ jsx(FileIcon, { fileType: file.type }),
13512
+ rightSlot,
13513
+ children: error2 ?? fileName2
13514
+ }
13515
+ )
13516
+ ]
13517
+ }
13518
+ );
13519
+ })
13520
+ );
13071
13521
  const UploadInput = memo((props) => {
13072
13522
  var _a2;
13073
13523
  const [{ inputId, labelId, size, severity, helpText, showInputOnly, field, fieldProps }, rest] = useFormikInput(props);
@@ -14204,17 +14654,15 @@ const FieldActions = memo((props) => {
14204
14654
  Action.key
14205
14655
  )) }),
14206
14656
  /* @__PURE__ */ jsx(Box, { display: forMobile(true, "block"), children: /* @__PURE__ */ jsx(
14207
- DropdownItemMenu,
14657
+ OvermapDropdownMenu,
14208
14658
  {
14209
14659
  trigger: /* @__PURE__ */ jsx(IconButton, { variant: "ghost", "aria-label": "Actions menu", children: /* @__PURE__ */ jsx(RiIcon, { icon: "RiMore2Line" }) }),
14210
14660
  items: actions.map((Action) => {
14211
14661
  var _a2;
14212
14662
  return {
14213
- content: /* @__PURE__ */ jsxs(Flex$1, { gap: "2", align: "center", children: [
14214
- /* @__PURE__ */ jsx(Action.Icon, {}),
14215
- Action.text
14216
- ] }, Action.key),
14217
- onSelect: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
14663
+ leftSlot: /* @__PURE__ */ jsx(Action.Icon, {}),
14664
+ children: Action.text,
14665
+ onClick: (_a2 = Action.buttonProps) == null ? void 0 : _a2.onClick
14218
14666
  };
14219
14667
  })
14220
14668
  }
@@ -14272,10 +14720,8 @@ const useFieldTypeItems = (onSelect = () => null) => {
14272
14720
  const field = FieldTypeToClsMapping[identifier];
14273
14721
  const Icon = field.Icon;
14274
14722
  return {
14275
- content: /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "2", children: [
14276
- /* @__PURE__ */ jsx(Icon, {}),
14277
- /* @__PURE__ */ jsx(Text$1, { children: field.fieldTypeName })
14278
- ] }, identifier),
14723
+ children: field.fieldTypeName,
14724
+ leftSlot: /* @__PURE__ */ jsx(Icon, {}),
14279
14725
  value: identifier,
14280
14726
  onSelect: () => {
14281
14727
  onSelect(identifier);
@@ -14479,7 +14925,7 @@ const FieldBuilder = memo((props) => {
14479
14925
  }
14480
14926
  ),
14481
14927
  /* @__PURE__ */ jsxs(Flex$1, { align: "center", gap: "3", children: [
14482
- /* @__PURE__ */ jsx(Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.content }),
14928
+ /* @__PURE__ */ jsx(Badge, { className: styles.typeBadge, children: (_f = fieldTypeItems.flat().find((item) => item.value === type)) == null ? void 0 : _f.children }),
14483
14929
  showPopoverInputs && /* @__PURE__ */ jsx(FieldSettingsPopover, { popoverInputs, hasError: popoverHasErrors })
14484
14930
  ] }),
14485
14931
  resolvedImage && /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -14840,7 +15286,7 @@ const FieldSectionWithActions = memo((props) => {
14840
15286
  )),
14841
15287
  droppableProvided.placeholder,
14842
15288
  /* @__PURE__ */ jsx(
14843
- DropdownItemMenu,
15289
+ OvermapDropdownMenu,
14844
15290
  {
14845
15291
  trigger: /* @__PURE__ */ jsxs(Button, { type: "button", variant: "soft", children: [
14846
15292
  /* @__PURE__ */ jsx(RiIcon, { icon: "RiAddLine" }),
@@ -15276,6 +15722,8 @@ export {
15276
15722
  IssuePriority,
15277
15723
  IssueService,
15278
15724
  IssueStatus,
15725
+ IssueUpdateChange,
15726
+ IssueUpdateService,
15279
15727
  LicenseLevel,
15280
15728
  LicenseService,
15281
15729
  LicenseStatus,
@@ -15314,6 +15762,7 @@ export {
15314
15762
  SpreadsheetViewer,
15315
15763
  StringField,
15316
15764
  StringInput,
15765
+ TeamService,
15317
15766
  TextField,
15318
15767
  TextInput,
15319
15768
  UserFormService,
@@ -15339,6 +15788,10 @@ export {
15339
15788
  addIssue,
15340
15789
  addIssueAttachment,
15341
15790
  addIssueAttachments,
15791
+ addIssueComment,
15792
+ addIssueComments,
15793
+ addIssueUpdate,
15794
+ addIssueUpdates,
15342
15795
  addLicenses,
15343
15796
  addOrReplaceCategories,
15344
15797
  addOrReplaceIssueComment,
@@ -15351,6 +15804,7 @@ export {
15351
15804
  addStageCompletion,
15352
15805
  addStageCompletions,
15353
15806
  addStages,
15807
+ addTeam,
15354
15808
  addToRecentIssues,
15355
15809
  addUserForm,
15356
15810
  addUserFormRevision,
@@ -15390,6 +15844,7 @@ export {
15390
15844
  defaultStore,
15391
15845
  deleteComponentType,
15392
15846
  deleteProject,
15847
+ deleteTeam,
15393
15848
  deleteUserForm,
15394
15849
  deleteUserFormRevision,
15395
15850
  deleteUserFormRevisions,
@@ -15498,6 +15953,9 @@ export {
15498
15953
  removeIssue,
15499
15954
  removeIssueAttachment,
15500
15955
  removeIssueComment,
15956
+ removeIssueComments,
15957
+ removeIssueUpdate,
15958
+ removeIssueUpdates,
15501
15959
  removeOrganizationAccess,
15502
15960
  removeProjectAccess,
15503
15961
  removeProjectAccessesOfProject,
@@ -15559,11 +16017,13 @@ export {
15559
16017
  selectCompletedStages,
15560
16018
  selectComponent,
15561
16019
  selectComponentAttachmentMapping,
16020
+ selectComponentSubmissionMapping,
15562
16021
  selectComponentType,
15563
16022
  selectComponentTypeAttachmentMapping,
15564
16023
  selectComponentTypeForm,
15565
16024
  selectComponentTypeFromComponent,
15566
16025
  selectComponentTypeFromComponents,
16026
+ selectComponentTypeStagesMapping,
15567
16027
  selectComponentTypes,
15568
16028
  selectComponentTypesByName,
15569
16029
  selectComponentTypesFromIds,
@@ -15571,6 +16031,7 @@ export {
15571
16031
  selectComponents,
15572
16032
  selectComponentsByType,
15573
16033
  selectComponentsFromComponentType,
16034
+ selectComponentsMapping,
15574
16035
  selectCreateProjectType,
15575
16036
  selectCurrentUser,
15576
16037
  selectDeletedRequests,
@@ -15599,6 +16060,8 @@ export {
15599
16060
  selectIssueAttachmentMapping,
15600
16061
  selectIssueAttachments,
15601
16062
  selectIssueMapping,
16063
+ selectIssueUpdateMapping,
16064
+ selectIssueUpdatesOfIssue,
15602
16065
  selectIssues,
15603
16066
  selectLatestFormRevision,
15604
16067
  selectLatestRetryTime,
@@ -15650,6 +16113,7 @@ export {
15650
16113
  selectSortedOrganizationUsers,
15651
16114
  selectSortedProjectUsers,
15652
16115
  selectSortedProjects,
16116
+ selectStage,
15653
16117
  selectStageFormIdsFromStageIds,
15654
16118
  selectStageMapping,
15655
16119
  selectStages,
@@ -15660,11 +16124,16 @@ export {
15660
16124
  selectSubmissionsForComponent,
15661
16125
  selectSubmissionsForForm,
15662
16126
  selectSubmissionsForIssue,
16127
+ selectTeams,
16128
+ selectTeamsMapping,
16129
+ selectTeamsOfOrganization,
16130
+ selectTeamsOfUser,
15663
16131
  selectUploadUrl,
15664
16132
  selectUsedColors,
15665
16133
  selectUser,
15666
16134
  selectUserForm,
15667
16135
  selectUserFormMapping,
16136
+ selectUserFormSubmission,
15668
16137
  selectUsersAsMapping,
15669
16138
  selectVisibleStatuses,
15670
16139
  selectVisibleUserIds,
@@ -15694,7 +16163,9 @@ export {
15694
16163
  setIsImportingProjectFile,
15695
16164
  setIsLoading,
15696
16165
  setIssueAttachments,
16166
+ setIssueComment,
15697
16167
  setIssueComments,
16168
+ setIssueUpdates,
15698
16169
  setIssues,
15699
16170
  setLicenses,
15700
16171
  setLoggedIn,
@@ -15709,6 +16180,8 @@ export {
15709
16180
  setSectionExpanded,
15710
16181
  setShowTooltips,
15711
16182
  setStageCompletions,
16183
+ setTeam,
16184
+ setTeams,
15712
16185
  setTokens,
15713
16186
  setTourStep,
15714
16187
  setUploadUrl,
@@ -15725,6 +16198,8 @@ export {
15725
16198
  slugify,
15726
16199
  spacesToDashesLower,
15727
16200
  successColor,
16201
+ teamReducer,
16202
+ teamSlice,
15728
16203
  toFileNameSafeString,
15729
16204
  toOfflineIdRecord,
15730
16205
  toggleComponentTypeVisibility,
@@ -15747,6 +16222,7 @@ export {
15747
16222
  updateProjectAccess,
15748
16223
  updateProjectAttachment,
15749
16224
  updateStages,
16225
+ updateTeam,
15750
16226
  useAppDispatch,
15751
16227
  useAppSelector,
15752
16228
  useFieldInput,