@overmap-ai/core 1.0.39 → 1.0.40-projects-licensing.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.
@@ -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,23 @@ 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
+ return LicenseStatus2;
2326
+ })(LicenseStatus || {});
2327
+ const initialState$c = {
2318
2328
  users: {},
2319
2329
  currentUser: {
2320
2330
  id: 0,
@@ -2325,8 +2335,8 @@ const initialState$b = {
2325
2335
  };
2326
2336
  const userSlice = createSlice({
2327
2337
  name: "users",
2328
- initialState: initialState$b,
2329
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2338
+ initialState: initialState$c,
2339
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$c)),
2330
2340
  reducers: {
2331
2341
  setUsers: (state, action) => {
2332
2342
  const usersMapping = {};
@@ -2388,13 +2398,13 @@ const selectUser = (userId) => (state) => {
2388
2398
  const selectUsersAsMapping = (state) => state.userReducer.users;
2389
2399
  const selectFavouriteProjects = (state) => state.userReducer.currentUser.profile.favourite_project_ids;
2390
2400
  const userReducer = userSlice.reducer;
2391
- const initialState$a = {
2401
+ const initialState$b = {
2392
2402
  organizationAccesses: {}
2393
2403
  };
2394
2404
  const organizationAccessSlice = createSlice({
2395
2405
  name: "organizationAccess",
2396
- initialState: initialState$a,
2397
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2406
+ initialState: initialState$b,
2407
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$b)),
2398
2408
  reducers: {
2399
2409
  setOrganizationAccesses: (state, action) => {
2400
2410
  if (!Array.isArray(action.payload))
@@ -2457,151 +2467,64 @@ const selectOrganizationAccessUserMapping = (state) => {
2457
2467
  return organizationAccesses;
2458
2468
  };
2459
2469
  const organizationAccessReducer = organizationAccessSlice.reducer;
2460
- const initialState$9 = {
2461
- organizations: {},
2462
- activeOrganizationId: null
2470
+ const initialState$a = {
2471
+ licenses: {}
2463
2472
  };
2464
- const organizationSlice = createSlice({
2465
- name: "organizations",
2466
- initialState: initialState$9,
2467
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
2473
+ const licenseSlice = createSlice({
2474
+ name: "license",
2475
+ initialState: initialState$a,
2476
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$a)),
2468
2477
  reducers: {
2469
- setOrganizations: (state, action) => {
2470
- for (const org of action.payload) {
2471
- state.organizations[org.id] = org;
2478
+ setLicenses: (state, action) => {
2479
+ if (!Array.isArray(action.payload))
2480
+ throw new Error("Expected an array of Licenses");
2481
+ if (action.payload.filter(onlyUniqueOfflineIds).length !== action.payload.length) {
2482
+ throw new Error("Tried to use setLicenses reducer with duplicate ID's");
2472
2483
  }
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");
2484
+ const licenses = {};
2485
+ for (const license of action.payload) {
2486
+ licenses[license.offline_id] = license;
2477
2487
  }
2478
- if (state.activeOrganizationId !== action.payload.id) {
2479
- throw new Error("Tried updating active organization with different organization");
2488
+ state.licenses = licenses;
2489
+ },
2490
+ addLicenses: (state, action) => {
2491
+ for (const license of action.payload) {
2492
+ state.licenses[license.offline_id] = license;
2480
2493
  }
2481
- state.organizations[state.activeOrganizationId] = action.payload;
2482
2494
  },
2483
- setActiveOrganizationId: (state, action) => {
2484
- state.activeOrganizationId = action.payload;
2495
+ updateLicense: (state, action) => {
2496
+ if (!(action.payload.offline_id in state.licenses)) {
2497
+ throw new Error("Tried to update license that does not exist.");
2498
+ }
2499
+ state.licenses[action.payload.offline_id] = action.payload;
2485
2500
  }
2486
2501
  }
2487
2502
  });
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)
2503
+ const { setLicenses, addLicenses, updateLicense } = licenseSlice.actions;
2504
+ const selectLicenses = (state) => {
2505
+ return state.licenseReducer.licenses;
2506
+ };
2507
+ const selectLicense = (licenseId) => (state) => state.licenseReducer.licenses[licenseId];
2508
+ const selectActiveLicense = (state) => Object.values(state.licenseReducer.licenses).find(
2509
+ (license) => license.project === state.projectReducer.activeProjectId
2510
+ ) ?? null;
2511
+ const selectLicenseForProject = (projectId) => (state) => Object.values(state.licenseReducer.licenses).find((license) => license.project === projectId) ?? null;
2512
+ const selectActiveStatusLicenses = createSelector(
2513
+ [selectLicenses],
2514
+ (licenses) => Object.values(licenses).filter((license) => license.is_active)
2513
2515
  );
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
- }
2516
+ const selectLicensesForProjectsMapping = createSelector(
2517
+ [selectLicenses],
2518
+ (licenses) => Object.values(licenses).filter((license) => license.project).reduce((accum, license) => ({ ...accum, [license.project]: license }), {})
2538
2519
  );
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 = {
2520
+ const licenseReducer = licenseSlice.reducer;
2521
+ const initialState$9 = {
2599
2522
  projectAccesses: {}
2600
2523
  };
2601
2524
  const projectAccessSlice = createSlice({
2602
2525
  name: "projectAccess",
2603
- initialState: initialState$7,
2604
- extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
2526
+ initialState: initialState$9,
2527
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$9)),
2605
2528
  reducers: {
2606
2529
  setProjectAccesses: (state, action) => {
2607
2530
  if (!Array.isArray(action.payload))
@@ -2669,7 +2592,7 @@ const selectProjectAccessUserMapping = (state) => {
2669
2592
  return projectAccesses;
2670
2593
  };
2671
2594
  const projectAccessReducer = projectAccessSlice.reducer;
2672
- const initialState$6 = {
2595
+ const initialState$8 = {
2673
2596
  projects: {},
2674
2597
  activeProjectId: null,
2675
2598
  recentProjectIds: [],
@@ -2678,7 +2601,7 @@ const initialState$6 = {
2678
2601
  };
2679
2602
  const projectSlice = createSlice({
2680
2603
  name: "projects",
2681
- initialState: initialState$6,
2604
+ initialState: initialState$8,
2682
2605
  reducers: {
2683
2606
  setProjects: (state, action) => {
2684
2607
  const projectsMap = {};
@@ -2724,6 +2647,27 @@ const projectSlice = createSlice({
2724
2647
  } else {
2725
2648
  throw new Error("Accept project invite: user is not in this project");
2726
2649
  }
2650
+ },
2651
+ addActiveProjectIssuesCount: (state, action) => {
2652
+ if (!state.activeProjectId || !(state.activeProjectId in state.projects)) {
2653
+ throw new Error("Update issues count: no active project");
2654
+ }
2655
+ if (!state.projects[state.activeProjectId].issues_count) {
2656
+ state.projects[state.activeProjectId].issues_count = action.payload;
2657
+ } else {
2658
+ state.projects[state.activeProjectId].issues_count += action.payload;
2659
+ }
2660
+ },
2661
+ addActiveProjectFormSubmissionsCount: (state, action) => {
2662
+ if (state.activeProjectId && state.activeProjectId in state.projects) {
2663
+ if (!state.projects[state.activeProjectId].form_submissions_count) {
2664
+ state.projects[state.activeProjectId].form_submissions_count = action.payload;
2665
+ } else {
2666
+ state.projects[state.activeProjectId].form_submissions_count += action.payload;
2667
+ }
2668
+ } else {
2669
+ throw new Error("Update form submissions count: no active project");
2670
+ }
2727
2671
  }
2728
2672
  }
2729
2673
  });
@@ -2734,7 +2678,9 @@ const {
2734
2678
  setActiveProjectId,
2735
2679
  setCreateProjectType,
2736
2680
  deleteProject,
2737
- acceptProjectInvite
2681
+ acceptProjectInvite,
2682
+ addActiveProjectIssuesCount,
2683
+ addActiveProjectFormSubmissionsCount
2738
2684
  } = projectSlice.actions;
2739
2685
  const selectProjects = (state) => state.projectReducer.projects;
2740
2686
  const selectActiveProjectId = (state) => state.projectReducer.activeProjectId;
@@ -2798,6 +2744,171 @@ const selectSortedProjectUsers = createSelector(
2798
2744
  });
2799
2745
  }
2800
2746
  );
2747
+ const initialState$7 = {
2748
+ organizations: {},
2749
+ activeOrganizationId: null
2750
+ };
2751
+ const organizationSlice = createSlice({
2752
+ name: "organizations",
2753
+ initialState: initialState$7,
2754
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$7)),
2755
+ reducers: {
2756
+ setOrganizations: (state, action) => {
2757
+ for (const org of action.payload) {
2758
+ state.organizations[org.id] = org;
2759
+ }
2760
+ },
2761
+ updateActiveOrganization: (state, action) => {
2762
+ if (!state.activeOrganizationId) {
2763
+ throw new Error("Cannot update name of active organization. Active organization ID does not exist");
2764
+ }
2765
+ if (state.activeOrganizationId !== action.payload.id) {
2766
+ throw new Error("Tried updating active organization with different organization");
2767
+ }
2768
+ state.organizations[state.activeOrganizationId] = action.payload;
2769
+ },
2770
+ setActiveOrganizationId: (state, action) => {
2771
+ state.activeOrganizationId = action.payload;
2772
+ }
2773
+ }
2774
+ });
2775
+ const { setOrganizations, setActiveOrganizationId, updateActiveOrganization } = organizationSlice.actions;
2776
+ const selectActiveOrganizationId = (state) => {
2777
+ return state.organizationReducer.activeOrganizationId;
2778
+ };
2779
+ const selectOrganizations = (state) => {
2780
+ return Object.values(state.organizationReducer.organizations);
2781
+ };
2782
+ const selectOrganizationsMapping = (state) => {
2783
+ return state.organizationReducer.organizations;
2784
+ };
2785
+ const selectOrganizationsWithAccess = createSelector(
2786
+ [selectOrganizations],
2787
+ (organizations) => Object.values(organizations).filter((organization) => organization.has_access)
2788
+ );
2789
+ const selectActiveOrganization = (state) => {
2790
+ const id = selectActiveOrganizationId(state);
2791
+ if (!id) {
2792
+ return null;
2793
+ }
2794
+ const organization = state.organizationReducer.organizations[id];
2795
+ if (!organization) {
2796
+ return null;
2797
+ }
2798
+ return organization;
2799
+ };
2800
+ const selectOrganizationUsersIds = createSelector(
2801
+ [selectOrganizationAccesses],
2802
+ (organizationAccesses) => Object.values(organizationAccesses).map((organizationAccess) => organizationAccess.user)
2803
+ );
2804
+ const selectActiveOrganizationProjects = createSelector(
2805
+ [selectProjects, selectActiveOrganizationId],
2806
+ (projects, activeOrganizationId) => activeOrganizationId ? Object.values(projects).filter((project) => project.owner_organization === activeOrganizationId) : []
2807
+ );
2808
+ const selectActiveOrganizationLicenses = createSelector(
2809
+ [selectActiveOrganizationId, selectLicenses],
2810
+ (activeOrganizationId, licenses) => !activeOrganizationId ? [] : Object.values(licenses).filter((license) => license.organization_owner === activeOrganizationId)
2811
+ );
2812
+ const selectSortedOrganizationLicenses = createSelector(
2813
+ [selectActiveOrganizationLicenses, selectProjects],
2814
+ (licences, projects) => licences.sort((licenseA, licenseB) => {
2815
+ if (!licenseA.project) {
2816
+ return 1;
2817
+ }
2818
+ if (!licenseB.project) {
2819
+ return -1;
2820
+ }
2821
+ return projects[licenseA.project].name.toLowerCase().localeCompare(
2822
+ projects[licenseB.project].name.toLowerCase(),
2823
+ void 0,
2824
+ { numeric: true }
2825
+ );
2826
+ })
2827
+ );
2828
+ const selectOrganizationUsersAsMapping = createSelector(
2829
+ [selectOrganizationUsersIds, selectUsersAsMapping],
2830
+ (organizationUserIds, users) => organizationUserIds.reduce((accum, userId) => ({ ...accum, [userId]: users[userId] }), {})
2831
+ );
2832
+ const selectSortedOrganizationUsers = createSelector(
2833
+ [selectCurrentUser, selectOrganizationUsersAsMapping, selectOrganizationAccessUserMapping],
2834
+ (currentUser, userMapping, organizationAccessMapping) => {
2835
+ return Object.values(userMapping).sort((userA, userB) => {
2836
+ if (userA.id === currentUser.id) {
2837
+ return -1;
2838
+ } else if (userB.id === currentUser.id) {
2839
+ return 1;
2840
+ }
2841
+ const organizationAccessesA = organizationAccessMapping[userA.id];
2842
+ const organizationAccessesB = organizationAccessMapping[userB.id];
2843
+ if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === (organizationAccessesB == null ? void 0 : organizationAccessesB.access_level)) {
2844
+ return userA.username.localeCompare(userB.username);
2845
+ }
2846
+ if ((organizationAccessesA == null ? void 0 : organizationAccessesA.access_level) === OrganizationAccessLevel.ADMIN) {
2847
+ return -1;
2848
+ }
2849
+ return 1;
2850
+ });
2851
+ }
2852
+ );
2853
+ const selectOrganization = (id) => (state) => {
2854
+ return state.organizationReducer.organizations[id];
2855
+ };
2856
+ const organizationReducer = organizationSlice.reducer;
2857
+ const createOfflineAction = (request2, baseUrl) => {
2858
+ const requestWithUuid = request2.uuid ? request2 : { ...request2, uuid: v4() };
2859
+ return {
2860
+ payload: requestWithUuid,
2861
+ type: "",
2862
+ meta: {
2863
+ offline: {
2864
+ effect: {
2865
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
2866
+ request: requestWithUuid,
2867
+ BASE_URL: baseUrl
2868
+ }
2869
+ }
2870
+ }
2871
+ };
2872
+ };
2873
+ const initialState$6 = {
2874
+ deletedRequests: [],
2875
+ latestRetryTime: 0
2876
+ };
2877
+ const outboxSlice = createSlice({
2878
+ name: "outbox",
2879
+ initialState: initialState$6,
2880
+ extraReducers: (builder) => builder.addCase("RESET", (state) => Object.assign(state, initialState$6)),
2881
+ reducers: {
2882
+ // enqueueActions is a reducer that does nothing but enqueue API request to the Redux Offline outbox
2883
+ // Whenever an issue is being created, a reducer addIssue() is responsible for adding it to the offline store
2884
+ // Then this reducer enqueueRequest() is responsible for adding the actual request data to the outbox
2885
+ enqueueRequest: {
2886
+ reducer: (state, _action) => {
2887
+ return state;
2888
+ },
2889
+ prepare: (payload) => {
2890
+ console.debug("Preparing to enqueue request", payload);
2891
+ const { BASE_URL, ...rest } = payload;
2892
+ return createOfflineAction(rest, BASE_URL);
2893
+ }
2894
+ },
2895
+ markForDeletion(state, action) {
2896
+ state.deletedRequests.push(action.payload);
2897
+ },
2898
+ markAsDeleted(state, action) {
2899
+ const index2 = state.deletedRequests.indexOf(action.payload);
2900
+ if (index2 !== -1)
2901
+ state.deletedRequests.splice(index2, 1);
2902
+ },
2903
+ _setLatestRetryTime: (state, action) => {
2904
+ state.latestRetryTime = action.payload;
2905
+ }
2906
+ }
2907
+ });
2908
+ const selectDeletedRequests = (state) => state.outboxReducer.deletedRequests;
2909
+ const selectLatestRetryTime = (state) => state.outboxReducer.latestRetryTime;
2910
+ const { enqueueRequest, markForDeletion, markAsDeleted, _setLatestRetryTime } = outboxSlice.actions;
2911
+ const outboxReducer = outboxSlice.reducer;
2801
2912
  const initialState$5 = {
2802
2913
  projectFiles: {},
2803
2914
  activeProjectFileId: null,
@@ -2934,7 +3045,9 @@ const initialState$3 = {
2934
3045
  Components: false,
2935
3046
  Experimental: false
2936
3047
  },
2937
- appearance: "dark"
3048
+ appearance: "dark",
3049
+ isFetchingInitialData: false,
3050
+ isLoading: false
2938
3051
  };
2939
3052
  const settingSlice = createSlice({
2940
3053
  name: "settings",
@@ -2958,6 +3071,12 @@ const settingSlice = createSlice({
2958
3071
  },
2959
3072
  setAppearance: (state, action) => {
2960
3073
  state.appearance = action.payload;
3074
+ },
3075
+ setIsFetchingInitialData: (state, action) => {
3076
+ state.isFetchingInitialData = action.payload;
3077
+ },
3078
+ setIsLoading: (state, action) => {
3079
+ state.isLoading = action.payload;
2961
3080
  }
2962
3081
  }
2963
3082
  });
@@ -2966,7 +3085,9 @@ const {
2966
3085
  setEnablePlacementMode,
2967
3086
  setSectionExpanded,
2968
3087
  setEnableClustering,
2969
- setAppearance
3088
+ setAppearance,
3089
+ setIsFetchingInitialData,
3090
+ setIsLoading
2970
3091
  } = settingSlice.actions;
2971
3092
  const selectEnablePlacementMode = (state) => state.settingReducer.placementMode;
2972
3093
  const selectEnableDuplicateIssues = (state) => state.settingReducer.useIssueTemplate;
@@ -2975,6 +3096,8 @@ const selectExpandedSections = (state) => state.settingReducer.expandedSections;
2975
3096
  const selectEnableClustering = (state) => state.settingReducer.enableClustering;
2976
3097
  const selectAppearance = (state) => state.settingReducer.appearance;
2977
3098
  const settingReducer = settingSlice.reducer;
3099
+ const selectIsFetchingInitialData = (state) => state.settingReducer.isFetchingInitialData;
3100
+ const selectIsLoading = (state) => state.settingReducer.isLoading;
2978
3101
  const LATEST_REVISION_CACHE = {};
2979
3102
  function considerCachingRevision(revision, formId2, preferPending = false) {
2980
3103
  var _a2;
@@ -3392,7 +3515,8 @@ const overmapReducers = {
3392
3515
  userFormReducer,
3393
3516
  userReducer,
3394
3517
  workspaceReducer,
3395
- emailDomainsReducer
3518
+ emailDomainsReducer,
3519
+ licenseReducer
3396
3520
  };
3397
3521
  const overmapReducer = combineReducers(overmapReducers);
3398
3522
  const resetStore = "RESET";
@@ -4879,6 +5003,7 @@ class IssueService extends BaseApiService {
4879
5003
  });
4880
5004
  store.dispatch(addIssue(issuePayload));
4881
5005
  store.dispatch(addToRecentIssues(issuePayload.offline_id));
5006
+ store.dispatch(addActiveProjectIssuesCount(1));
4882
5007
  const promise = this.enqueueRequest({
4883
5008
  description: "Create issue",
4884
5009
  method: HttpMethod.POST,
@@ -4888,6 +5013,7 @@ class IssueService extends BaseApiService {
4888
5013
  },
4889
5014
  payload: issuePayload,
4890
5015
  blockers: [
5016
+ "add-issue",
4891
5017
  ...issuePayload.index_workspace ? [issuePayload.index_workspace] : [],
4892
5018
  ...issuePayload.visible_in_workspaces
4893
5019
  ],
@@ -4905,6 +5031,7 @@ class IssueService extends BaseApiService {
4905
5031
  });
4906
5032
  }
4907
5033
  store.dispatch(removeIssue(issuePayload.offline_id));
5034
+ store.dispatch(addActiveProjectIssuesCount(-1));
4908
5035
  throw error2;
4909
5036
  });
4910
5037
  return [issuePayload, promise];
@@ -4943,16 +5070,18 @@ class IssueService extends BaseApiService {
4943
5070
  return [fullIssue, promise];
4944
5071
  }
4945
5072
  async remove(id) {
4946
- const state = this.client.store.getState();
5073
+ const { store } = this.client;
5074
+ const state = store.getState();
4947
5075
  const backup = state.issueReducer.issues[id];
4948
5076
  if (!backup) {
4949
5077
  throw new Error(`No issue with id ${id} found in the store`);
4950
5078
  }
4951
5079
  const attachments = Object.values(state.issueReducer.attachments).filter((a) => a.issue_id === id);
4952
5080
  const attachmentsOfIssue = selectPhotoAttachmentsOfIssue(id)(state);
4953
- this.client.store.dispatch(removeIssue(id));
5081
+ store.dispatch(removeIssue(id));
5082
+ store.dispatch(addActiveProjectIssuesCount(-1));
4954
5083
  if (attachmentsOfIssue) {
4955
- this.client.store.dispatch(removeAttachmentsOfIssue(id));
5084
+ store.dispatch(removeAttachmentsOfIssue(id));
4956
5085
  }
4957
5086
  try {
4958
5087
  return await this.enqueueRequest({
@@ -4963,8 +5092,9 @@ class IssueService extends BaseApiService {
4963
5092
  blocks: []
4964
5093
  });
4965
5094
  } catch (e) {
4966
- this.client.store.dispatch(addIssue(backup));
4967
- this.client.store.dispatch(addAttachments(attachments));
5095
+ store.dispatch(addIssue(backup));
5096
+ store.dispatch(addAttachments(attachments));
5097
+ store.dispatch(addActiveProjectIssuesCount(1));
4968
5098
  throw e;
4969
5099
  }
4970
5100
  }
@@ -5040,7 +5170,9 @@ class MainService extends BaseApiService {
5040
5170
  owner_organization: projectData.organization_owner,
5041
5171
  owner_user: projectData.user_owner,
5042
5172
  bounds: projectData.bounds,
5043
- invited: projectData.invited || false
5173
+ invited: projectData.invited || false,
5174
+ issues_count: projectData.issues_count,
5175
+ form_submissions_count: projectData.form_submissions_count
5044
5176
  });
5045
5177
  if (currentProjectId === projectData.id && !projectData.invited) {
5046
5178
  isProjectIdValid = true;
@@ -5058,6 +5190,7 @@ class MainService extends BaseApiService {
5058
5190
  }
5059
5191
  store.dispatch(setCurrentUser(data.user));
5060
5192
  store.dispatch(addUsers(data.project_owners));
5193
+ store.dispatch(setLicenses(data.licenses));
5061
5194
  const organizationsData = data.organizations;
5062
5195
  store.dispatch(setOrganizations(organizationsData));
5063
5196
  const validProjects = projects.filter((project) => !project.invited);
@@ -5171,7 +5304,7 @@ class ProjectAccessService extends BaseApiService {
5171
5304
  method: HttpMethod.PATCH,
5172
5305
  url: `/access/${projectAccess.offline_id}/`,
5173
5306
  payload: projectAccess,
5174
- blockers: [projectAccess.offline_id],
5307
+ blockers: [projectAccess.offline_id, "change-access-level"],
5175
5308
  blocks: [projectAccess.offline_id]
5176
5309
  });
5177
5310
  }
@@ -5370,6 +5503,7 @@ class ProjectService extends BaseApiService {
5370
5503
  if (!project) {
5371
5504
  throw new Error("Expected project to exist");
5372
5505
  }
5506
+ const license = selectLicenseForProject(project.id);
5373
5507
  const activeProjectId = state.projectReducer.activeProjectId;
5374
5508
  if (activeProjectId === projectId) {
5375
5509
  store.dispatch({ type: "project/setActiveProjectId", payload: null });
@@ -5380,6 +5514,9 @@ class ProjectService extends BaseApiService {
5380
5514
  store.dispatch(removeProjectAccessesOfProject(project.id));
5381
5515
  store.dispatch({ type: "rehydrated/setRehydrated", payload: false });
5382
5516
  store.dispatch(deleteProject(project));
5517
+ if (license) {
5518
+ store.dispatch(updateLicense({ ...license, project: null }));
5519
+ }
5383
5520
  try {
5384
5521
  await this.enqueueRequest({
5385
5522
  description: "Delete project",
@@ -5395,6 +5532,9 @@ class ProjectService extends BaseApiService {
5395
5532
  store.dispatch(addOrReplaceProjectFiles(filesToDelete));
5396
5533
  store.dispatch(setActiveProjectId(activeProjectId));
5397
5534
  store.dispatch({ type: "rehydrated/setRehydrated", payload: true });
5535
+ if (license) {
5536
+ store.dispatch(updateLicense({ ...license, project: project.id }));
5537
+ }
5398
5538
  throw e;
5399
5539
  }
5400
5540
  }
@@ -5769,7 +5909,7 @@ class UserFormSubmissionService extends BaseApiService {
5769
5909
  method: HttpMethod.POST,
5770
5910
  url: `/forms/revisions/${payload.form_revision}/respond/`,
5771
5911
  payload: { ...payloadWithoutFiles, project: activeProjectId },
5772
- blockers: [payload.issue, payload.component, payload.component_stage].filter(
5912
+ blockers: [payload.issue, payload.component, payload.component_stage, "add-form-entry"].filter(
5773
5913
  (x) => x !== void 0
5774
5914
  ),
5775
5915
  blocks: [payload.offline_id]
@@ -5788,10 +5928,12 @@ class UserFormSubmissionService extends BaseApiService {
5788
5928
  };
5789
5929
  store.dispatch(updateOrCreateUserFormSubmission(offlineResultWithoutFiles));
5790
5930
  void promise.then((result) => {
5931
+ store.dispatch(addActiveProjectFormSubmissionsCount(1));
5791
5932
  store.dispatch(updateOrCreateUserFormSubmission(result));
5792
5933
  return result;
5793
5934
  }).catch(() => {
5794
5935
  store.dispatch(deleteUserFormSubmission(payload.offline_id));
5936
+ store.dispatch(addActiveProjectFormSubmissionsCount(-1));
5795
5937
  });
5796
5938
  const settledPromise = Promise.all([promise, ...attachFilesPromises]).then(() => promise);
5797
5939
  return [fullOfflineResult, settledPromise];
@@ -5825,6 +5967,7 @@ class UserFormSubmissionService extends BaseApiService {
5825
5967
  const state = store.getState();
5826
5968
  const submission = state.userFormReducer.submissions[submissionId];
5827
5969
  store.dispatch(deleteUserFormSubmission(submissionId));
5970
+ store.dispatch(addActiveProjectFormSubmissionsCount(-1));
5828
5971
  try {
5829
5972
  return await this.enqueueRequest({
5830
5973
  description: "Delete user form submissions",
@@ -5835,6 +5978,7 @@ class UserFormSubmissionService extends BaseApiService {
5835
5978
  });
5836
5979
  } catch (e) {
5837
5980
  if (submission) {
5981
+ store.dispatch(addActiveProjectFormSubmissionsCount(1));
5838
5982
  store.dispatch(updateOrCreateUserFormSubmission(submission));
5839
5983
  }
5840
5984
  throw e;
@@ -5871,7 +6015,7 @@ class WorkspaceService extends BaseApiService {
5871
6015
  method: HttpMethod.POST,
5872
6016
  url: `/projects/${store.getState().projectReducer.activeProjectId}/workspaces/`,
5873
6017
  payload: offlineWorkspace,
5874
- blockers: [],
6018
+ blockers: ["add-workspace"],
5875
6019
  blocks: [offlineWorkspace.offline_id]
5876
6020
  });
5877
6021
  void promise.then((result) => {
@@ -6248,10 +6392,12 @@ class OrganizationService extends BaseApiService {
6248
6392
  const organizationAccesses = data.organization_accesses;
6249
6393
  const emailDomains = data.email_domains;
6250
6394
  const users = data.users;
6395
+ const licenses = data.licenses;
6251
6396
  store.dispatch(addUsers(users));
6252
6397
  store.dispatch(setActiveOrganizationId(activeOrganization.id));
6253
6398
  store.dispatch(setOrganizationAccesses(organizationAccesses));
6254
6399
  store.dispatch(setEmailDomains(emailDomains));
6400
+ store.dispatch(addLicenses(licenses));
6255
6401
  if (showLoading) {
6256
6402
  store.dispatch(setIsFetchingInitialData(false));
6257
6403
  }
@@ -6292,6 +6438,103 @@ class OrganizationService extends BaseApiService {
6292
6438
  });
6293
6439
  }
6294
6440
  }
6441
+ class LicenseService extends BaseApiService {
6442
+ async getLicensesForOrganization(organizationId, showLoading = false) {
6443
+ if (showLoading) {
6444
+ this.client.store.dispatch(setIsFetchingInitialData(true));
6445
+ }
6446
+ return this.enqueueRequest({
6447
+ description: "Get licenses",
6448
+ method: HttpMethod.GET,
6449
+ url: `/organizations/${organizationId}/licenses/`,
6450
+ isAuthNeeded: true,
6451
+ blockers: [organizationId.toString()],
6452
+ blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
6453
+ }).then((result) => {
6454
+ if (showLoading) {
6455
+ this.client.store.dispatch(setIsFetchingInitialData(false));
6456
+ }
6457
+ return result;
6458
+ });
6459
+ }
6460
+ async pauseLicense(license) {
6461
+ return this.enqueueRequest({
6462
+ description: "Pause license",
6463
+ method: HttpMethod.DELETE,
6464
+ url: `/billing/${license.offline_id}/suspend/`,
6465
+ isAuthNeeded: true,
6466
+ blockers: [
6467
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6468
+ ],
6469
+ blocks: []
6470
+ }).then((result) => {
6471
+ this.client.store.dispatch(updateLicense(result));
6472
+ return result;
6473
+ });
6474
+ }
6475
+ async resumeLicense(license) {
6476
+ return this.enqueueRequest({
6477
+ description: "Resume license",
6478
+ method: HttpMethod.PATCH,
6479
+ url: `/billing/${license.offline_id}/suspend/`,
6480
+ isAuthNeeded: true,
6481
+ blockers: [
6482
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6483
+ ],
6484
+ blocks: []
6485
+ }).then((result) => {
6486
+ this.client.store.dispatch(updateLicense(result));
6487
+ return result;
6488
+ });
6489
+ }
6490
+ async cancelLicense(license) {
6491
+ return this.enqueueRequest({
6492
+ description: "Cancel license",
6493
+ method: HttpMethod.DELETE,
6494
+ url: `/billing/${license.offline_id}/`,
6495
+ isAuthNeeded: true,
6496
+ blockers: [
6497
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6498
+ ],
6499
+ blocks: []
6500
+ }).then((result) => {
6501
+ this.client.store.dispatch(updateLicense(result));
6502
+ return result;
6503
+ });
6504
+ }
6505
+ async attachLicenseToProject(license, project) {
6506
+ return this.enqueueRequest({
6507
+ description: "Attach license",
6508
+ method: HttpMethod.PATCH,
6509
+ url: `/billing/${license.offline_id}/project/`,
6510
+ isAuthNeeded: true,
6511
+ payload: { project: project.id },
6512
+ blockers: [
6513
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : "",
6514
+ project.id ? project.id.toString() : ""
6515
+ ],
6516
+ blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
6517
+ }).then((result) => {
6518
+ this.client.store.dispatch(updateLicense(result));
6519
+ return result;
6520
+ });
6521
+ }
6522
+ async detachLicenseFromProject(license) {
6523
+ return this.enqueueRequest({
6524
+ description: "Detach license",
6525
+ method: HttpMethod.DELETE,
6526
+ url: `/billing/${license.offline_id}/project/`,
6527
+ isAuthNeeded: true,
6528
+ blockers: [
6529
+ license.organization_owner ? license.organization_owner.toString() : license.user_owner ? license.user_owner.toString() : ""
6530
+ ],
6531
+ blocks: ["add-issue", "add-form-entry", "change-access-level", "add-workspace"]
6532
+ }).then((result) => {
6533
+ this.client.store.dispatch(updateLicense(result));
6534
+ return result;
6535
+ });
6536
+ }
6537
+ }
6295
6538
  class OvermapSDK {
6296
6539
  constructor(apiUrl, store) {
6297
6540
  __publicField(this, "API_URL");
@@ -6317,6 +6560,7 @@ class OvermapSDK {
6317
6560
  __publicField(this, "projectFiles", new ProjectFileService(this));
6318
6561
  __publicField(this, "emailVerification", new EmailVerificationService(this));
6319
6562
  __publicField(this, "emailDomains", new EmailDomainsService(this));
6563
+ __publicField(this, "licenses", new LicenseService(this));
6320
6564
  this.API_URL = apiUrl;
6321
6565
  this.store = store;
6322
6566
  }
@@ -11924,6 +12168,9 @@ export {
11924
12168
  IssuePriority,
11925
12169
  IssueService,
11926
12170
  IssueStatus,
12171
+ LicenseLevel,
12172
+ LicenseService,
12173
+ LicenseStatus,
11927
12174
  MainService,
11928
12175
  MapStyle,
11929
12176
  MultiSelectField,
@@ -11940,6 +12187,7 @@ export {
11940
12187
  OvermapContext,
11941
12188
  OvermapProvider,
11942
12189
  OvermapSDK,
12190
+ PaddleCheckoutEvent,
11943
12191
  PatchField,
11944
12192
  PatchFormProvider,
11945
12193
  ProjectAccessLevel,
@@ -11962,6 +12210,8 @@ export {
11962
12210
  YELLOW,
11963
12211
  _setLatestRetryTime,
11964
12212
  acceptProjectInvite,
12213
+ addActiveProjectFormSubmissionsCount,
12214
+ addActiveProjectIssuesCount,
11965
12215
  addAttachment,
11966
12216
  addAttachments,
11967
12217
  addCategory,
@@ -11971,6 +12221,7 @@ export {
11971
12221
  addEmailDomain,
11972
12222
  addFavouriteProjectId,
11973
12223
  addIssue,
12224
+ addLicenses,
11974
12225
  addOrReplaceCategories,
11975
12226
  addOrReplaceIssueComment,
11976
12227
  addOrReplaceProjectFile,
@@ -12069,6 +12320,8 @@ export {
12069
12320
  issueReducer,
12070
12321
  issueSlice,
12071
12322
  issueToSearchResult,
12323
+ licenseReducer,
12324
+ licenseSlice,
12072
12325
  linkStageToForm,
12073
12326
  literalToCoordinates,
12074
12327
  logOnlyOnce,
@@ -12136,13 +12389,17 @@ export {
12136
12389
  searchIssues,
12137
12390
  selectAccessToken,
12138
12391
  selectActiveIssueId,
12392
+ selectActiveLicense,
12139
12393
  selectActiveOrganization,
12140
12394
  selectActiveOrganizationAccess,
12141
12395
  selectActiveOrganizationId,
12396
+ selectActiveOrganizationLicenses,
12397
+ selectActiveOrganizationProjects,
12142
12398
  selectActiveProject,
12143
12399
  selectActiveProjectAccess,
12144
12400
  selectActiveProjectFileId,
12145
12401
  selectActiveProjectId,
12402
+ selectActiveStatusLicenses,
12146
12403
  selectActiveWorkspace,
12147
12404
  selectActiveWorkspaceId,
12148
12405
  selectAllAttachments,
@@ -12188,6 +12445,7 @@ export {
12188
12445
  selectHiddenComponentTypeIds,
12189
12446
  selectIsFetchingInitialData,
12190
12447
  selectIsImportingProjectFile,
12448
+ selectIsLoading,
12191
12449
  selectIsLoggedIn,
12192
12450
  selectIssue,
12193
12451
  selectIssueAttachmentMapping,
@@ -12198,6 +12456,10 @@ export {
12198
12456
  selectLatestRetryTime,
12199
12457
  selectLatestRevisionByFormId,
12200
12458
  selectLatestRevisionsFromComponentTypeIds,
12459
+ selectLicense,
12460
+ selectLicenseForProject,
12461
+ selectLicenses,
12462
+ selectLicensesForProjectsMapping,
12201
12463
  selectMainWorkspace,
12202
12464
  selectMapStyle,
12203
12465
  selectNumberOfComponentTypesMatchingCaseInsensitiveName,
@@ -12212,6 +12474,7 @@ export {
12212
12474
  selectOrganizationUsersAsMapping,
12213
12475
  selectOrganizationUsersIds,
12214
12476
  selectOrganizations,
12477
+ selectOrganizationsMapping,
12215
12478
  selectOrganizationsWithAccess,
12216
12479
  selectPermittedWorkspaceIds,
12217
12480
  selectPhotoAttachmentsOfIssue,
@@ -12233,6 +12496,7 @@ export {
12233
12496
  selectRevisionsForForm,
12234
12497
  selectShowTooltips,
12235
12498
  selectSortedEmailDomains,
12499
+ selectSortedOrganizationLicenses,
12236
12500
  selectSortedOrganizationUsers,
12237
12501
  selectSortedProjectUsers,
12238
12502
  selectSortedProjects,
@@ -12276,8 +12540,10 @@ export {
12276
12540
  setEnablePlacementMode,
12277
12541
  setIsFetchingInitialData,
12278
12542
  setIsImportingProjectFile,
12543
+ setIsLoading,
12279
12544
  setIssueComments,
12280
12545
  setIssues,
12546
+ setLicenses,
12281
12547
  setLoggedIn,
12282
12548
  setMapStyle,
12283
12549
  setOrganizationAccesses,
@@ -12317,6 +12583,7 @@ export {
12317
12583
  updateAttachment,
12318
12584
  updateComponent,
12319
12585
  updateIssue,
12586
+ updateLicense,
12320
12587
  updateOrCreateProject,
12321
12588
  updateOrCreateUserFormSubmission,
12322
12589
  updateOrganizationAccess,