@overmap-ai/core 1.0.25 → 1.0.26

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.
@@ -617,15 +617,15 @@ const wrapMigration = (migrator) => (state) => {
617
617
  };
618
618
  const migrations = [initialVersioning, signOut, signOut, createOutboxState];
619
619
  const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
620
- const initialState$k = {
620
+ const initialState$l = {
621
621
  accessToken: "",
622
622
  refreshToken: "",
623
623
  isLoggedIn: false
624
624
  };
625
625
  const authSlice = createSlice({
626
626
  name: "auth",
627
- initialState: initialState$k,
628
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
627
+ initialState: initialState$l,
628
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
629
629
  reducers: {
630
630
  setTokens: (state, action) => {
631
631
  state.accessToken = action.payload.accessToken;
@@ -1328,7 +1328,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
1328
1328
  return getLocalDateString(date);
1329
1329
  return relative.format(days, "days");
1330
1330
  });
1331
- const initialState$j = {
1331
+ const initialState$k = {
1332
1332
  categories: {},
1333
1333
  usedCategoryColors: [],
1334
1334
  categoryVisibility: {
@@ -1338,8 +1338,8 @@ const initialState$j = {
1338
1338
  };
1339
1339
  const categorySlice = createSlice({
1340
1340
  name: "categories",
1341
- initialState: initialState$j,
1342
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1341
+ initialState: initialState$k,
1342
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1343
1343
  reducers: {
1344
1344
  setCategories: (state, action) => {
1345
1345
  if (!Array.isArray(action.payload))
@@ -1472,13 +1472,13 @@ const selectHiddenCategoryCount = (state) => {
1472
1472
  return hiddenCategoryCount;
1473
1473
  };
1474
1474
  const categoryReducer = categorySlice.reducer;
1475
- const initialState$i = {
1475
+ const initialState$j = {
1476
1476
  components: {}
1477
1477
  };
1478
1478
  const componentSlice = createSlice({
1479
1479
  name: "components",
1480
- initialState: initialState$i,
1481
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1480
+ initialState: initialState$j,
1481
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1482
1482
  reducers: {
1483
1483
  addComponent: (state, action) => {
1484
1484
  state.components[action.payload.offline_id] = action.payload;
@@ -1590,13 +1590,13 @@ const {
1590
1590
  removeAllComponentsOfType
1591
1591
  } = componentSlice.actions;
1592
1592
  const componentReducer = componentSlice.reducer;
1593
- const initialState$h = {
1593
+ const initialState$i = {
1594
1594
  completionsByComponentId: {}
1595
1595
  };
1596
1596
  const componentStageCompletionSlice = createSlice({
1597
1597
  name: "componentStageCompletions",
1598
- initialState: initialState$h,
1599
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
1598
+ initialState: initialState$i,
1599
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1600
1600
  reducers: {
1601
1601
  addStageCompletion: (state, action) => {
1602
1602
  let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
@@ -1647,13 +1647,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
1647
1647
  return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
1648
1648
  };
1649
1649
  const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
1650
- const initialState$g = {
1650
+ const initialState$h = {
1651
1651
  stages: {}
1652
1652
  };
1653
1653
  const componentStageSlice = createSlice({
1654
1654
  name: "componentStages",
1655
- initialState: initialState$g,
1656
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
1655
+ initialState: initialState$h,
1656
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
1657
1657
  reducers: {
1658
1658
  addStages: (state, action) => {
1659
1659
  Object.assign(state.stages, toOfflineIdRecord(action.payload));
@@ -1713,14 +1713,14 @@ const selectStagesFromStageIds = restructureCreateSelectorWithArgs(
1713
1713
  );
1714
1714
  const { addStages, updateStages, removeStages } = componentStageSlice.actions;
1715
1715
  const componentStageReducer = componentStageSlice.reducer;
1716
- const initialState$f = {
1716
+ const initialState$g = {
1717
1717
  componentTypes: {},
1718
1718
  hiddenComponentTypeIds: {}
1719
1719
  };
1720
1720
  const componentTypeSlice = createSlice({
1721
1721
  name: "componentTypes",
1722
- initialState: initialState$f,
1723
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$f)),
1722
+ initialState: initialState$g,
1723
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
1724
1724
  reducers: {
1725
1725
  addComponentType: (state, action) => {
1726
1726
  state.componentTypes[action.payload.offline_id] = action.payload;
@@ -1779,13 +1779,13 @@ const selectComponentTypesByName = restructureCreateSelectorWithArgs(
1779
1779
  const selectHiddenComponentTypeIds = (state) => state.componentTypeReducer.hiddenComponentTypeIds;
1780
1780
  const { addComponentType, setComponentTypes, toggleComponentTypeVisibility, deleteComponentType } = componentTypeSlice.actions;
1781
1781
  const componentTypeReducer = componentTypeSlice.reducer;
1782
- const initialState$e = {
1782
+ const initialState$f = {
1783
1783
  workspaces: {},
1784
1784
  activeWorkspaceId: null
1785
1785
  };
1786
1786
  const workspaceSlice = createSlice({
1787
1787
  name: "workspace",
1788
- initialState: initialState$e,
1788
+ initialState: initialState$f,
1789
1789
  // The `reducers` field lets us define reducers and generate associated actions
1790
1790
  reducers: {
1791
1791
  setWorkspaces: (state, action) => {
@@ -1842,7 +1842,7 @@ const selectPermittedWorkspaceIds = createSelector(
1842
1842
  );
1843
1843
  const workspaceReducer = workspaceSlice.reducer;
1844
1844
  const maxRecentIssues = 10;
1845
- const initialState$d = {
1845
+ const initialState$e = {
1846
1846
  issues: {},
1847
1847
  attachments: {},
1848
1848
  comments: {},
@@ -1854,9 +1854,9 @@ const initialState$d = {
1854
1854
  };
1855
1855
  const issueSlice = createSlice({
1856
1856
  name: "issues",
1857
- initialState: initialState$d,
1857
+ initialState: initialState$e,
1858
1858
  extraReducers: (builder) => builder.addCase("RESET", (state) => {
1859
- Object.assign(state, initialState$d);
1859
+ Object.assign(state, initialState$e);
1860
1860
  }),
1861
1861
  reducers: {
1862
1862
  setIssues: (state, action) => {
@@ -2187,15 +2187,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
2187
2187
  }
2188
2188
  );
2189
2189
  const issueReducer = issueSlice.reducer;
2190
- const initialState$c = {
2190
+ const initialState$d = {
2191
2191
  s3Urls: {}
2192
2192
  };
2193
2193
  const msPerHour = 1e3 * 60 * 60;
2194
2194
  const msPerWeek = msPerHour * 24 * 7;
2195
2195
  const fileSlice = createSlice({
2196
2196
  name: "file",
2197
- initialState: initialState$c,
2198
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2197
+ initialState: initialState$d,
2198
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2199
2199
  reducers: {
2200
2200
  setUploadUrl: (state, action) => {
2201
2201
  const { url, fields, sha1 } = action.payload;
@@ -2222,7 +2222,7 @@ const selectUploadUrl = (sha1) => (state) => {
2222
2222
  return url;
2223
2223
  };
2224
2224
  const fileReducer = fileSlice.reducer;
2225
- const initialState$b = {
2225
+ const initialState$c = {
2226
2226
  // TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
2227
2227
  mapStyle: MapStyle.SATELLITE,
2228
2228
  showTooltips: false,
@@ -2230,8 +2230,8 @@ const initialState$b = {
2230
2230
  };
2231
2231
  const mapSlice = createSlice({
2232
2232
  name: "map",
2233
- initialState: initialState$b,
2234
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2233
+ initialState: initialState$c,
2234
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2235
2235
  reducers: {
2236
2236
  setMapStyle: (state, action) => {
2237
2237
  state.mapStyle = action.payload;
@@ -2249,26 +2249,209 @@ const selectMapStyle = (state) => state.mapReducer.mapStyle;
2249
2249
  const selectShowTooltips = (state) => state.mapReducer.showTooltips;
2250
2250
  const selectCenterMapToProject = (state) => state.mapReducer.centerMapToProject;
2251
2251
  const mapReducer = mapSlice.reducer;
2252
+ var ProjectAccessLevel = /* @__PURE__ */ ((ProjectAccessLevel2) => {
2253
+ ProjectAccessLevel2[ProjectAccessLevel2["BASIC"] = 0] = "BASIC";
2254
+ ProjectAccessLevel2[ProjectAccessLevel2["ADMIN"] = 2] = "ADMIN";
2255
+ return ProjectAccessLevel2;
2256
+ })(ProjectAccessLevel || {});
2257
+ var OrganizationAccessLevel = /* @__PURE__ */ ((OrganizationAccessLevel2) => {
2258
+ OrganizationAccessLevel2[OrganizationAccessLevel2["BASIC"] = 0] = "BASIC";
2259
+ OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
2260
+ return OrganizationAccessLevel2;
2261
+ })(OrganizationAccessLevel || {});
2262
+ var ProjectType = /* @__PURE__ */ ((ProjectType2) => {
2263
+ ProjectType2[ProjectType2["PERSONAL"] = 0] = "PERSONAL";
2264
+ ProjectType2[ProjectType2["ORGANIZATION"] = 2] = "ORGANIZATION";
2265
+ return ProjectType2;
2266
+ })(ProjectType || {});
2267
+ var VerificationCodeType = /* @__PURE__ */ ((VerificationCodeType2) => {
2268
+ VerificationCodeType2[VerificationCodeType2["USER_REGISTRATION"] = 0] = "USER_REGISTRATION";
2269
+ VerificationCodeType2[VerificationCodeType2["APPLICATION_INVITE"] = 2] = "APPLICATION_INVITE";
2270
+ VerificationCodeType2[VerificationCodeType2["PROJECT_INVITE"] = 4] = "PROJECT_INVITE";
2271
+ VerificationCodeType2[VerificationCodeType2["ORGANIZATION_INVITE"] = 6] = "ORGANIZATION_INVITE";
2272
+ VerificationCodeType2[VerificationCodeType2["ADD_EMAIL_DOMAIN"] = 8] = "ADD_EMAIL_DOMAIN";
2273
+ VerificationCodeType2[VerificationCodeType2["RESET_PASSWORD"] = 10] = "RESET_PASSWORD";
2274
+ return VerificationCodeType2;
2275
+ })(VerificationCodeType || {});
2276
+ const initialState$b = {
2277
+ users: {},
2278
+ currentUser: {
2279
+ id: 0,
2280
+ username: "",
2281
+ email: "",
2282
+ profile: { file: null, file_sha1: null, favourite_project_ids: [], tour_step: -1 }
2283
+ }
2284
+ };
2285
+ const userSlice = createSlice({
2286
+ name: "users",
2287
+ initialState: initialState$b,
2288
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2289
+ reducers: {
2290
+ setUsers: (state, action) => {
2291
+ const usersMapping = {};
2292
+ action.payload.forEach((user) => {
2293
+ usersMapping[user.id] = user;
2294
+ });
2295
+ state.users = usersMapping;
2296
+ },
2297
+ addUsers: (state, action) => {
2298
+ for (const user of action.payload) {
2299
+ state.users[user.id] = user;
2300
+ }
2301
+ },
2302
+ setCurrentUser: (state, action) => {
2303
+ state.currentUser = action.payload;
2304
+ },
2305
+ setProfilePicture: (state, action) => {
2306
+ state.currentUser.profile.file = action.payload.file ?? null;
2307
+ state.currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null;
2308
+ const currentUser = state.users[state.currentUser.id];
2309
+ if (!currentUser) {
2310
+ throw new Error("Unable to find current user in users slice");
2311
+ }
2312
+ currentUser.profile.file = action.payload.file ?? null;
2313
+ currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null;
2314
+ },
2315
+ addFavouriteProjectId: (state, action) => {
2316
+ state.currentUser.profile.favourite_project_ids.push(action.payload);
2317
+ },
2318
+ removeFavouriteProjectId: (state, action) => {
2319
+ state.currentUser.profile.favourite_project_ids = state.currentUser.profile.favourite_project_ids.filter(
2320
+ (id) => id !== action.payload
2321
+ );
2322
+ },
2323
+ setTourStep: (state, action) => {
2324
+ state.currentUser.profile.tour_step = action.payload;
2325
+ },
2326
+ removeUser: (state, action) => {
2327
+ delete state.users[action.payload];
2328
+ }
2329
+ }
2330
+ });
2331
+ const {
2332
+ setCurrentUser,
2333
+ setProfilePicture,
2334
+ setUsers,
2335
+ addUsers,
2336
+ addFavouriteProjectId,
2337
+ removeFavouriteProjectId,
2338
+ setTourStep,
2339
+ removeUser
2340
+ } = userSlice.actions;
2341
+ const selectCurrentUser = (state) => state.userReducer.currentUser;
2342
+ const selectUser = (userId) => (state) => {
2343
+ if (userId === null)
2344
+ return void 0;
2345
+ return state.userReducer.users[userId];
2346
+ };
2347
+ const selectUsersAsMapping = (state) => state.userReducer.users;
2348
+ const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
2349
+ const userReducer = userSlice.reducer;
2252
2350
  const initialState$a = {
2351
+ organizationAccesses: {},
2352
+ activeOrganizationAccessId: null
2353
+ };
2354
+ const organizationAccessSlice = createSlice({
2355
+ name: "organizationAccess",
2356
+ initialState: initialState$a,
2357
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2358
+ reducers: {
2359
+ setOrganizationAccesses: (state, action) => {
2360
+ if (!Array.isArray(action.payload))
2361
+ throw new Error("Expected an array of OrganizationAccess");
2362
+ if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2363
+ throw new Error("Tried to use setOrganizationAccesses reducer with duplicate ID's");
2364
+ }
2365
+ const organizationAccesses = {};
2366
+ for (const organizationAccess of action.payload) {
2367
+ organizationAccesses[organizationAccess.offline_id] = organizationAccess;
2368
+ }
2369
+ state.organizationAccesses = organizationAccesses;
2370
+ },
2371
+ updateOrganizationAccess: (state, action) => {
2372
+ if (action.payload.offline_id in state.organizationAccesses) {
2373
+ state.organizationAccesses[action.payload.offline_id] = action.payload;
2374
+ } else {
2375
+ throw new Error(
2376
+ `Tried to update organization access with ID that doesn't exist: ${action.payload.offline_id}`
2377
+ );
2378
+ }
2379
+ },
2380
+ removeOrganizationAccess: (state, action) => {
2381
+ if (action.payload.offline_id in state.organizationAccesses) {
2382
+ delete state.organizationAccesses[action.payload.offline_id];
2383
+ } else {
2384
+ throw new Error(
2385
+ `Tried to remove organization access with ID that doesn't exist: ${action.payload.offline_id}`
2386
+ );
2387
+ }
2388
+ },
2389
+ setActiveOrganizationAccessId: (state, action) => {
2390
+ state.activeOrganizationAccessId = action.payload;
2391
+ }
2392
+ }
2393
+ });
2394
+ const {
2395
+ setOrganizationAccesses,
2396
+ updateOrganizationAccess,
2397
+ removeOrganizationAccess,
2398
+ setActiveOrganizationAccessId
2399
+ } = organizationAccessSlice.actions;
2400
+ const selectOrganizationAccesses = (state) => {
2401
+ return state.organizationAccessReducer.organizationAccesses;
2402
+ };
2403
+ const selectOrganizationAccess = (organizationAccessId) => (state) => {
2404
+ return state.organizationAccessReducer.organizationAccesses[organizationAccessId];
2405
+ };
2406
+ const selectActiveOrganizationAccess = (state) => {
2407
+ const activeOrganizationAccessId = state.organizationAccessReducer.activeOrganizationAccessId;
2408
+ if (!activeOrganizationAccessId) {
2409
+ return null;
2410
+ }
2411
+ return state.organizationAccessReducer.organizationAccesses[activeOrganizationAccessId] ?? null;
2412
+ };
2413
+ const selectOrganizationAccessForUser = (user) => (state) => {
2414
+ return Object.values(state.organizationAccessReducer.organizationAccesses).find(
2415
+ (organizationAccess) => organizationAccess.user === user.id
2416
+ );
2417
+ };
2418
+ const selectOrganizationAccessUserMapping = (state) => {
2419
+ const organizationAccesses = {};
2420
+ for (const organizationAccess of Object.values(state.organizationAccessReducer.organizationAccesses)) {
2421
+ organizationAccesses[organizationAccess.user] = organizationAccess;
2422
+ }
2423
+ return organizationAccesses;
2424
+ };
2425
+ const organizationAccessReducer = organizationAccessSlice.reducer;
2426
+ const initialState$9 = {
2253
2427
  organizations: {},
2254
2428
  activeOrganizationId: null
2255
2429
  };
2256
2430
  const organizationSlice = createSlice({
2257
2431
  name: "organizations",
2258
- initialState: initialState$a,
2259
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2432
+ initialState: initialState$9,
2433
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
2260
2434
  reducers: {
2261
2435
  setOrganizations: (state, action) => {
2262
2436
  for (const org of action.payload) {
2263
2437
  state.organizations[org.id] = org;
2264
2438
  }
2265
2439
  },
2440
+ updateActiveOrganization: (state, action) => {
2441
+ if (!state.activeOrganizationId) {
2442
+ throw new Error("Cannot update name of active organization. Active organization ID does not exist");
2443
+ }
2444
+ if (state.activeOrganizationId !== action.payload.id) {
2445
+ throw new Error("Tried updating active organization with different organization");
2446
+ }
2447
+ state.organizations[state.activeOrganizationId] = action.payload;
2448
+ },
2266
2449
  setActiveOrganizationId: (state, action) => {
2267
2450
  state.activeOrganizationId = action.payload;
2268
2451
  }
2269
2452
  }
2270
2453
  });
2271
- const { setOrganizations, setActiveOrganizationId } = organizationSlice.actions;
2454
+ const { setOrganizations, setActiveOrganizationId, updateActiveOrganization } = organizationSlice.actions;
2272
2455
  const selectActiveOrganizationId = (state) => {
2273
2456
  return state.organizationReducer.activeOrganizationId;
2274
2457
  };
@@ -2286,6 +2469,35 @@ const selectActiveOrganization = (state) => {
2286
2469
  }
2287
2470
  return organization;
2288
2471
  };
2472
+ const selectOrganizationUsersIds = createSelector(
2473
+ [selectOrganizationAccesses],
2474
+ (organizationAccesses) => Object.values(organizationAccesses).map((organizationAccess) => organizationAccess.user)
2475
+ );
2476
+ const selectOrganizationUsersAsMapping = createSelector(
2477
+ [selectOrganizationUsersIds, selectUsersAsMapping],
2478
+ (organizationUserIds, users) => organizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {})
2479
+ );
2480
+ const selectSortedOrganizationUsers = createSelector(
2481
+ [selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],
2482
+ (currentUser, userMapping, organizationAccessMapping) => {
2483
+ return Object.values(userMapping).sort((userA, userB) => {
2484
+ if (userA.id === currentUser.id) {
2485
+ return -1;
2486
+ } else if (userB.id === currentUser.id) {
2487
+ return 1;
2488
+ }
2489
+ const organizationAccessesA = organizationAccessMapping[userA.id];
2490
+ const organizationAccessesB = organizationAccessMapping[userB.id];
2491
+ if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === (organizationAccessesB == null ? void 0 : organizationAccessesB.access_level)) {
2492
+ return userA.username.localeCompare(userB.username);
2493
+ }
2494
+ if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === OrganizationAccessLevel.ADMIN) {
2495
+ return -1;
2496
+ }
2497
+ return 1;
2498
+ });
2499
+ }
2500
+ );
2289
2501
  const selectOrganization = (id) => (state) => {
2290
2502
  return state.organizationReducer.organizations[id];
2291
2503
  };
@@ -2306,14 +2518,14 @@ const createOfflineAction = (request2, baseUrl) => {
2306
2518
  }
2307
2519
  };
2308
2520
  };
2309
- const initialState$9 = {
2521
+ const initialState$8 = {
2310
2522
  deletedRequests: [],
2311
2523
  latestRetryTime: 0
2312
2524
  };
2313
2525
  const outboxSlice = createSlice({
2314
2526
  name: "outbox",
2315
- initialState: initialState$9,
2316
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
2527
+ initialState: initialState$8,
2528
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
2317
2529
  reducers: {
2318
2530
  // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
2319
2531
  // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
@@ -2345,13 +2557,13 @@ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
2345
2557
  const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
2346
2558
  const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
2347
2559
  const outboxReducer = outboxSlice.reducer;
2348
- const initialState$8 = {
2560
+ const initialState$7 = {
2349
2561
  projectAccesses: {}
2350
2562
  };
2351
2563
  const projectAccessSlice = createSlice({
2352
2564
  name: "projectAccess",
2353
- initialState: initialState$8,
2354
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
2565
+ initialState: initialState$7,
2566
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
2355
2567
  reducers: {
2356
2568
  setProjectAccesses: (state, action) => {
2357
2569
  if (!Array.isArray(action.payload))
@@ -2419,31 +2631,7 @@ const selectProjectAccessUserMapping = (state) => {
2419
2631
  return projectAccesses;
2420
2632
  };
2421
2633
  const projectAccessReducer = projectAccessSlice.reducer;
2422
- var ProjectAccessLevel = /* @__PURE__ */ ((ProjectAccessLevel2) => {
2423
- ProjectAccessLevel2[ProjectAccessLevel2["BASIC"] = 0] = "BASIC";
2424
- ProjectAccessLevel2[ProjectAccessLevel2["ADMIN"] = 2] = "ADMIN";
2425
- return ProjectAccessLevel2;
2426
- })(ProjectAccessLevel || {});
2427
- var OrganizationAccessLevel = /* @__PURE__ */ ((OrganizationAccessLevel2) => {
2428
- OrganizationAccessLevel2[OrganizationAccessLevel2["BASIC"] = 0] = "BASIC";
2429
- OrganizationAccessLevel2[OrganizationAccessLevel2["ADMIN"] = 2] = "ADMIN";
2430
- return OrganizationAccessLevel2;
2431
- })(OrganizationAccessLevel || {});
2432
- var ProjectType = /* @__PURE__ */ ((ProjectType2) => {
2433
- ProjectType2[ProjectType2["PERSONAL"] = 0] = "PERSONAL";
2434
- ProjectType2[ProjectType2["ORGANIZATION"] = 2] = "ORGANIZATION";
2435
- return ProjectType2;
2436
- })(ProjectType || {});
2437
- var VerificationCodeType = /* @__PURE__ */ ((VerificationCodeType2) => {
2438
- VerificationCodeType2[VerificationCodeType2["USER_REGISTRATION"] = 0] = "USER_REGISTRATION";
2439
- VerificationCodeType2[VerificationCodeType2["APPLICATION_INVITE"] = 2] = "APPLICATION_INVITE";
2440
- VerificationCodeType2[VerificationCodeType2["PROJECT_INVITE"] = 4] = "PROJECT_INVITE";
2441
- VerificationCodeType2[VerificationCodeType2["ORGANIZATION_INVITE"] = 6] = "ORGANIZATION_INVITE";
2442
- VerificationCodeType2[VerificationCodeType2["ADD_EMAIL_DOMAIN"] = 8] = "ADD_EMAIL_DOMAIN";
2443
- VerificationCodeType2[VerificationCodeType2["RESET_PASSWORD"] = 10] = "RESET_PASSWORD";
2444
- return VerificationCodeType2;
2445
- })(VerificationCodeType || {});
2446
- const initialState$7 = {
2634
+ const initialState$6 = {
2447
2635
  projects: {},
2448
2636
  activeProjectId: null,
2449
2637
  recentProjectIds: [],
@@ -2452,7 +2640,7 @@ const initialState$7 = {
2452
2640
  };
2453
2641
  const projectSlice = createSlice({
2454
2642
  name: "projects",
2455
- initialState: initialState$7,
2643
+ initialState: initialState$6,
2456
2644
  reducers: {
2457
2645
  setProjects: (state, action) => {
2458
2646
  const projectsMap = {};
@@ -2509,14 +2697,43 @@ const selectActiveProject = (state) => {
2509
2697
  if (!activeProjectId) {
2510
2698
  return null;
2511
2699
  }
2512
- return state.projectReducer.projects[activeProjectId] ?? null;
2513
- };
2514
- const selectRecentProjects = (state) => {
2515
- return state.projectReducer.recentProjectIds;
2516
- };
2517
- const selectCreateProjectType = (state) => state.projectReducer.createProjectType;
2518
- const projectReducer = projectSlice.reducer;
2519
- const initialState$6 = {
2700
+ return state.projectReducer.projects[activeProjectId] ?? null;
2701
+ };
2702
+ const selectRecentProjects = (state) => {
2703
+ return state.projectReducer.recentProjectIds;
2704
+ };
2705
+ const selectCreateProjectType = (state) => state.projectReducer.createProjectType;
2706
+ const projectReducer = projectSlice.reducer;
2707
+ const selectProjectUsersIds = createSelector(
2708
+ [selectProjectAccesses],
2709
+ (projectAccesses) => Object.values(projectAccesses).map((projectAccess) => projectAccess.user)
2710
+ );
2711
+ const selectProjectUsersAsMapping = createSelector(
2712
+ [selectProjectUsersIds, selectUsersAsMapping],
2713
+ (projectUserIds, users) => projectUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {})
2714
+ );
2715
+ const selectSortedProjectUsers = createSelector(
2716
+ [selectCurrentUser, selectProjectUsersAsMapping, selectProjectAccessUserMapping],
2717
+ (currentUser, userMapping, projectAccessMapping) => {
2718
+ return Object.values(userMapping).sort((userA, userB) => {
2719
+ if (userA.id === currentUser.id) {
2720
+ return -1;
2721
+ } else if (userB.id === currentUser.id) {
2722
+ return 1;
2723
+ }
2724
+ const projectAccessesA = projectAccessMapping[userA.id];
2725
+ const projectAccessesB = projectAccessMapping[userB.id];
2726
+ if ((projectAccessesA == null ? void 0 : projectAccessesA.access_level) === (projectAccessesB == null ? void 0 : projectAccessesB.access_level)) {
2727
+ return userA.username.localeCompare(userB.username);
2728
+ }
2729
+ if ((projectAccessesA == null ? void 0 : projectAccessesA.access_level) === ProjectAccessLevel.ADMIN) {
2730
+ return -1;
2731
+ }
2732
+ return 1;
2733
+ });
2734
+ }
2735
+ );
2736
+ const initialState$5 = {
2520
2737
  projectFiles: {},
2521
2738
  activeProjectFileId: null,
2522
2739
  isImportingProjectFile: false,
@@ -2524,8 +2741,8 @@ const initialState$6 = {
2524
2741
  };
2525
2742
  const projectFileSlice = createSlice({
2526
2743
  name: "projectFiles",
2527
- initialState: initialState$6,
2528
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
2744
+ initialState: initialState$5,
2745
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$5)),
2529
2746
  reducers: {
2530
2747
  addOrReplaceProjectFiles: (state, action) => {
2531
2748
  for (let fileObj of action.payload) {
@@ -2626,12 +2843,12 @@ const selectProjectFiles = createSelector(
2626
2843
  const selectActiveProjectFileId = (state) => state.projectFileReducer.activeProjectFileId;
2627
2844
  const selectIsImportingProjectFile = (state) => state.projectFileReducer.isImportingProjectFile;
2628
2845
  const projectFileReducer = projectFileSlice.reducer;
2629
- const initialState$5 = {
2846
+ const initialState$4 = {
2630
2847
  isRehydrated: false
2631
2848
  };
2632
2849
  const rehydratedSlice = createSlice({
2633
2850
  name: "rehydrated",
2634
- initialState: initialState$5,
2851
+ initialState: initialState$4,
2635
2852
  // The `reducers` field lets us define reducers and generate associated actions
2636
2853
  reducers: {
2637
2854
  setRehydrated: (state, action) => {
@@ -2641,7 +2858,7 @@ const rehydratedSlice = createSlice({
2641
2858
  });
2642
2859
  const selectRehydrated = (state) => state.rehydratedReducer.isRehydrated;
2643
2860
  const rehydratedReducer = rehydratedSlice.reducer;
2644
- const initialState$4 = {
2861
+ const initialState$3 = {
2645
2862
  useIssueTemplate: false,
2646
2863
  placementMode: false,
2647
2864
  enableClustering: true,
@@ -2656,8 +2873,8 @@ const initialState$4 = {
2656
2873
  };
2657
2874
  const settingSlice = createSlice({
2658
2875
  name: "settings",
2659
- initialState: initialState$4,
2660
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$4)),
2876
+ initialState: initialState$3,
2877
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
2661
2878
  reducers: {
2662
2879
  setEnableDuplicateIssues: (state, action) => {
2663
2880
  state.useIssueTemplate = action.payload;
@@ -2720,7 +2937,7 @@ function considerCachingRevision(revision, formId, preferPending = false) {
2720
2937
  function getLatestRevisionFromCache(formId) {
2721
2938
  return LATEST_REVISION_CACHE[formId];
2722
2939
  }
2723
- const initialState$3 = {
2940
+ const initialState$2 = {
2724
2941
  userForms: {},
2725
2942
  revisions: {},
2726
2943
  submissions: {},
@@ -2728,8 +2945,8 @@ const initialState$3 = {
2728
2945
  };
2729
2946
  const userFormSlice = createSlice({
2730
2947
  name: "userForms",
2731
- initialState: initialState$3,
2732
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$3)),
2948
+ initialState: initialState$2,
2949
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$2)),
2733
2950
  reducers: {
2734
2951
  setUserForms: (state, action) => {
2735
2952
  state.userForms = {};
@@ -2977,171 +3194,38 @@ const selectNumberOfUserForms = createSelector([selectUserFormMapping], (userFor
2977
3194
  return Object.keys(userForms).length;
2978
3195
  });
2979
3196
  const userFormReducer = userFormSlice.reducer;
2980
- const initialState$2 = {
2981
- users: {},
2982
- currentUser: {
2983
- id: 0,
2984
- username: "",
2985
- email: "",
2986
- profile: { file: null, file_sha1: null, favourite_project_ids: [], tour_step: -1 }
2987
- }
2988
- };
2989
- const userSlice = createSlice({
2990
- name: "users",
2991
- initialState: initialState$2,
2992
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$2)),
2993
- reducers: {
2994
- setUsers: (state, action) => {
2995
- const usersMapping = {};
2996
- action.payload.forEach((user) => {
2997
- usersMapping[user.id] = user;
2998
- });
2999
- state.users = usersMapping;
3000
- },
3001
- setCurrentUser: (state, action) => {
3002
- state.currentUser = action.payload;
3003
- },
3004
- setProfilePicture: (state, action) => {
3005
- state.currentUser.profile.file = action.payload.file ?? null;
3006
- state.currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null;
3007
- const currentUser = state.users[state.currentUser.id];
3008
- if (!currentUser) {
3009
- throw new Error("Unable to find current user in users slice");
3010
- }
3011
- currentUser.profile.file = action.payload.file ?? null;
3012
- currentUser.profile.file_sha1 = action.payload.file_sha1 ?? null;
3013
- },
3014
- addFavouriteProjectId: (state, action) => {
3015
- state.currentUser.profile.favourite_project_ids.push(action.payload);
3016
- },
3017
- removeFavouriteProjectId: (state, action) => {
3018
- state.currentUser.profile.favourite_project_ids = state.currentUser.profile.favourite_project_ids.filter(
3019
- (id) => id !== action.payload
3020
- );
3021
- },
3022
- setTourStep: (state, action) => {
3023
- state.currentUser.profile.tour_step = action.payload;
3024
- },
3025
- removeUser: (state, action) => {
3026
- delete state.users[action.payload];
3027
- }
3028
- }
3029
- });
3030
- const {
3031
- setCurrentUser,
3032
- setProfilePicture,
3033
- setUsers,
3034
- addFavouriteProjectId,
3035
- removeFavouriteProjectId,
3036
- setTourStep,
3037
- removeUser
3038
- } = userSlice.actions;
3039
- const selectCurrentUser = (state) => state.userReducer.currentUser;
3040
- const selectUser = (userId) => (state) => {
3041
- if (userId === null)
3042
- return void 0;
3043
- return state.userReducer.users[userId];
3044
- };
3045
- const selectUsersAsMapping = (state) => state.userReducer.users;
3046
- const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
3047
- const selectSortedUsers = createSelector(
3048
- [selectCurrentUser, selectUsersAsMapping, selectProjectAccessUserMapping],
3049
- (currentUser, userMapping, projectAccessMapping) => {
3050
- return Object.values(userMapping).sort((userA, userB) => {
3051
- if (userA.id === currentUser.id) {
3052
- return -1;
3053
- } else if (userB.id === currentUser.id) {
3054
- return 1;
3055
- }
3056
- const projectAccessesA = projectAccessMapping[userA.id];
3057
- const projectAccessesB = projectAccessMapping[userB.id];
3058
- if ((projectAccessesA == null ? void 0 : projectAccessesA.access_level) === (projectAccessesB == null ? void 0 : projectAccessesB.access_level)) {
3059
- return userA.username.localeCompare(userB.username);
3060
- }
3061
- if ((projectAccessesA == null ? void 0 : projectAccessesA.access_level) === ProjectAccessLevel.ADMIN) {
3062
- return -1;
3063
- }
3064
- return 1;
3065
- });
3066
- }
3067
- );
3068
- const userReducer = userSlice.reducer;
3069
3197
  const initialState$1 = {
3070
- organizationAccesses: {},
3071
- activeOrganizationAccessId: null
3198
+ emailDomains: {}
3072
3199
  };
3073
- const organizationAccessSlice = createSlice({
3074
- name: "organizationAccess",
3200
+ const emailDomainsSlice = createSlice({
3201
+ name: "emailDomains",
3075
3202
  initialState: initialState$1,
3076
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$1)),
3077
3203
  reducers: {
3078
- setOrganizationAccesses: (state, action) => {
3079
- if (!Array.isArray(action.payload))
3080
- throw new Error("Expected an array of OrganizationAccess");
3081
- if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
3082
- throw new Error("Tried to use setOrganizationAccesses reducer with duplicate ID's");
3083
- }
3084
- const organizationAccesses = {};
3085
- for (const organizationAccess of action.payload) {
3086
- organizationAccesses[organizationAccess.offline_id] = organizationAccess;
3087
- }
3088
- state.organizationAccesses = organizationAccesses;
3204
+ setEmailDomains: (state, action) => {
3205
+ const emailDomains = {};
3206
+ action.payload.forEach((emailDomain) => {
3207
+ emailDomains[emailDomain.offline_id] = emailDomain;
3208
+ });
3209
+ state.emailDomains = emailDomains;
3089
3210
  },
3090
- updateOrganizationAccess: (state, action) => {
3091
- if (action.payload.offline_id in state.organizationAccesses) {
3092
- state.organizationAccesses[action.payload.offline_id] = action.payload;
3093
- } else {
3094
- throw new Error(
3095
- `Tried to update organization access with ID that doesn't exist: ${action.payload.offline_id}`
3096
- );
3097
- }
3211
+ addEmailDomain: (state, action) => {
3212
+ state.emailDomains[action.payload.offline_id] = action.payload;
3098
3213
  },
3099
- removeOrganizationAccess: (state, action) => {
3100
- if (action.payload.offline_id in state.organizationAccesses) {
3101
- delete state.organizationAccesses[action.payload.offline_id];
3214
+ removeEmailDomain: (state, action) => {
3215
+ if (action.payload.offline_id in state.emailDomains) {
3216
+ delete state.emailDomains[action.payload.offline_id];
3102
3217
  } else {
3103
- throw new Error(
3104
- `Tried to remove organization access with ID that doesn't exist: ${action.payload.offline_id}`
3105
- );
3218
+ throw new Error(`Tried to remove email domain with ID that doesn't exist: ${action.payload.offline_id}`);
3106
3219
  }
3107
- },
3108
- setActiveOrganizationAccessId: (state, action) => {
3109
- state.activeOrganizationAccessId = action.payload;
3110
3220
  }
3111
3221
  }
3112
3222
  });
3113
- const {
3114
- setOrganizationAccesses,
3115
- updateOrganizationAccess,
3116
- removeOrganizationAccess,
3117
- setActiveOrganizationAccessId
3118
- } = organizationAccessSlice.actions;
3119
- const selectOrganizationAccesses = (state) => {
3120
- return state.organizationAccessReducer.organizationAccesses;
3121
- };
3122
- const selectOrganizationAccess = (organizationAccessId) => (state) => {
3123
- return state.organizationAccessReducer.organizationAccesses[organizationAccessId];
3124
- };
3125
- const selectActiveOrganizationAccess = (state) => {
3126
- const activeOrganizationAccessId = state.organizationAccessReducer.activeOrganizationAccessId;
3127
- if (!activeOrganizationAccessId) {
3128
- return null;
3129
- }
3130
- return state.organizationAccessReducer.organizationAccesses[activeOrganizationAccessId] ?? null;
3131
- };
3132
- const selectOrganizationAccessForUser = (user) => (state) => {
3133
- return Object.values(state.organizationAccessReducer.organizationAccesses).find(
3134
- (organizationAccess) => organizationAccess.user === user.id
3135
- );
3136
- };
3137
- const selectOrganizationAccessUserMapping = (state) => {
3138
- const organizationAccesses = {};
3139
- Object.values(state.organizationAccessReducer.organizationAccesses).forEach((organizationAccess) => {
3140
- organizationAccesses[organizationAccess.user] = organizationAccess;
3141
- });
3142
- return organizationAccesses;
3143
- };
3144
- const organizationAccessReducer = organizationAccessSlice.reducer;
3223
+ const { setEmailDomains, addEmailDomain, removeEmailDomain } = emailDomainsSlice.actions;
3224
+ const selectEmailDomainsAsMapping = (state) => state.emailDomainsReducer.emailDomains;
3225
+ const selectSortedEmailDomains = (state) => Object.values(state.emailDomainsReducer.emailDomains).sort(
3226
+ (ed1, ed2) => ed1.domain.localeCompare(ed2.domain)
3227
+ );
3228
+ const emailDomainsReducer = emailDomainsSlice.reducer;
3145
3229
  const initialState = {
3146
3230
  version: 0
3147
3231
  };
@@ -3178,7 +3262,8 @@ const overmapReducers = {
3178
3262
  settingReducer,
3179
3263
  userFormReducer,
3180
3264
  userReducer,
3181
- workspaceReducer
3265
+ workspaceReducer,
3266
+ emailDomainsReducer
3182
3267
  };
3183
3268
  const overmapReducer = combineReducers(overmapReducers);
3184
3269
  const resetStore = "RESET";
@@ -4732,7 +4817,7 @@ class MainService extends BaseApiService {
4732
4817
  return result;
4733
4818
  });
4734
4819
  }
4735
- async fetchUsers(projectId) {
4820
+ async fetchProjectUsers(projectId) {
4736
4821
  return this.enqueueRequest({
4737
4822
  description: "Fetch users",
4738
4823
  method: HttpMethod.GET,
@@ -4741,6 +4826,15 @@ class MainService extends BaseApiService {
4741
4826
  blocks: []
4742
4827
  });
4743
4828
  }
4829
+ async fetchOrganizationUsers(orgId) {
4830
+ return this.enqueueRequest({
4831
+ description: "Fetch organization users",
4832
+ method: HttpMethod.GET,
4833
+ url: `/organizations/${orgId}/users/`,
4834
+ blockers: [],
4835
+ blocks: []
4836
+ });
4837
+ }
4744
4838
  // TODO:
4745
4839
  // Don't accept updateStore in ComponentService.list. Just return the offline objects and promise. Here, if
4746
4840
  // overwrite, use setComponents. Otherwise, use bulkAddComponents.
@@ -4759,8 +4853,8 @@ class MainService extends BaseApiService {
4759
4853
  projects.push({
4760
4854
  id: projectData.id,
4761
4855
  name: projectData.name,
4762
- owner_organization: projectData.owner_organization,
4763
- owner_user: projectData.owner_user,
4856
+ owner_organization: projectData.organization_owner,
4857
+ owner_user: projectData.user_owner,
4764
4858
  bounds: projectData.bounds
4765
4859
  });
4766
4860
  if (currentProjectId === projectData.id) {
@@ -4783,13 +4877,22 @@ class MainService extends BaseApiService {
4783
4877
  const firstOrg = organizationsData[0];
4784
4878
  const currProjObj = projects.find((project) => project.id === currentProjectId);
4785
4879
  const isOrgProject = !!(currProjObj == null ? void 0 : currProjObj.owner_organization);
4880
+ let currentOrgId = -1;
4786
4881
  if (isOrgProject && currProjObj.owner_organization) {
4787
- store.dispatch(setActiveOrganizationId(currProjObj.owner_organization));
4882
+ currentOrgId = currProjObj.owner_organization;
4788
4883
  } else if (firstOrg) {
4789
4884
  console.warn(
4790
4885
  "No active organization; using the first available one. TODO: No active organization in personal projects."
4791
4886
  );
4792
- store.dispatch(setActiveOrganizationId(firstOrg.id));
4887
+ currentOrgId = firstOrg.id;
4888
+ }
4889
+ if (currentOrgId !== -1) {
4890
+ store.dispatch(setActiveOrganizationId(currentOrgId));
4891
+ const orgUsersResultPromise = this.fetchOrganizationUsers(currentOrgId);
4892
+ const organizationAccessRefreshPromise = this.client.organizationAccess.refreshStore();
4893
+ const orgUsersResult = await orgUsersResultPromise;
4894
+ await organizationAccessRefreshPromise;
4895
+ store.dispatch(addUsers(orgUsersResult));
4793
4896
  }
4794
4897
  if (!isProjectIdValid) {
4795
4898
  if (projects.length !== 0) {
@@ -4812,13 +4915,11 @@ class MainService extends BaseApiService {
4812
4915
  }
4813
4916
  }
4814
4917
  if (currentProjectId) {
4815
- const usersResultPromise = this.fetchUsers(currentProjectId);
4918
+ const usersResultPromise = this.fetchProjectUsers(currentProjectId);
4816
4919
  const projectAccessRefreshPromise = this.client.projectAccesses.refreshStore();
4817
- const organizationAccessRefreshPromise = this.client.organizationAccess.refreshStore();
4818
4920
  const usersResult = await usersResultPromise;
4819
4921
  await projectAccessRefreshPromise;
4820
- await organizationAccessRefreshPromise;
4821
- store.dispatch(setUsers(usersResult));
4922
+ store.dispatch(addUsers(usersResult));
4822
4923
  }
4823
4924
  let currentWorkspaceId;
4824
4925
  const oldWorkspaceId = this.client.store.getState().workspaceReducer.activeWorkspaceId;
@@ -4844,6 +4945,7 @@ class MainService extends BaseApiService {
4844
4945
  void this.client.userForms.refreshStore().then(() => {
4845
4946
  void this.client.userFormSubmissions.refreshStore().then();
4846
4947
  });
4948
+ void this.client.emailDomains.refreshStore().then();
4847
4949
  }
4848
4950
  if (currentProjectId) {
4849
4951
  const [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId);
@@ -4867,21 +4969,18 @@ class MainService extends BaseApiService {
4867
4969
  }
4868
4970
  }
4869
4971
  class ProjectAccessService extends BaseApiService {
4870
- fetchAll(projectId) {
4871
- const { store } = this.client;
4872
- const promise = this.enqueueRequest({
4972
+ async fetchAll(projectId) {
4973
+ return this.enqueueRequest({
4873
4974
  description: "Get project accesses",
4874
4975
  method: HttpMethod.GET,
4875
4976
  url: `/projects/${projectId}/access/`,
4876
4977
  blockers: [],
4877
4978
  blocks: []
4878
4979
  });
4879
- const offlineProjectAccesses = Object.values(store.getState().projectAccessReducer.projectAccesses);
4880
- return [offlineProjectAccesses, promise];
4881
4980
  }
4882
- update(projectAccess) {
4981
+ async update(projectAccess) {
4883
4982
  this.client.store.dispatch(updateProjectAccess(projectAccess));
4884
- const promise = this.enqueueRequest({
4983
+ return this.enqueueRequest({
4885
4984
  description: "Edit project access",
4886
4985
  method: HttpMethod.PATCH,
4887
4986
  url: `/access/${projectAccess.offline_id}/`,
@@ -4889,10 +4988,9 @@ class ProjectAccessService extends BaseApiService {
4889
4988
  blockers: [projectAccess.offline_id],
4890
4989
  blocks: [projectAccess.offline_id]
4891
4990
  });
4892
- return [projectAccess, promise];
4893
4991
  }
4894
4992
  // TODO: Re-add user to project if removal fails
4895
- remove(projectAccess) {
4993
+ async remove(projectAccess) {
4896
4994
  const { store } = this.client;
4897
4995
  store.dispatch(removeProjectAccess(projectAccess));
4898
4996
  store.dispatch(removeUser(projectAccess.user));
@@ -4912,7 +5010,7 @@ class ProjectAccessService extends BaseApiService {
4912
5010
  if (!projectId) {
4913
5011
  throw new Error("No active project");
4914
5012
  }
4915
- const [_offlineProjectAccesses, promise] = this.fetchAll(projectId);
5013
+ const promise = this.fetchAll(projectId);
4916
5014
  const result = await promise;
4917
5015
  const activeProjectAccess = result.find((projectAccess) => projectAccess.user === currentUser.id);
4918
5016
  if (!activeProjectAccess) {
@@ -5509,6 +5607,31 @@ class WorkspaceService extends BaseApiService {
5509
5607
  }
5510
5608
  }
5511
5609
  class OrganizationAccessService extends BaseApiService {
5610
+ async update(organizationAccess) {
5611
+ const promise = this.enqueueRequest({
5612
+ description: "Edit organization access",
5613
+ method: HttpMethod.PATCH,
5614
+ url: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,
5615
+ payload: organizationAccess,
5616
+ blockers: [organizationAccess.offline_id],
5617
+ blocks: [organizationAccess.offline_id]
5618
+ });
5619
+ void promise.then(() => {
5620
+ this.client.store.dispatch(updateOrganizationAccess(organizationAccess));
5621
+ });
5622
+ return promise;
5623
+ }
5624
+ async remove(organizationAccess) {
5625
+ this.client.store.dispatch(removeOrganizationAccess(organizationAccess));
5626
+ this.client.store.dispatch(removeUser(organizationAccess.user));
5627
+ return this.enqueueRequest({
5628
+ description: "Remove organization access",
5629
+ method: HttpMethod.DELETE,
5630
+ url: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,
5631
+ blockers: [organizationAccess.offline_id],
5632
+ blocks: []
5633
+ });
5634
+ }
5512
5635
  async refreshStore() {
5513
5636
  const { store } = this.client;
5514
5637
  const state = store.getState();
@@ -5756,6 +5879,86 @@ class EmailVerificationService extends BaseApiService {
5756
5879
  return this.enqueueRequest(requestDetails);
5757
5880
  }
5758
5881
  }
5882
+ class EmailDomainsService extends BaseApiService {
5883
+ async fetchAll(orgId) {
5884
+ return this.enqueueRequest({
5885
+ description: "Fetch email domains for organization",
5886
+ method: HttpMethod.GET,
5887
+ url: `/organizations/${orgId}/email-domains/`,
5888
+ blockers: [orgId.toString()],
5889
+ blocks: []
5890
+ });
5891
+ }
5892
+ async add(orgId, email) {
5893
+ return this.enqueueRequest({
5894
+ description: "Add email domain to organization",
5895
+ method: HttpMethod.POST,
5896
+ url: `/organizations/${orgId}/email-domains/`,
5897
+ payload: { email },
5898
+ blockers: [orgId.toString(), "create-org"],
5899
+ blocks: []
5900
+ });
5901
+ }
5902
+ async remove(emailDomain) {
5903
+ this.client.store.dispatch(removeEmailDomain(emailDomain));
5904
+ return this.enqueueRequest({
5905
+ description: "Remove email domain from organization",
5906
+ method: HttpMethod.DELETE,
5907
+ url: `/organizations/${emailDomain.organization}/email-domains/${emailDomain.offline_id}/`,
5908
+ blockers: [emailDomain.domain],
5909
+ blocks: []
5910
+ }).catch((e) => {
5911
+ this.client.store.dispatch(addEmailDomain(emailDomain));
5912
+ throw e;
5913
+ });
5914
+ }
5915
+ async refreshStore() {
5916
+ const organizationId = this.client.store.getState().organizationReducer.activeOrganizationId;
5917
+ if (!organizationId) {
5918
+ throw new Error("No active organization");
5919
+ }
5920
+ const promise = this.fetchAll(organizationId);
5921
+ const result = await promise;
5922
+ this.client.store.dispatch(setEmailDomains(result));
5923
+ }
5924
+ }
5925
+ class OrganizationService extends BaseApiService {
5926
+ async create(name) {
5927
+ const result = await this.enqueueRequest({
5928
+ description: "Create organization",
5929
+ method: HttpMethod.POST,
5930
+ url: "/organizations/",
5931
+ payload: { name },
5932
+ blockers: [],
5933
+ blocks: [`add-org-${name}`, "create-org"]
5934
+ });
5935
+ await this.client.main.fetchInitialData(true);
5936
+ return result;
5937
+ }
5938
+ async update(organization) {
5939
+ const promise = this.enqueueRequest({
5940
+ description: "Edit organization",
5941
+ method: HttpMethod.PATCH,
5942
+ url: `/organizations/${organization.id}/`,
5943
+ payload: organization,
5944
+ blockers: [`add-org-${organization.name}`, organization.id.toString()],
5945
+ blocks: [organization.id.toString()]
5946
+ });
5947
+ return promise.then((result) => {
5948
+ this.client.store.dispatch(updateActiveOrganization(organization));
5949
+ return result;
5950
+ });
5951
+ }
5952
+ async invite(organizationId, email) {
5953
+ return this.enqueueRequest({
5954
+ description: "Invite user to organization",
5955
+ method: HttpMethod.POST,
5956
+ url: `/organizations/${organizationId}/invite/${email}/`,
5957
+ blockers: [],
5958
+ blocks: []
5959
+ });
5960
+ }
5961
+ }
5759
5962
  class OvermapSDK {
5760
5963
  constructor(apiUrl, store) {
5761
5964
  __publicField(this, "API_URL");
@@ -5765,6 +5968,7 @@ class OvermapSDK {
5765
5968
  __publicField(this, "auth", new AuthService(this));
5766
5969
  __publicField(this, "categories", new CategoryService(this));
5767
5970
  __publicField(this, "projectAccesses", new ProjectAccessService(this));
5971
+ __publicField(this, "organizations", new OrganizationService(this));
5768
5972
  __publicField(this, "organizationAccess", new OrganizationAccessService(this));
5769
5973
  __publicField(this, "issues", new IssueService(this));
5770
5974
  __publicField(this, "issueComments", new IssueCommentService(this));
@@ -5779,6 +5983,7 @@ class OvermapSDK {
5779
5983
  __publicField(this, "projects", new ProjectService(this));
5780
5984
  __publicField(this, "projectFiles", new ProjectFileService(this));
5781
5985
  __publicField(this, "emailVerification", new EmailVerificationService(this));
5986
+ __publicField(this, "emailDomains", new EmailDomainsService(this));
5782
5987
  this.API_URL = apiUrl;
5783
5988
  this.store = store;
5784
5989
  }
@@ -5821,6 +6026,7 @@ export {
5821
6026
  ComponentTypeService,
5822
6027
  DEFAULT_ISSUE_PRIORITY,
5823
6028
  DEFAULT_ISSUE_STATUS,
6029
+ EmailDomainsService,
5824
6030
  EmailVerificationService,
5825
6031
  FileService,
5826
6032
  GREEN,
@@ -5834,6 +6040,7 @@ export {
5834
6040
  OUTBOX_RETRY_DELAY,
5835
6041
  OrganizationAccessLevel,
5836
6042
  OrganizationAccessService,
6043
+ OrganizationService,
5837
6044
  OutboxCoordinator,
5838
6045
  OvermapContext,
5839
6046
  OvermapProvider,
@@ -5857,6 +6064,7 @@ export {
5857
6064
  addComponent,
5858
6065
  addComponentType,
5859
6066
  addComponentsInBatches,
6067
+ addEmailDomain,
5860
6068
  addFavouriteProjectId,
5861
6069
  addIssue,
5862
6070
  addOrReplaceCategories,
@@ -5876,6 +6084,7 @@ export {
5876
6084
  addUserFormSubmissionAttachment,
5877
6085
  addUserFormSubmissions,
5878
6086
  addUserForms,
6087
+ addUsers,
5879
6088
  addWorkspace,
5880
6089
  areArraysEqual,
5881
6090
  authReducer,
@@ -5915,6 +6124,8 @@ export {
5915
6124
  dequeue,
5916
6125
  discard,
5917
6126
  downloadInMemoryFile,
6127
+ emailDomainsReducer,
6128
+ emailDomainsSlice,
5918
6129
  emailRegex,
5919
6130
  enqueue,
5920
6131
  enqueueRequest,
@@ -5983,6 +6194,7 @@ export {
5983
6194
  removeCategory,
5984
6195
  removeColor,
5985
6196
  removeComponent,
6197
+ removeEmailDomain,
5986
6198
  removeFavouriteProjectId,
5987
6199
  removeIssue,
5988
6200
  removeIssueComment,
@@ -6041,6 +6253,7 @@ export {
6041
6253
  selectCreateProjectType,
6042
6254
  selectCurrentUser,
6043
6255
  selectDeletedRequests,
6256
+ selectEmailDomainsAsMapping,
6044
6257
  selectEnableClustering,
6045
6258
  selectEnableDuplicateIssues,
6046
6259
  selectEnablePlacementMode,
@@ -6075,6 +6288,8 @@ export {
6075
6288
  selectOrganizationAccessForUser,
6076
6289
  selectOrganizationAccessUserMapping,
6077
6290
  selectOrganizationAccesses,
6291
+ selectOrganizationUsersAsMapping,
6292
+ selectOrganizationUsersIds,
6078
6293
  selectOrganizations,
6079
6294
  selectPermittedWorkspaceIds,
6080
6295
  selectPhotoAttachmentsOfIssue,
@@ -6084,6 +6299,8 @@ export {
6084
6299
  selectProjectAccesses,
6085
6300
  selectProjectFileVisibility,
6086
6301
  selectProjectFiles,
6302
+ selectProjectUsersAsMapping,
6303
+ selectProjectUsersIds,
6087
6304
  selectProjects,
6088
6305
  selectRecentIssueIds,
6089
6306
  selectRecentIssuesAsSearchResults,
@@ -6091,7 +6308,9 @@ export {
6091
6308
  selectRehydrated,
6092
6309
  selectRevisionsForForm,
6093
6310
  selectShowTooltips,
6094
- selectSortedUsers,
6311
+ selectSortedEmailDomains,
6312
+ selectSortedOrganizationUsers,
6313
+ selectSortedProjectUsers,
6095
6314
  selectStageMapping,
6096
6315
  selectStages,
6097
6316
  selectStagesFromComponentType,
@@ -6126,6 +6345,7 @@ export {
6126
6345
  setComponents,
6127
6346
  setCreateProjectType,
6128
6347
  setCurrentUser,
6348
+ setEmailDomains,
6129
6349
  setEnableClustering,
6130
6350
  setEnableDuplicateIssues,
6131
6351
  setEnablePlacementMode,
@@ -6166,6 +6386,7 @@ export {
6166
6386
  unfavoriteForm,
6167
6387
  unhideAllCategories,
6168
6388
  unhideCategory,
6389
+ updateActiveOrganization,
6169
6390
  updateAttachment,
6170
6391
  updateComponent,
6171
6392
  updateIssue,