@overmap-ai/core 1.0.25 → 1.0.27-org-switcher-and-bug-fixes.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.
@@ -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,20 @@ 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);
4786
- if (isOrgProject && currProjObj.owner_organization) {
4787
- store.dispatch(setActiveOrganizationId(currProjObj.owner_organization));
4880
+ const userIsInProjectOrg = isOrgProject && currProjObj.owner_organization && organizationsData.find((organization) => organization.id === currProjObj.owner_organization);
4881
+ let currentOrgId = null;
4882
+ if (userIsInProjectOrg) {
4883
+ currentOrgId = currProjObj.owner_organization;
4788
4884
  } else if (firstOrg) {
4789
- console.warn(
4790
- "No active organization; using the first available one. TODO: No active organization in personal projects."
4791
- );
4792
- store.dispatch(setActiveOrganizationId(firstOrg.id));
4885
+ currentOrgId = firstOrg.id;
4886
+ }
4887
+ if (currentOrgId) {
4888
+ store.dispatch(setActiveOrganizationId(currentOrgId));
4889
+ const orgUsersResultPromise = this.fetchOrganizationUsers(currentOrgId);
4890
+ const organizationAccessRefreshPromise = this.client.organizationAccess.refreshStore();
4891
+ const orgUsersResult = await orgUsersResultPromise;
4892
+ await organizationAccessRefreshPromise;
4893
+ store.dispatch(addUsers(orgUsersResult));
4793
4894
  }
4794
4895
  if (!isProjectIdValid) {
4795
4896
  if (projects.length !== 0) {
@@ -4812,13 +4913,11 @@ class MainService extends BaseApiService {
4812
4913
  }
4813
4914
  }
4814
4915
  if (currentProjectId) {
4815
- const usersResultPromise = this.fetchUsers(currentProjectId);
4916
+ const usersResultPromise = this.fetchProjectUsers(currentProjectId);
4816
4917
  const projectAccessRefreshPromise = this.client.projectAccesses.refreshStore();
4817
- const organizationAccessRefreshPromise = this.client.organizationAccess.refreshStore();
4818
4918
  const usersResult = await usersResultPromise;
4819
4919
  await projectAccessRefreshPromise;
4820
- await organizationAccessRefreshPromise;
4821
- store.dispatch(setUsers(usersResult));
4920
+ store.dispatch(addUsers(usersResult));
4822
4921
  }
4823
4922
  let currentWorkspaceId;
4824
4923
  const oldWorkspaceId = this.client.store.getState().workspaceReducer.activeWorkspaceId;
@@ -4844,6 +4943,7 @@ class MainService extends BaseApiService {
4844
4943
  void this.client.userForms.refreshStore().then(() => {
4845
4944
  void this.client.userFormSubmissions.refreshStore().then();
4846
4945
  });
4946
+ void this.client.emailDomains.refreshStore().then();
4847
4947
  }
4848
4948
  if (currentProjectId) {
4849
4949
  const [_offlineAttachments, promise] = this.client.attachments.fetchAll(currentProjectId);
@@ -4867,21 +4967,18 @@ class MainService extends BaseApiService {
4867
4967
  }
4868
4968
  }
4869
4969
  class ProjectAccessService extends BaseApiService {
4870
- fetchAll(projectId) {
4871
- const { store } = this.client;
4872
- const promise = this.enqueueRequest({
4970
+ async fetchAll(projectId) {
4971
+ return this.enqueueRequest({
4873
4972
  description: "Get project accesses",
4874
4973
  method: HttpMethod.GET,
4875
4974
  url: `/projects/${projectId}/access/`,
4876
4975
  blockers: [],
4877
4976
  blocks: []
4878
4977
  });
4879
- const offlineProjectAccesses = Object.values(store.getState().projectAccessReducer.projectAccesses);
4880
- return [offlineProjectAccesses, promise];
4881
4978
  }
4882
- update(projectAccess) {
4979
+ async update(projectAccess) {
4883
4980
  this.client.store.dispatch(updateProjectAccess(projectAccess));
4884
- const promise = this.enqueueRequest({
4981
+ return this.enqueueRequest({
4885
4982
  description: "Edit project access",
4886
4983
  method: HttpMethod.PATCH,
4887
4984
  url: `/access/${projectAccess.offline_id}/`,
@@ -4889,10 +4986,9 @@ class ProjectAccessService extends BaseApiService {
4889
4986
  blockers: [projectAccess.offline_id],
4890
4987
  blocks: [projectAccess.offline_id]
4891
4988
  });
4892
- return [projectAccess, promise];
4893
4989
  }
4894
4990
  // TODO: Re-add user to project if removal fails
4895
- remove(projectAccess) {
4991
+ async remove(projectAccess) {
4896
4992
  const { store } = this.client;
4897
4993
  store.dispatch(removeProjectAccess(projectAccess));
4898
4994
  store.dispatch(removeUser(projectAccess.user));
@@ -4912,7 +5008,7 @@ class ProjectAccessService extends BaseApiService {
4912
5008
  if (!projectId) {
4913
5009
  throw new Error("No active project");
4914
5010
  }
4915
- const [_offlineProjectAccesses, promise] = this.fetchAll(projectId);
5011
+ const promise = this.fetchAll(projectId);
4916
5012
  const result = await promise;
4917
5013
  const activeProjectAccess = result.find((projectAccess) => projectAccess.user === currentUser.id);
4918
5014
  if (!activeProjectAccess) {
@@ -5509,6 +5605,31 @@ class WorkspaceService extends BaseApiService {
5509
5605
  }
5510
5606
  }
5511
5607
  class OrganizationAccessService extends BaseApiService {
5608
+ async update(organizationAccess) {
5609
+ const promise = this.enqueueRequest({
5610
+ description: "Edit organization access",
5611
+ method: HttpMethod.PATCH,
5612
+ url: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,
5613
+ payload: organizationAccess,
5614
+ blockers: [organizationAccess.offline_id],
5615
+ blocks: [organizationAccess.offline_id]
5616
+ });
5617
+ void promise.then(() => {
5618
+ this.client.store.dispatch(updateOrganizationAccess(organizationAccess));
5619
+ });
5620
+ return promise;
5621
+ }
5622
+ async remove(organizationAccess) {
5623
+ this.client.store.dispatch(removeOrganizationAccess(organizationAccess));
5624
+ this.client.store.dispatch(removeUser(organizationAccess.user));
5625
+ return this.enqueueRequest({
5626
+ description: "Remove organization access",
5627
+ method: HttpMethod.DELETE,
5628
+ url: `/organizations/${organizationAccess.organization}/access/${organizationAccess.offline_id}/`,
5629
+ blockers: [organizationAccess.offline_id],
5630
+ blocks: []
5631
+ });
5632
+ }
5512
5633
  async refreshStore() {
5513
5634
  const { store } = this.client;
5514
5635
  const state = store.getState();
@@ -5756,6 +5877,86 @@ class EmailVerificationService extends BaseApiService {
5756
5877
  return this.enqueueRequest(requestDetails);
5757
5878
  }
5758
5879
  }
5880
+ class EmailDomainsService extends BaseApiService {
5881
+ async fetchAll(orgId) {
5882
+ return this.enqueueRequest({
5883
+ description: "Fetch email domains for organization",
5884
+ method: HttpMethod.GET,
5885
+ url: `/organizations/${orgId}/email-domains/`,
5886
+ blockers: [orgId.toString()],
5887
+ blocks: []
5888
+ });
5889
+ }
5890
+ async add(orgId, email) {
5891
+ return this.enqueueRequest({
5892
+ description: "Add email domain to organization",
5893
+ method: HttpMethod.POST,
5894
+ url: `/organizations/${orgId}/email-domains/`,
5895
+ payload: { email },
5896
+ blockers: [orgId.toString(), "create-org"],
5897
+ blocks: []
5898
+ });
5899
+ }
5900
+ async remove(emailDomain) {
5901
+ this.client.store.dispatch(removeEmailDomain(emailDomain));
5902
+ return this.enqueueRequest({
5903
+ description: "Remove email domain from organization",
5904
+ method: HttpMethod.DELETE,
5905
+ url: `/organizations/${emailDomain.organization}/email-domains/${emailDomain.offline_id}/`,
5906
+ blockers: [emailDomain.domain],
5907
+ blocks: []
5908
+ }).catch((e) => {
5909
+ this.client.store.dispatch(addEmailDomain(emailDomain));
5910
+ throw e;
5911
+ });
5912
+ }
5913
+ async refreshStore() {
5914
+ const organizationId = this.client.store.getState().organizationReducer.activeOrganizationId;
5915
+ if (!organizationId) {
5916
+ throw new Error("No active organization");
5917
+ }
5918
+ const promise = this.fetchAll(organizationId);
5919
+ const result = await promise;
5920
+ this.client.store.dispatch(setEmailDomains(result));
5921
+ }
5922
+ }
5923
+ class OrganizationService extends BaseApiService {
5924
+ async create(name) {
5925
+ const result = await this.enqueueRequest({
5926
+ description: "Create organization",
5927
+ method: HttpMethod.POST,
5928
+ url: "/organizations/",
5929
+ payload: { name },
5930
+ blockers: [],
5931
+ blocks: [`add-org-${name}`, "create-org"]
5932
+ });
5933
+ await this.client.main.fetchInitialData(true);
5934
+ return result;
5935
+ }
5936
+ async update(organization) {
5937
+ const promise = this.enqueueRequest({
5938
+ description: "Edit organization",
5939
+ method: HttpMethod.PATCH,
5940
+ url: `/organizations/${organization.id}/`,
5941
+ payload: organization,
5942
+ blockers: [`add-org-${organization.name}`, organization.id.toString()],
5943
+ blocks: [organization.id.toString()]
5944
+ });
5945
+ return promise.then((result) => {
5946
+ this.client.store.dispatch(updateActiveOrganization(organization));
5947
+ return result;
5948
+ });
5949
+ }
5950
+ async invite(organizationId, email) {
5951
+ return this.enqueueRequest({
5952
+ description: "Invite user to organization",
5953
+ method: HttpMethod.POST,
5954
+ url: `/organizations/${organizationId}/invite/${email}/`,
5955
+ blockers: [],
5956
+ blocks: []
5957
+ });
5958
+ }
5959
+ }
5759
5960
  class OvermapSDK {
5760
5961
  constructor(apiUrl, store) {
5761
5962
  __publicField(this, "API_URL");
@@ -5765,6 +5966,7 @@ class OvermapSDK {
5765
5966
  __publicField(this, "auth", new AuthService(this));
5766
5967
  __publicField(this, "categories", new CategoryService(this));
5767
5968
  __publicField(this, "projectAccesses", new ProjectAccessService(this));
5969
+ __publicField(this, "organizations", new OrganizationService(this));
5768
5970
  __publicField(this, "organizationAccess", new OrganizationAccessService(this));
5769
5971
  __publicField(this, "issues", new IssueService(this));
5770
5972
  __publicField(this, "issueComments", new IssueCommentService(this));
@@ -5779,6 +5981,7 @@ class OvermapSDK {
5779
5981
  __publicField(this, "projects", new ProjectService(this));
5780
5982
  __publicField(this, "projectFiles", new ProjectFileService(this));
5781
5983
  __publicField(this, "emailVerification", new EmailVerificationService(this));
5984
+ __publicField(this, "emailDomains", new EmailDomainsService(this));
5782
5985
  this.API_URL = apiUrl;
5783
5986
  this.store = store;
5784
5987
  }
@@ -5821,6 +6024,7 @@ export {
5821
6024
  ComponentTypeService,
5822
6025
  DEFAULT_ISSUE_PRIORITY,
5823
6026
  DEFAULT_ISSUE_STATUS,
6027
+ EmailDomainsService,
5824
6028
  EmailVerificationService,
5825
6029
  FileService,
5826
6030
  GREEN,
@@ -5834,6 +6038,7 @@ export {
5834
6038
  OUTBOX_RETRY_DELAY,
5835
6039
  OrganizationAccessLevel,
5836
6040
  OrganizationAccessService,
6041
+ OrganizationService,
5837
6042
  OutboxCoordinator,
5838
6043
  OvermapContext,
5839
6044
  OvermapProvider,
@@ -5857,6 +6062,7 @@ export {
5857
6062
  addComponent,
5858
6063
  addComponentType,
5859
6064
  addComponentsInBatches,
6065
+ addEmailDomain,
5860
6066
  addFavouriteProjectId,
5861
6067
  addIssue,
5862
6068
  addOrReplaceCategories,
@@ -5876,6 +6082,7 @@ export {
5876
6082
  addUserFormSubmissionAttachment,
5877
6083
  addUserFormSubmissions,
5878
6084
  addUserForms,
6085
+ addUsers,
5879
6086
  addWorkspace,
5880
6087
  areArraysEqual,
5881
6088
  authReducer,
@@ -5915,6 +6122,8 @@ export {
5915
6122
  dequeue,
5916
6123
  discard,
5917
6124
  downloadInMemoryFile,
6125
+ emailDomainsReducer,
6126
+ emailDomainsSlice,
5918
6127
  emailRegex,
5919
6128
  enqueue,
5920
6129
  enqueueRequest,
@@ -5983,6 +6192,7 @@ export {
5983
6192
  removeCategory,
5984
6193
  removeColor,
5985
6194
  removeComponent,
6195
+ removeEmailDomain,
5986
6196
  removeFavouriteProjectId,
5987
6197
  removeIssue,
5988
6198
  removeIssueComment,
@@ -6041,6 +6251,7 @@ export {
6041
6251
  selectCreateProjectType,
6042
6252
  selectCurrentUser,
6043
6253
  selectDeletedRequests,
6254
+ selectEmailDomainsAsMapping,
6044
6255
  selectEnableClustering,
6045
6256
  selectEnableDuplicateIssues,
6046
6257
  selectEnablePlacementMode,
@@ -6075,6 +6286,8 @@ export {
6075
6286
  selectOrganizationAccessForUser,
6076
6287
  selectOrganizationAccessUserMapping,
6077
6288
  selectOrganizationAccesses,
6289
+ selectOrganizationUsersAsMapping,
6290
+ selectOrganizationUsersIds,
6078
6291
  selectOrganizations,
6079
6292
  selectPermittedWorkspaceIds,
6080
6293
  selectPhotoAttachmentsOfIssue,
@@ -6084,6 +6297,8 @@ export {
6084
6297
  selectProjectAccesses,
6085
6298
  selectProjectFileVisibility,
6086
6299
  selectProjectFiles,
6300
+ selectProjectUsersAsMapping,
6301
+ selectProjectUsersIds,
6087
6302
  selectProjects,
6088
6303
  selectRecentIssueIds,
6089
6304
  selectRecentIssuesAsSearchResults,
@@ -6091,7 +6306,9 @@ export {
6091
6306
  selectRehydrated,
6092
6307
  selectRevisionsForForm,
6093
6308
  selectShowTooltips,
6094
- selectSortedUsers,
6309
+ selectSortedEmailDomains,
6310
+ selectSortedOrganizationUsers,
6311
+ selectSortedProjectUsers,
6095
6312
  selectStageMapping,
6096
6313
  selectStages,
6097
6314
  selectStagesFromComponentType,
@@ -6126,6 +6343,7 @@ export {
6126
6343
  setComponents,
6127
6344
  setCreateProjectType,
6128
6345
  setCurrentUser,
6346
+ setEmailDomains,
6129
6347
  setEnableClustering,
6130
6348
  setEnableDuplicateIssues,
6131
6349
  setEnablePlacementMode,
@@ -6166,6 +6384,7 @@ export {
6166
6384
  unfavoriteForm,
6167
6385
  unhideAllCategories,
6168
6386
  unhideCategory,
6387
+ updateActiveOrganization,
6169
6388
  updateAttachment,
6170
6389
  updateComponent,
6171
6390
  updateIssue,