@overmap-ai/core 1.0.39 → 1.0.40-projects-licensing.1

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.
@@ -626,15 +626,15 @@ const wrapMigration = (migrator) => (state) => {
626
626
  };
627
627
  const migrations = [initialVersioning, signOut, signOut, createOutboxState];
628
628
  const manifest = Object.fromEntries(migrations.map((migration2, i) => [i, wrapMigration(migration2)]));
629
- const initialState$l = {
629
+ const initialState$m = {
630
630
  accessToken: "",
631
631
  refreshToken: "",
632
632
  isLoggedIn: false
633
633
  };
634
634
  const authSlice = createSlice({
635
635
  name: "auth",
636
- initialState: initialState$l,
637
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
636
+ initialState: initialState$m,
637
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$m)),
638
638
  reducers: {
639
639
  setTokens: (state, action) => {
640
640
  state.accessToken = action.payload.accessToken;
@@ -1338,7 +1338,7 @@ const getLocalRelativeDateString = memoize((date, min, max) => {
1338
1338
  return getLocalDateString(date);
1339
1339
  return relative.format(days, "days");
1340
1340
  });
1341
- const initialState$k = {
1341
+ const initialState$l = {
1342
1342
  categories: {},
1343
1343
  usedCategoryColors: [],
1344
1344
  categoryVisibility: {
@@ -1348,8 +1348,8 @@ const initialState$k = {
1348
1348
  };
1349
1349
  const categorySlice = createSlice({
1350
1350
  name: "categories",
1351
- initialState: initialState$k,
1352
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1351
+ initialState: initialState$l,
1352
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$l)),
1353
1353
  reducers: {
1354
1354
  setCategories: (state, action) => {
1355
1355
  if (!Array.isArray(action.payload))
@@ -1482,13 +1482,13 @@ const selectHiddenCategoryCount = (state) => {
1482
1482
  return hiddenCategoryCount;
1483
1483
  };
1484
1484
  const categoryReducer = categorySlice.reducer;
1485
- const initialState$j = {
1485
+ const initialState$k = {
1486
1486
  components: {}
1487
1487
  };
1488
1488
  const componentSlice = createSlice({
1489
1489
  name: "components",
1490
- initialState: initialState$j,
1491
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1490
+ initialState: initialState$k,
1491
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$k)),
1492
1492
  reducers: {
1493
1493
  addComponent: (state, action) => {
1494
1494
  state.components[action.payload.offline_id] = action.payload;
@@ -1600,13 +1600,13 @@ const {
1600
1600
  removeAllComponentsOfType
1601
1601
  } = componentSlice.actions;
1602
1602
  const componentReducer = componentSlice.reducer;
1603
- const initialState$i = {
1603
+ const initialState$j = {
1604
1604
  completionsByComponentId: {}
1605
1605
  };
1606
1606
  const componentStageCompletionSlice = createSlice({
1607
1607
  name: "componentStageCompletions",
1608
- initialState: initialState$i,
1609
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1608
+ initialState: initialState$j,
1609
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$j)),
1610
1610
  reducers: {
1611
1611
  addStageCompletion: (state, action) => {
1612
1612
  let stageToCompletionDateMapping = state.completionsByComponentId[action.payload.component];
@@ -1657,13 +1657,13 @@ const selectCompletedStageIdsForComponent = (component) => (state) => {
1657
1657
  return Object.keys(state.componentStageCompletionReducer.completionsByComponentId[component.offline_id] ?? {});
1658
1658
  };
1659
1659
  const componentStageCompletionReducer = componentStageCompletionSlice.reducer;
1660
- const initialState$h = {
1660
+ const initialState$i = {
1661
1661
  stages: {}
1662
1662
  };
1663
1663
  const componentStageSlice = createSlice({
1664
1664
  name: "componentStages",
1665
- initialState: initialState$h,
1666
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
1665
+ initialState: initialState$i,
1666
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$i)),
1667
1667
  reducers: {
1668
1668
  addStages: (state, action) => {
1669
1669
  Object.assign(state.stages, toOfflineIdRecord(action.payload));
@@ -1754,14 +1754,14 @@ const selectStageFormIdsFromStageIds = restructureCreateSelectorWithArgs(
1754
1754
  );
1755
1755
  const { addStages, updateStages, removeStages, linkStageToForm, unlinkStageToForm } = componentStageSlice.actions;
1756
1756
  const componentStageReducer = componentStageSlice.reducer;
1757
- const initialState$g = {
1757
+ const initialState$h = {
1758
1758
  componentTypes: {},
1759
1759
  hiddenComponentTypeIds: {}
1760
1760
  };
1761
1761
  const componentTypeSlice = createSlice({
1762
1762
  name: "componentTypes",
1763
- initialState: initialState$g,
1764
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$g)),
1763
+ initialState: initialState$h,
1764
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$h)),
1765
1765
  reducers: {
1766
1766
  addComponentType: (state, action) => {
1767
1767
  state.componentTypes[action.payload.offline_id] = action.payload;
@@ -1820,13 +1820,13 @@ const selectComponentTypesByName = restructureCreateSelectorWithArgs(
1820
1820
  const selectHiddenComponentTypeIds = (state) => state.componentTypeReducer.hiddenComponentTypeIds;
1821
1821
  const { addComponentType, setComponentTypes, toggleComponentTypeVisibility, deleteComponentType } = componentTypeSlice.actions;
1822
1822
  const componentTypeReducer = componentTypeSlice.reducer;
1823
- const initialState$f = {
1823
+ const initialState$g = {
1824
1824
  workspaces: {},
1825
1825
  activeWorkspaceId: null
1826
1826
  };
1827
1827
  const workspaceSlice = createSlice({
1828
1828
  name: "workspace",
1829
- initialState: initialState$f,
1829
+ initialState: initialState$g,
1830
1830
  // The `reducers` field lets us define reducers and generate associated actions
1831
1831
  reducers: {
1832
1832
  setWorkspaces: (state, action) => {
@@ -1883,21 +1883,20 @@ const selectPermittedWorkspaceIds = createSelector(
1883
1883
  );
1884
1884
  const workspaceReducer = workspaceSlice.reducer;
1885
1885
  const maxRecentIssues = 10;
1886
- const initialState$e = {
1886
+ const initialState$f = {
1887
1887
  issues: {},
1888
1888
  attachments: {},
1889
1889
  comments: {},
1890
1890
  visibleStatuses: [IssueStatus.BACKLOG, IssueStatus.SELECTED],
1891
- isFetchingInitialData: false,
1892
1891
  visibleUserIds: null,
1893
1892
  recentIssueIds: [],
1894
1893
  activeIssueId: null
1895
1894
  };
1896
1895
  const issueSlice = createSlice({
1897
1896
  name: "issues",
1898
- initialState: initialState$e,
1897
+ initialState: initialState$f,
1899
1898
  extraReducers: (builder) => builder.addCase("RESET", (state) => {
1900
- Object.assign(state, initialState$e);
1899
+ Object.assign(state, initialState$f);
1901
1900
  }),
1902
1901
  reducers: {
1903
1902
  setIssues: (state, action) => {
@@ -1976,9 +1975,6 @@ const issueSlice = createSlice({
1976
1975
  setVisibleStatuses: (state, action) => {
1977
1976
  state.visibleStatuses = action.payload;
1978
1977
  },
1979
- setIsFetchingInitialData: (state, action) => {
1980
- state.isFetchingInitialData = action.payload;
1981
- },
1982
1978
  setVisibleUserIds: (state, action) => {
1983
1979
  state.visibleUserIds = [...new Set(action.payload)];
1984
1980
  },
@@ -2037,7 +2033,6 @@ const {
2037
2033
  resetRecentIssues,
2038
2034
  setActiveIssueId,
2039
2035
  setAttachments,
2040
- setIsFetchingInitialData,
2041
2036
  setIssueComments,
2042
2037
  setIssues,
2043
2038
  setVisibleStatuses,
@@ -2136,7 +2131,6 @@ const selectIssue = restructureCreateSelectorWithArgs(
2136
2131
  return mapping[id];
2137
2132
  })
2138
2133
  );
2139
- const selectIsFetchingInitialData = (state) => state.issueReducer.isFetchingInitialData;
2140
2134
  const selectAllAttachments = createSelector([selectIssueAttachmentMapping], (mapping) => Object.values(mapping));
2141
2135
  const searchIssues = restructureCreateSelectorWithArgs(
2142
2136
  createSelector(
@@ -2228,15 +2222,15 @@ const selectRecentIssuesAsSearchResults = createSelector(
2228
2222
  }
2229
2223
  );
2230
2224
  const issueReducer = issueSlice.reducer;
2231
- const initialState$d = {
2225
+ const initialState$e = {
2232
2226
  s3Urls: {}
2233
2227
  };
2234
2228
  const msPerHour = 1e3 * 60 * 60;
2235
2229
  const msPerWeek = msPerHour * 24 * 7;
2236
2230
  const fileSlice = createSlice({
2237
2231
  name: "file",
2238
- initialState: initialState$d,
2239
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2232
+ initialState: initialState$e,
2233
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$e)),
2240
2234
  reducers: {
2241
2235
  setUploadUrl: (state, action) => {
2242
2236
  const { url, fields, sha1 } = action.payload;
@@ -2263,7 +2257,7 @@ const selectUploadUrl = (sha1) => (state) => {
2263
2257
  return url;
2264
2258
  };
2265
2259
  const fileReducer = fileSlice.reducer;
2266
- const initialState$c = {
2260
+ const initialState$d = {
2267
2261
  // TODO: Change first MapStyle.SATELLITE to MaptStyle.None when project creation map is fixed
2268
2262
  mapStyle: MapStyle.SATELLITE,
2269
2263
  showTooltips: false,
@@ -2271,8 +2265,8 @@ const initialState$c = {
2271
2265
  };
2272
2266
  const mapSlice = createSlice({
2273
2267
  name: "map",
2274
- initialState: initialState$c,
2275
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2268
+ initialState: initialState$d,
2269
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$d)),
2276
2270
  reducers: {
2277
2271
  setMapStyle: (state, action) => {
2278
2272
  state.mapStyle = action.payload;
@@ -2314,7 +2308,24 @@ var VerificationCodeType = /* @__PURE__ */ ((VerificationCodeType2) => {
2314
2308
  VerificationCodeType2[VerificationCodeType2["RESET_PASSWORD"] = 10] = "RESET_PASSWORD";
2315
2309
  return VerificationCodeType2;
2316
2310
  })(VerificationCodeType || {});
2317
- const initialState$b = {
2311
+ var PaddleCheckoutEvent = /* @__PURE__ */ ((PaddleCheckoutEvent2) => {
2312
+ PaddleCheckoutEvent2["COMPLETED"] = "checkout.completed";
2313
+ PaddleCheckoutEvent2["CLOSED"] = "checkout.closed";
2314
+ return PaddleCheckoutEvent2;
2315
+ })(PaddleCheckoutEvent || {});
2316
+ var LicenseLevel = /* @__PURE__ */ ((LicenseLevel2) => {
2317
+ LicenseLevel2[LicenseLevel2["PRO"] = 0] = "PRO";
2318
+ return LicenseLevel2;
2319
+ })(LicenseLevel || {});
2320
+ var LicenseStatus = /* @__PURE__ */ ((LicenseStatus2) => {
2321
+ LicenseStatus2[LicenseStatus2["ACTIVE"] = 0] = "ACTIVE";
2322
+ LicenseStatus2[LicenseStatus2["PAUSED"] = 2] = "PAUSED";
2323
+ LicenseStatus2[LicenseStatus2["CANCELLED"] = 4] = "CANCELLED";
2324
+ LicenseStatus2[LicenseStatus2["INACTIVE"] = 6] = "INACTIVE";
2325
+ LicenseStatus2[LicenseStatus2["PAST_DUE"] = 8] = "PAST_DUE";
2326
+ return LicenseStatus2;
2327
+ })(LicenseStatus || {});
2328
+ const initialState$c = {
2318
2329
  users: {},
2319
2330
  currentUser: {
2320
2331
  id: 0,
@@ -2325,8 +2336,8 @@ const initialState$b = {
2325
2336
  };
2326
2337
  const userSlice = createSlice({
2327
2338
  name: "users",
2328
- initialState: initialState$b,
2329
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2339
+ initialState: initialState$c,
2340
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2330
2341
  reducers: {
2331
2342
  setUsers: (state, action) => {
2332
2343
  const usersMapping = {};
@@ -2388,13 +2399,13 @@ const selectUser = (userId) => (state) => {
2388
2399
  const selectUsersAsMapping = (state) => state.userReducer.users;
2389
2400
  const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
2390
2401
  const userReducer = userSlice.reducer;
2391
- const initialState$a = {
2402
+ const initialState$b = {
2392
2403
  organizationAccesses: {}
2393
2404
  };
2394
2405
  const organizationAccessSlice = createSlice({
2395
2406
  name: "organizationAccess",
2396
- initialState: initialState$a,
2397
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2407
+ initialState: initialState$b,
2408
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2398
2409
  reducers: {
2399
2410
  setOrganizationAccesses: (state, action) => {
2400
2411
  if (!Array.isArray(action.payload))
@@ -2457,151 +2468,64 @@ const selectOrganizationAccessUserMapping = (state) => {
2457
2468
  return organizationAccesses;
2458
2469
  };
2459
2470
  const organizationAccessReducer = organizationAccessSlice.reducer;
2460
- const initialState$9 = {
2461
- organizations: {},
2462
- activeOrganizationId: null
2471
+ const initialState$a = {
2472
+ licenses: {}
2463
2473
  };
2464
- const organizationSlice = createSlice({
2465
- name: "organizations",
2466
- initialState: initialState$9,
2467
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
2474
+ const licenseSlice = createSlice({
2475
+ name: "license",
2476
+ initialState: initialState$a,
2477
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2468
2478
  reducers: {
2469
- setOrganizations: (state, action) => {
2470
- for (const org of action.payload) {
2471
- state.organizations[org.id] = org;
2479
+ setLicenses: (state, action) => {
2480
+ if (!Array.isArray(action.payload))
2481
+ throw new Error("Expected an array of Licenses");
2482
+ if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2483
+ throw new Error("Tried to use setLicenses reducer with duplicate ID's");
2472
2484
  }
2473
- },
2474
- updateActiveOrganization: (state, action) => {
2475
- if (!state.activeOrganizationId) {
2476
- throw new Error("Cannot update name of active organization. Active organization ID does not exist");
2485
+ const licenses = {};
2486
+ for (const license of action.payload) {
2487
+ licenses[license.offline_id] = license;
2477
2488
  }
2478
- if (state.activeOrganizationId !== action.payload.id) {
2479
- throw new Error("Tried updating active organization with different organization");
2489
+ state.licenses = licenses;
2490
+ },
2491
+ addLicenses: (state, action) => {
2492
+ for (const license of action.payload) {
2493
+ state.licenses[license.offline_id] = license;
2480
2494
  }
2481
- state.organizations[state.activeOrganizationId] = action.payload;
2482
2495
  },
2483
- setActiveOrganizationId: (state, action) => {
2484
- state.activeOrganizationId = action.payload;
2496
+ updateLicense: (state, action) => {
2497
+ if (!(action.payload.offline_id in state.licenses)) {
2498
+ throw new Error("Tried to update license that does not exist.");
2499
+ }
2500
+ state.licenses[action.payload.offline_id] = action.payload;
2485
2501
  }
2486
2502
  }
2487
2503
  });
2488
- const { setOrganizations, setActiveOrganizationId, updateActiveOrganization } = organizationSlice.actions;
2489
- const selectActiveOrganizationId = (state) => {
2490
- return state.organizationReducer.activeOrganizationId;
2491
- };
2492
- const selectOrganizations = (state) => {
2493
- return Object.values(state.organizationReducer.organizations);
2494
- };
2495
- const selectOrganizationsWithAccess = createSelector(
2496
- [selectOrganizations],
2497
- (organizations) => Object.values(organizations).filter((organization) => organization.has_access)
2498
- );
2499
- const selectActiveOrganization = (state) => {
2500
- const id = selectActiveOrganizationId(state);
2501
- if (!id) {
2502
- return null;
2503
- }
2504
- const organization = state.organizationReducer.organizations[id];
2505
- if (!organization) {
2506
- return null;
2507
- }
2508
- return organization;
2509
- };
2510
- const selectOrganizationUsersIds = createSelector(
2511
- [selectOrganizationAccesses],
2512
- (organizationAccesses) => Object.values(organizationAccesses).map((organizationAccess) => organizationAccess.user)
2504
+ const { setLicenses, addLicenses, updateLicense } = licenseSlice.actions;
2505
+ const selectLicenses = (state) => {
2506
+ return state.licenseReducer.licenses;
2507
+ };
2508
+ const selectLicense = (licenseId) => (state) => state.licenseReducer.licenses[licenseId];
2509
+ const selectActiveLicense = (state) => Object.values(state.licenseReducer.licenses).find(
2510
+ (license) => license.project === state.projectReducer.activeProjectId
2511
+ ) ?? null;
2512
+ const selectLicenseForProject = (projectId) => (state) => Object.values(state.licenseReducer.licenses).find((license) => license.project === projectId) ?? null;
2513
+ const selectActiveStatusLicenses = createSelector(
2514
+ [selectLicenses],
2515
+ (licenses) => Object.values(licenses).filter((license) => license.is_active)
2513
2516
  );
2514
- const selectOrganizationUsersAsMapping = createSelector(
2515
- [selectOrganizationUsersIds, selectUsersAsMapping],
2516
- (organizationUserIds, users) => organizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {})
2517
- );
2518
- const selectSortedOrganizationUsers = createSelector(
2519
- [selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],
2520
- (currentUser, userMapping, organizationAccessMapping) => {
2521
- return Object.values(userMapping).sort((userA, userB) => {
2522
- if (userA.id === currentUser.id) {
2523
- return -1;
2524
- } else if (userB.id === currentUser.id) {
2525
- return 1;
2526
- }
2527
- const organizationAccessesA = organizationAccessMapping[userA.id];
2528
- const organizationAccessesB = organizationAccessMapping[userB.id];
2529
- if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === (organizationAccessesB == null ? void 0 : organizationAccessesB.access_level)) {
2530
- return userA.username.localeCompare(userB.username);
2531
- }
2532
- if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === OrganizationAccessLevel.ADMIN) {
2533
- return -1;
2534
- }
2535
- return 1;
2536
- });
2537
- }
2517
+ const selectLicensesForProjectsMapping = createSelector(
2518
+ [selectLicenses],
2519
+ (licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
2538
2520
  );
2539
- const selectOrganization = (id) => (state) => {
2540
- return state.organizationReducer.organizations[id];
2541
- };
2542
- const organizationReducer = organizationSlice.reducer;
2543
- const createOfflineAction = (request2, baseUrl) => {
2544
- const requestWithUuid = request2.uuid ? request2 : { ...request2, uuid: v4() };
2545
- return {
2546
- payload: requestWithUuid,
2547
- type: "",
2548
- meta: {
2549
- offline: {
2550
- effect: {
2551
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2552
- request: requestWithUuid,
2553
- BASE_URL: baseUrl
2554
- }
2555
- }
2556
- }
2557
- };
2558
- };
2559
- const initialState$8 = {
2560
- deletedRequests: [],
2561
- latestRetryTime: 0
2562
- };
2563
- const outboxSlice = createSlice({
2564
- name: "outbox",
2565
- initialState: initialState$8,
2566
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$8)),
2567
- reducers: {
2568
- // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
2569
- // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
2570
- // Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox
2571
- enqueueRequest: {
2572
- reducer: (state, _action) => {
2573
- return state;
2574
- },
2575
- prepare: (payload) => {
2576
- console.debug("Preparing to enqueue request", payload);
2577
- const { BASE_URL, ...rest } = payload;
2578
- return createOfflineAction(rest, BASE_URL);
2579
- }
2580
- },
2581
- markForDeletion(state, action) {
2582
- state.deletedRequests.push(action.payload);
2583
- },
2584
- markAsDeleted(state, action) {
2585
- const index2 = state.deletedRequests.indexOf(action.payload);
2586
- if (index2 !== -1)
2587
- state.deletedRequests.splice(index2, 1);
2588
- },
2589
- _setLatestRetryTime: (state, action) => {
2590
- state.latestRetryTime = action.payload;
2591
- }
2592
- }
2593
- });
2594
- const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
2595
- const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
2596
- const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
2597
- const outboxReducer = outboxSlice.reducer;
2598
- const initialState$7 = {
2521
+ const licenseReducer = licenseSlice.reducer;
2522
+ const initialState$9 = {
2599
2523
  projectAccesses: {}
2600
2524
  };
2601
2525
  const projectAccessSlice = createSlice({
2602
2526
  name: "projectAccess",
2603
- initialState: initialState$7,
2604
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
2527
+ initialState: initialState$9,
2528
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
2605
2529
  reducers: {
2606
2530
  setProjectAccesses: (state, action) => {
2607
2531
  if (!Array.isArray(action.payload))
@@ -2669,7 +2593,7 @@ const selectProjectAccessUserMapping = (state) => {
2669
2593
  return projectAccesses;
2670
2594
  };
2671
2595
  const projectAccessReducer = projectAccessSlice.reducer;
2672
- const initialState$6 = {
2596
+ const initialState$8 = {
2673
2597
  projects: {},
2674
2598
  activeProjectId: null,
2675
2599
  recentProjectIds: [],
@@ -2678,7 +2602,7 @@ const initialState$6 = {
2678
2602
  };
2679
2603
  const projectSlice = createSlice({
2680
2604
  name: "projects",
2681
- initialState: initialState$6,
2605
+ initialState: initialState$8,
2682
2606
  reducers: {
2683
2607
  setProjects: (state, action) => {
2684
2608
  const projectsMap = {};
@@ -2724,6 +2648,27 @@ const projectSlice = createSlice({
2724
2648
  } else {
2725
2649
  throw new Error("Accept project invite: user is not in this project");
2726
2650
  }
2651
+ },
2652
+ addActiveProjectIssuesCount: (state, action) => {
2653
+ if (!state.activeProjectId || !(state.activeProjectId in state.projects)) {
2654
+ throw new Error("Update issues count: no active project");
2655
+ }
2656
+ if (!state.projects[state.activeProjectId].issues_count) {
2657
+ state.projects[state.activeProjectId].issues_count = action.payload;
2658
+ } else {
2659
+ state.projects[state.activeProjectId].issues_count += action.payload;
2660
+ }
2661
+ },
2662
+ addActiveProjectFormSubmissionsCount: (state, action) => {
2663
+ if (state.activeProjectId && state.activeProjectId in state.projects) {
2664
+ if (!state.projects[state.activeProjectId].form_submissions_count) {
2665
+ state.projects[state.activeProjectId].form_submissions_count = action.payload;
2666
+ } else {
2667
+ state.projects[state.activeProjectId].form_submissions_count += action.payload;
2668
+ }
2669
+ } else {
2670
+ throw new Error("Update form submissions count: no active project");
2671
+ }
2727
2672
  }
2728
2673
  }
2729
2674
  });
@@ -2734,7 +2679,9 @@ const {
2734
2679
  setActiveProjectId,
2735
2680
  setCreateProjectType,
2736
2681
  deleteProject,
2737
- acceptProjectInvite
2682
+ acceptProjectInvite,
2683
+ addActiveProjectIssuesCount,
2684
+ addActiveProjectFormSubmissionsCount
2738
2685
  } = projectSlice.actions;
2739
2686
  const selectProjects = (state) => state.projectReducer.projects;
2740
2687
  const selectActiveProjectId = (state) => state.projectReducer.activeProjectId;
@@ -2798,6 +2745,171 @@ const selectSortedProjectUsers = createSelector(
2798
2745
  });
2799
2746
  }
2800
2747
  );
2748
+ const initialState$7 = {
2749
+ organizations: {},
2750
+ activeOrganizationId: null
2751
+ };
2752
+ const organizationSlice = createSlice({
2753
+ name: "organizations",
2754
+ initialState: initialState$7,
2755
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
2756
+ reducers: {
2757
+ setOrganizations: (state, action) => {
2758
+ for (const org of action.payload) {
2759
+ state.organizations[org.id] = org;
2760
+ }
2761
+ },
2762
+ updateActiveOrganization: (state, action) => {
2763
+ if (!state.activeOrganizationId) {
2764
+ throw new Error("Cannot update name of active organization. Active organization ID does not exist");
2765
+ }
2766
+ if (state.activeOrganizationId !== action.payload.id) {
2767
+ throw new Error("Tried updating active organization with different organization");
2768
+ }
2769
+ state.organizations[state.activeOrganizationId] = action.payload;
2770
+ },
2771
+ setActiveOrganizationId: (state, action) => {
2772
+ state.activeOrganizationId = action.payload;
2773
+ }
2774
+ }
2775
+ });
2776
+ const { setOrganizations, setActiveOrganizationId, updateActiveOrganization } = organizationSlice.actions;
2777
+ const selectActiveOrganizationId = (state) => {
2778
+ return state.organizationReducer.activeOrganizationId;
2779
+ };
2780
+ const selectOrganizations = (state) => {
2781
+ return Object.values(state.organizationReducer.organizations);
2782
+ };
2783
+ const selectOrganizationsMapping = (state) => {
2784
+ return state.organizationReducer.organizations;
2785
+ };
2786
+ const selectOrganizationsWithAccess = createSelector(
2787
+ [selectOrganizations],
2788
+ (organizations) => Object.values(organizations).filter((organization) => organization.has_access)
2789
+ );
2790
+ const selectActiveOrganization = (state) => {
2791
+ const id = selectActiveOrganizationId(state);
2792
+ if (!id) {
2793
+ return null;
2794
+ }
2795
+ const organization = state.organizationReducer.organizations[id];
2796
+ if (!organization) {
2797
+ return null;
2798
+ }
2799
+ return organization;
2800
+ };
2801
+ const selectOrganizationUsersIds = createSelector(
2802
+ [selectOrganizationAccesses],
2803
+ (organizationAccesses) => Object.values(organizationAccesses).map((organizationAccess) => organizationAccess.user)
2804
+ );
2805
+ const selectActiveOrganizationProjects = createSelector(
2806
+ [selectProjects, selectActiveOrganizationId],
2807
+ (projects, activeOrganizationId) => activeOrganizationId ? Object.values(projects).filter((project) => project.owner_organization === activeOrganizationId) : []
2808
+ );
2809
+ const selectActiveOrganizationLicenses = createSelector(
2810
+ [selectActiveOrganizationId, selectLicenses],
2811
+ (activeOrganizationId, licenses) => !activeOrganizationId ? [] : Object.values(licenses).filter((license) => license.organization_owner === activeOrganizationId)
2812
+ );
2813
+ const selectSortedOrganizationLicenses = createSelector(
2814
+ [selectActiveOrganizationLicenses, selectProjects],
2815
+ (licences, projects) => licences.sort((licenseA, licenseB) => {
2816
+ if (!licenseA.project) {
2817
+ return 1;
2818
+ }
2819
+ if (!licenseB.project) {
2820
+ return -1;
2821
+ }
2822
+ return projects[licenseA.project].name.toLowerCase().localeCompare(
2823
+ projects[licenseB.project].name.toLowerCase(),
2824
+ void 0,
2825
+ { numeric: true }
2826
+ );
2827
+ })
2828
+ );
2829
+ const selectOrganizationUsersAsMapping = createSelector(
2830
+ [selectOrganizationUsersIds, selectUsersAsMapping],
2831
+ (organizationUserIds, users) => organizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {})
2832
+ );
2833
+ const selectSortedOrganizationUsers = createSelector(
2834
+ [selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],
2835
+ (currentUser, userMapping, organizationAccessMapping) => {
2836
+ return Object.values(userMapping).sort((userA, userB) => {
2837
+ if (userA.id === currentUser.id) {
2838
+ return -1;
2839
+ } else if (userB.id === currentUser.id) {
2840
+ return 1;
2841
+ }
2842
+ const organizationAccessesA = organizationAccessMapping[userA.id];
2843
+ const organizationAccessesB = organizationAccessMapping[userB.id];
2844
+ if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === (organizationAccessesB == null ? void 0 : organizationAccessesB.access_level)) {
2845
+ return userA.username.localeCompare(userB.username);
2846
+ }
2847
+ if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === OrganizationAccessLevel.ADMIN) {
2848
+ return -1;
2849
+ }
2850
+ return 1;
2851
+ });
2852
+ }
2853
+ );
2854
+ const selectOrganization = (id) => (state) => {
2855
+ return state.organizationReducer.organizations[id];
2856
+ };
2857
+ const organizationReducer = organizationSlice.reducer;
2858
+ const createOfflineAction = (request2, baseUrl) => {
2859
+ const requestWithUuid = request2.uuid ? request2 : { ...request2, uuid: v4() };
2860
+ return {
2861
+ payload: requestWithUuid,
2862
+ type: "",
2863
+ meta: {
2864
+ offline: {
2865
+ effect: {
2866
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2867
+ request: requestWithUuid,
2868
+ BASE_URL: baseUrl
2869
+ }
2870
+ }
2871
+ }
2872
+ };
2873
+ };
2874
+ const initialState$6 = {
2875
+ deletedRequests: [],
2876
+ latestRetryTime: 0
2877
+ };
2878
+ const outboxSlice = createSlice({
2879
+ name: "outbox",
2880
+ initialState: initialState$6,
2881
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
2882
+ reducers: {
2883
+ // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
2884
+ // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
2885
+ // Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox
2886
+ enqueueRequest: {
2887
+ reducer: (state, _action) => {
2888
+ return state;
2889
+ },
2890
+ prepare: (payload) => {
2891
+ console.debug("Preparing to enqueue request", payload);
2892
+ const { BASE_URL, ...rest } = payload;
2893
+ return createOfflineAction(rest, BASE_URL);
2894
+ }
2895
+ },
2896
+ markForDeletion(state, action) {
2897
+ state.deletedRequests.push(action.payload);
2898
+ },
2899
+ markAsDeleted(state, action) {
2900
+ const index2 = state.deletedRequests.indexOf(action.payload);
2901
+ if (index2 !== -1)
2902
+ state.deletedRequests.splice(index2, 1);
2903
+ },
2904
+ _setLatestRetryTime: (state, action) => {
2905
+ state.latestRetryTime = action.payload;
2906
+ }
2907
+ }
2908
+ });
2909
+ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
2910
+ const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
2911
+ const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
2912
+ const outboxReducer = outboxSlice.reducer;
2801
2913
  const initialState$5 = {
2802
2914
  projectFiles: {},
2803
2915
  activeProjectFileId: null,
@@ -2934,7 +3046,9 @@ const initialState$3 = {
2934
3046
  Components: false,
2935
3047
  Experimental: false
2936
3048
  },
2937
- appearance: "dark"
3049
+ appearance: "dark",
3050
+ isFetchingInitialData: false,
3051
+ isLoading: false
2938
3052
  };
2939
3053
  const settingSlice = createSlice({
2940
3054
  name: "settings",
@@ -2958,6 +3072,12 @@ const settingSlice = createSlice({
2958
3072
  },
2959
3073
  setAppearance: (state, action) => {
2960
3074
  state.appearance = action.payload;
3075
+ },
3076
+ setIsFetchingInitialData: (state, action) => {
3077
+ state.isFetchingInitialData = action.payload;
3078
+ },
3079
+ setIsLoading: (state, action) => {
3080
+ state.isLoading = action.payload;
2961
3081
  }
2962
3082
  }
2963
3083
  });
@@ -2966,7 +3086,9 @@ const {
2966
3086
  setEnablePlacementMode,
2967
3087
  setSectionExpanded,
2968
3088
  setEnableClustering,
2969
- setAppearance
3089
+ setAppearance,
3090
+ setIsFetchingInitialData,
3091
+ setIsLoading
2970
3092
  } = settingSlice.actions;
2971
3093
  const selectEnablePlacementMode = (state) => state.settingReducer.placementMode;
2972
3094
  const selectEnableDuplicateIssues = (state) => state.settingReducer.useIssueTemplate;
@@ -2975,6 +3097,8 @@ const selectExpandedSections = (state) => state.settingReducer.expandedSections;
2975
3097
  const selectEnableClustering = (state) => state.settingReducer.enableClustering;
2976
3098
  const selectAppearance = (state) => state.settingReducer.appearance;
2977
3099
  const settingReducer = settingSlice.reducer;
3100
+ const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
3101
+ const selectIsLoading = (state) => state.settingReducer.isLoading;
2978
3102
  const LATEST_REVISION_CACHE = {};
2979
3103
  function considerCachingRevision(revision, formId2, preferPending = false) {
2980
3104
  var _a2;
@@ -3392,7 +3516,8 @@ const overmapReducers = {
3392
3516
  userFormReducer,
3393
3517
  userReducer,
3394
3518
  workspaceReducer,
3395
- emailDomainsReducer
3519
+ emailDomainsReducer,
3520
+ licenseReducer
3396
3521
  };
3397
3522
  const overmapReducer = combineReducers(overmapReducers);
3398
3523
  const resetStore = "RESET";
@@ -4879,6 +5004,7 @@ class IssueService extends BaseApiService {
4879
5004
  });
4880
5005
  store.dispatch(addIssue(issuePayload));
4881
5006
  store.dispatch(addToRecentIssues(issuePayload.offline_id));
5007
+ store.dispatch(addActiveProjectIssuesCount(1));
4882
5008
  const promise = this.enqueueRequest({
4883
5009
  description: "Create issue",
4884
5010
  method: HttpMethod.POST,
@@ -4888,6 +5014,7 @@ class IssueService extends BaseApiService {
4888
5014
  },
4889
5015
  payload: issuePayload,
4890
5016
  blockers: [
5017
+ "add-issue",
4891
5018
  ...issuePayload.index_workspace ? [issuePayload.index_workspace] : [],
4892
5019
  ...issuePayload.visible_in_workspaces
4893
5020
  ],
@@ -4905,6 +5032,7 @@ class IssueService extends BaseApiService {
4905
5032
  });
4906
5033
  }
4907
5034
  store.dispatch(removeIssue(issuePayload.offline_id));
5035
+ store.dispatch(addActiveProjectIssuesCount(-1));
4908
5036
  throw error2;
4909
5037
  });
4910
5038
  return [issuePayload, promise];
@@ -4943,16 +5071,18 @@ class IssueService extends BaseApiService {
4943
5071
  return [fullIssue, promise];
4944
5072
  }
4945
5073
  async remove(id) {
4946
- const state = this.client.store.getState();
5074
+ const { store } = this.client;
5075
+ const state = store.getState();
4947
5076
  const backup = state.issueReducer.issues[id];
4948
5077
  if (!backup) {
4949
5078
  throw new Error(`No issue with id ${id} found in the store`);
4950
5079
  }
4951
5080
  const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue_id === id);
4952
5081
  const attachmentsOfIssue = selectPhotoAttachmentsOfIssue(id)(state);
4953
- this.client.store.dispatch(removeIssue(id));
5082
+ store.dispatch(removeIssue(id));
5083
+ store.dispatch(addActiveProjectIssuesCount(-1));
4954
5084
  if (attachmentsOfIssue) {
4955
- this.client.store.dispatch(removeAttachmentsOfIssue(id));
5085
+ store.dispatch(removeAttachmentsOfIssue(id));
4956
5086
  }
4957
5087
  try {
4958
5088
  return await this.enqueueRequest({
@@ -4963,8 +5093,9 @@ class IssueService extends BaseApiService {
4963
5093
  blocks: []
4964
5094
  });
4965
5095
  } catch (e) {
4966
- this.client.store.dispatch(addIssue(backup));
4967
- this.client.store.dispatch(addAttachments(attachments));
5096
+ store.dispatch(addIssue(backup));
5097
+ store.dispatch(addAttachments(attachments));
5098
+ store.dispatch(addActiveProjectIssuesCount(1));
4968
5099
  throw e;
4969
5100
  }
4970
5101
  }
@@ -5040,7 +5171,9 @@ class MainService extends BaseApiService {
5040
5171
  owner_organization: projectData.organization_owner,
5041
5172
  owner_user: projectData.user_owner,
5042
5173
  bounds: projectData.bounds,
5043
- invited: projectData.invited || false
5174
+ invited: projectData.invited || false,
5175
+ issues_count: projectData.issues_count,
5176
+ form_submissions_count: projectData.form_submissions_count
5044
5177
  });
5045
5178
  if (currentProjectId === projectData.id && !projectData.invited) {
5046
5179
  isProjectIdValid = true;
@@ -5058,6 +5191,7 @@ class MainService extends BaseApiService {
5058
5191
  }
5059
5192
  store.dispatch(setCurrentUser(data.user));
5060
5193
  store.dispatch(addUsers(data.project_owners));
5194
+ store.dispatch(setLicenses(data.licenses));
5061
5195
  const organizationsData = data.organizations;
5062
5196
  store.dispatch(setOrganizations(organizationsData));
5063
5197
  const validProjects = projects.filter((project) => !project.invited);
@@ -5171,7 +5305,7 @@ class ProjectAccessService extends BaseApiService {
5171
5305
  method: HttpMethod.PATCH,
5172
5306
  url: `/access/${projectAccess.offline_id}/`,
5173
5307
  payload: projectAccess,
5174
- blockers: [projectAccess.offline_id],
5308
+ blockers: [projectAccess.offline_id, "change-access-level"],
5175
5309
  blocks: [projectAccess.offline_id]
5176
5310
  });
5177
5311
  }
@@ -5370,6 +5504,7 @@ class ProjectService extends BaseApiService {
5370
5504
  if (!project) {
5371
5505
  throw new Error("Expected project to exist");
5372
5506
  }
5507
+ const license = selectLicenseForProject(project.id);
5373
5508
  const activeProjectId = state.projectReducer.activeProjectId;
5374
5509
  if (activeProjectId === projectId) {
5375
5510
  store.dispatch({ type: "project/setActiveProjectId", payload: null });
@@ -5380,6 +5515,9 @@ class ProjectService extends BaseApiService {
5380
5515
  store.dispatch(removeProjectAccessesOfProject(project.id));
5381
5516
  store.dispatch({ type: "rehydrated/setRehydrated", payload: false });
5382
5517
  store.dispatch(deleteProject(project));
5518
+ if (license) {
5519
+ store.dispatch(updateLicense({ ...license, project: null }));
5520
+ }
5383
5521
  try {
5384
5522
  await this.enqueueRequest({
5385
5523
  description: "Delete project",
@@ -5395,6 +5533,9 @@ class ProjectService extends BaseApiService {
5395
5533
  store.dispatch(addOrReplaceProjectFiles(filesToDelete));
5396
5534
  store.dispatch(setActiveProjectId(activeProjectId));
5397
5535
  store.dispatch({ type: "rehydrated/setRehydrated", payload: true });
5536
+ if (license) {
5537
+ store.dispatch(updateLicense({ ...license, project: project.id }));
5538
+ }
5398
5539
  throw e;
5399
5540
  }
5400
5541
  }
@@ -5769,7 +5910,7 @@ class UserFormSubmissionService extends BaseApiService {
5769
5910
  method: HttpMethod.POST,
5770
5911
  url: `/forms/revisions/${payload.form_revision}/respond/`,
5771
5912
  payload: { ...payloadWithoutFiles, project: activeProjectId },
5772
- blockers: [payload.issue, payload.component, payload.component_stage].filter(
5913
+ blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
5773
5914
  (x) => x !== void 0
5774
5915
  ),
5775
5916
  blocks: [payload.offline_id]
@@ -5788,10 +5929,12 @@ class UserFormSubmissionService extends BaseApiService {
5788
5929
  };
5789
5930
  store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
5790
5931
  void promise.then((result) => {
5932
+ store.dispatch(addActiveProjectFormSubmissionsCount(1));
5791
5933
  store.dispatch(updateOrCreateUserFormSubmission(result));
5792
5934
  return result;
5793
5935
  }).catch(() => {
5794
5936
  store.dispatch(deleteUserFormSubmission(payload.offline_id));
5937
+ store.dispatch(addActiveProjectFormSubmissionsCount(-1));
5795
5938
  });
5796
5939
  const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
5797
5940
  return [fullOfflineResult, settledPromise];
@@ -5825,6 +5968,7 @@ class UserFormSubmissionService extends BaseApiService {
5825
5968
  const state = store.getState();
5826
5969
  const submission = state.userFormReducer.submissions[submissionId];
5827
5970
  store.dispatch(deleteUserFormSubmission(submissionId));
5971
+ store.dispatch(addActiveProjectFormSubmissionsCount(-1));
5828
5972
  try {
5829
5973
  return await this.enqueueRequest({
5830
5974
  description: "Delete user form submissions",
@@ -5835,6 +5979,7 @@ class UserFormSubmissionService extends BaseApiService {
5835
5979
  });
5836
5980
  } catch (e) {
5837
5981
  if (submission) {
5982
+ store.dispatch(addActiveProjectFormSubmissionsCount(1));
5838
5983
  store.dispatch(updateOrCreateUserFormSubmission(submission));
5839
5984
  }
5840
5985
  throw e;
@@ -5871,7 +6016,7 @@ class WorkspaceService extends BaseApiService {
5871
6016
  method: HttpMethod.POST,
5872
6017
  url: `/projects/${store.getState().projectReducer.activeProjectId}/workspaces/`,
5873
6018
  payload: offlineWorkspace,
5874
- blockers: [],
6019
+ blockers: ["add-workspace"],
5875
6020
  blocks: [offlineWorkspace.offline_id]
5876
6021
  });
5877
6022
  void promise.then((result) => {
@@ -6248,10 +6393,12 @@ class OrganizationService extends BaseApiService {
6248
6393
  const organizationAccesses = data.organization_accesses;
6249
6394
  const emailDomains = data.email_domains;
6250
6395
  const users = data.users;
6396
+ const licenses = data.licenses;
6251
6397
  store.dispatch(addUsers(users));
6252
6398
  store.dispatch(setActiveOrganizationId(activeOrganization.id));
6253
6399
  store.dispatch(setOrganizationAccesses(organizationAccesses));
6254
6400
  store.dispatch(setEmailDomains(emailDomains));
6401
+ store.dispatch(addLicenses(licenses));
6255
6402
  if (showLoading) {
6256
6403
  store.dispatch(setIsFetchingInitialData(false));
6257
6404
  }
@@ -6292,6 +6439,113 @@ class OrganizationService extends BaseApiService {
6292
6439
  });
6293
6440
  }
6294
6441
  }
6442
+ class LicenseService extends BaseApiService {
6443
+ async getLicensesForOrganization(organizationId, showLoading = false) {
6444
+ if (showLoading) {
6445
+ this.client.store.dispatch(setIsFetchingInitialData(true));
6446
+ }
6447
+ return this.enqueueRequest({
6448
+ description: "Get licenses",
6449
+ method: HttpMethod.GET,
6450
+ url: `/organizations/${organizationId}/licenses/`,
6451
+ isAuthNeeded: true,
6452
+ blockers: [organizationId.toString()],
6453
+ blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
6454
+ }).then((result) => {
6455
+ if (showLoading) {
6456
+ this.client.store.dispatch(setIsFetchingInitialData(false));
6457
+ }
6458
+ return result;
6459
+ });
6460
+ }
6461
+ async pauseLicense(license) {
6462
+ return this.enqueueRequest({
6463
+ description: "Pause license",
6464
+ method: HttpMethod.DELETE,
6465
+ url: `/billing/${license.offline_id}/suspend/`,
6466
+ isAuthNeeded: true,
6467
+ blockers: [
6468
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6469
+ ],
6470
+ blocks: []
6471
+ }).then((result) => {
6472
+ this.client.store.dispatch(updateLicense(result));
6473
+ return result;
6474
+ });
6475
+ }
6476
+ async resumeLicense(license) {
6477
+ return this.enqueueRequest({
6478
+ description: "Resume license",
6479
+ method: HttpMethod.PATCH,
6480
+ url: `/billing/${license.offline_id}/suspend/`,
6481
+ isAuthNeeded: true,
6482
+ blockers: [
6483
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6484
+ ],
6485
+ blocks: []
6486
+ }).then((result) => {
6487
+ this.client.store.dispatch(updateLicense(result));
6488
+ return result;
6489
+ });
6490
+ }
6491
+ async cancelLicense(license) {
6492
+ return this.enqueueRequest({
6493
+ description: "Cancel license",
6494
+ method: HttpMethod.DELETE,
6495
+ url: `/billing/${license.offline_id}/`,
6496
+ isAuthNeeded: true,
6497
+ blockers: [
6498
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6499
+ ],
6500
+ blocks: []
6501
+ }).then((result) => {
6502
+ this.client.store.dispatch(updateLicense(result));
6503
+ return result;
6504
+ });
6505
+ }
6506
+ async attachLicenseToProject(license, project) {
6507
+ return this.enqueueRequest({
6508
+ description: "Attach license",
6509
+ method: HttpMethod.PATCH,
6510
+ url: `/billing/${license.offline_id}/project/`,
6511
+ isAuthNeeded: true,
6512
+ payload: { project: project.id },
6513
+ blockers: [
6514
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : "",
6515
+ project.id ? project.id.toString() : ""
6516
+ ],
6517
+ blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
6518
+ }).then((result) => {
6519
+ this.client.store.dispatch(updateLicense(result));
6520
+ return result;
6521
+ });
6522
+ }
6523
+ async detachLicenseFromProject(license) {
6524
+ return this.enqueueRequest({
6525
+ description: "Detach license",
6526
+ method: HttpMethod.DELETE,
6527
+ url: `/billing/${license.offline_id}/project/`,
6528
+ isAuthNeeded: true,
6529
+ blockers: [
6530
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6531
+ ],
6532
+ blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
6533
+ }).then((result) => {
6534
+ this.client.store.dispatch(updateLicense(result));
6535
+ return result;
6536
+ });
6537
+ }
6538
+ async getLatestTransaction(license) {
6539
+ return this.enqueueRequest({
6540
+ description: "Get latest transaction",
6541
+ method: HttpMethod.GET,
6542
+ url: `/billing/${license.offline_id}/transaction/`,
6543
+ isAuthNeeded: true,
6544
+ blockers: [license.offline_id],
6545
+ blocks: [license.offline_id]
6546
+ });
6547
+ }
6548
+ }
6295
6549
  class OvermapSDK {
6296
6550
  constructor(apiUrl, store) {
6297
6551
  __publicField(this, "API_URL");
@@ -6317,6 +6571,7 @@ class OvermapSDK {
6317
6571
  __publicField(this, "projectFiles", new ProjectFileService(this));
6318
6572
  __publicField(this, "emailVerification", new EmailVerificationService(this));
6319
6573
  __publicField(this, "emailDomains", new EmailDomainsService(this));
6574
+ __publicField(this, "licenses", new LicenseService(this));
6320
6575
  this.API_URL = apiUrl;
6321
6576
  this.store = store;
6322
6577
  }
@@ -11924,6 +12179,9 @@ export {
11924
12179
  IssuePriority,
11925
12180
  IssueService,
11926
12181
  IssueStatus,
12182
+ LicenseLevel,
12183
+ LicenseService,
12184
+ LicenseStatus,
11927
12185
  MainService,
11928
12186
  MapStyle,
11929
12187
  MultiSelectField,
@@ -11940,6 +12198,7 @@ export {
11940
12198
  OvermapContext,
11941
12199
  OvermapProvider,
11942
12200
  OvermapSDK,
12201
+ PaddleCheckoutEvent,
11943
12202
  PatchField,
11944
12203
  PatchFormProvider,
11945
12204
  ProjectAccessLevel,
@@ -11962,6 +12221,8 @@ export {
11962
12221
  YELLOW,
11963
12222
  _setLatestRetryTime,
11964
12223
  acceptProjectInvite,
12224
+ addActiveProjectFormSubmissionsCount,
12225
+ addActiveProjectIssuesCount,
11965
12226
  addAttachment,
11966
12227
  addAttachments,
11967
12228
  addCategory,
@@ -11971,6 +12232,7 @@ export {
11971
12232
  addEmailDomain,
11972
12233
  addFavouriteProjectId,
11973
12234
  addIssue,
12235
+ addLicenses,
11974
12236
  addOrReplaceCategories,
11975
12237
  addOrReplaceIssueComment,
11976
12238
  addOrReplaceProjectFile,
@@ -12069,6 +12331,8 @@ export {
12069
12331
  issueReducer,
12070
12332
  issueSlice,
12071
12333
  issueToSearchResult,
12334
+ licenseReducer,
12335
+ licenseSlice,
12072
12336
  linkStageToForm,
12073
12337
  literalToCoordinates,
12074
12338
  logOnlyOnce,
@@ -12136,13 +12400,17 @@ export {
12136
12400
  searchIssues,
12137
12401
  selectAccessToken,
12138
12402
  selectActiveIssueId,
12403
+ selectActiveLicense,
12139
12404
  selectActiveOrganization,
12140
12405
  selectActiveOrganizationAccess,
12141
12406
  selectActiveOrganizationId,
12407
+ selectActiveOrganizationLicenses,
12408
+ selectActiveOrganizationProjects,
12142
12409
  selectActiveProject,
12143
12410
  selectActiveProjectAccess,
12144
12411
  selectActiveProjectFileId,
12145
12412
  selectActiveProjectId,
12413
+ selectActiveStatusLicenses,
12146
12414
  selectActiveWorkspace,
12147
12415
  selectActiveWorkspaceId,
12148
12416
  selectAllAttachments,
@@ -12188,6 +12456,7 @@ export {
12188
12456
  selectHiddenComponentTypeIds,
12189
12457
  selectIsFetchingInitialData,
12190
12458
  selectIsImportingProjectFile,
12459
+ selectIsLoading,
12191
12460
  selectIsLoggedIn,
12192
12461
  selectIssue,
12193
12462
  selectIssueAttachmentMapping,
@@ -12198,6 +12467,10 @@ export {
12198
12467
  selectLatestRetryTime,
12199
12468
  selectLatestRevisionByFormId,
12200
12469
  selectLatestRevisionsFromComponentTypeIds,
12470
+ selectLicense,
12471
+ selectLicenseForProject,
12472
+ selectLicenses,
12473
+ selectLicensesForProjectsMapping,
12201
12474
  selectMainWorkspace,
12202
12475
  selectMapStyle,
12203
12476
  selectNumberOfComponentTypesMatchingCaseInsensitiveName,
@@ -12212,6 +12485,7 @@ export {
12212
12485
  selectOrganizationUsersAsMapping,
12213
12486
  selectOrganizationUsersIds,
12214
12487
  selectOrganizations,
12488
+ selectOrganizationsMapping,
12215
12489
  selectOrganizationsWithAccess,
12216
12490
  selectPermittedWorkspaceIds,
12217
12491
  selectPhotoAttachmentsOfIssue,
@@ -12233,6 +12507,7 @@ export {
12233
12507
  selectRevisionsForForm,
12234
12508
  selectShowTooltips,
12235
12509
  selectSortedEmailDomains,
12510
+ selectSortedOrganizationLicenses,
12236
12511
  selectSortedOrganizationUsers,
12237
12512
  selectSortedProjectUsers,
12238
12513
  selectSortedProjects,
@@ -12276,8 +12551,10 @@ export {
12276
12551
  setEnablePlacementMode,
12277
12552
  setIsFetchingInitialData,
12278
12553
  setIsImportingProjectFile,
12554
+ setIsLoading,
12279
12555
  setIssueComments,
12280
12556
  setIssues,
12557
+ setLicenses,
12281
12558
  setLoggedIn,
12282
12559
  setMapStyle,
12283
12560
  setOrganizationAccesses,
@@ -12317,6 +12594,7 @@ export {
12317
12594
  updateAttachment,
12318
12595
  updateComponent,
12319
12596
  updateIssue,
12597
+ updateLicense,
12320
12598
  updateOrCreateProject,
12321
12599
  updateOrCreateUserFormSubmission,
12322
12600
  updateOrganizationAccess,