@northern.tech/store 0.30.0 → 0.30.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.
Files changed (446) hide show
  1. package/dist/actions.cjs +21 -1130
  2. package/dist/actions.cjs.map +1 -1
  3. package/dist/actions.d.cts +212 -221
  4. package/dist/actions.d.ts +212 -220
  5. package/dist/actions.js +21 -18
  6. package/dist/actions.js.map +1 -1
  7. package/dist/api/general-api.cjs +61 -459
  8. package/dist/api/general-api.cjs.map +1 -1
  9. package/dist/api/general-api.d.cts +15 -17
  10. package/dist/api/general-api.d.ts +15 -17
  11. package/dist/api/general-api.js +56 -15
  12. package/dist/api/general-api.js.map +1 -1
  13. package/dist/api/users-api.cjs +32 -469
  14. package/dist/api/users-api.cjs.map +1 -1
  15. package/dist/api/users-api.d.cts +19 -14
  16. package/dist/api/users-api.d.ts +19 -13
  17. package/dist/api/users-api.js +30 -12
  18. package/dist/api/users-api.js.map +1 -1
  19. package/dist/appSlice/constants.cjs +190 -144
  20. package/dist/appSlice/constants.cjs.map +1 -1
  21. package/dist/appSlice/constants.d.cts +2 -159
  22. package/dist/appSlice/constants.d.ts +2 -159
  23. package/dist/appSlice/constants.js +181 -29
  24. package/dist/appSlice/constants.js.map +1 -1
  25. package/dist/appSlice/index.cjs +147 -178
  26. package/dist/appSlice/index.cjs.map +1 -1
  27. package/dist/appSlice/index.d.cts +2 -148
  28. package/dist/appSlice/index.d.ts +2 -148
  29. package/dist/appSlice/index.js +142 -18
  30. package/dist/appSlice/index.js.map +1 -1
  31. package/dist/appSlice/mocks.cjs +17 -191
  32. package/dist/appSlice/mocks.cjs.map +1 -1
  33. package/dist/appSlice/mocks.d.cts +33 -36
  34. package/dist/appSlice/mocks.d.ts +33 -36
  35. package/dist/appSlice/mocks.js +17 -25
  36. package/dist/appSlice/mocks.js.map +1 -1
  37. package/dist/appSlice/selectors.cjs +49 -91
  38. package/dist/appSlice/selectors.cjs.map +1 -1
  39. package/dist/appSlice/selectors.d.cts +216 -230
  40. package/dist/appSlice/selectors.d.ts +216 -230
  41. package/dist/appSlice/selectors.js +29 -44
  42. package/dist/appSlice/selectors.js.map +1 -1
  43. package/dist/appSlice/thunks.cjs +6 -4636
  44. package/dist/appSlice/thunks.d.cts +59 -62
  45. package/dist/appSlice/thunks.d.ts +59 -62
  46. package/dist/appSlice/thunks.js +2 -45
  47. package/dist/auth.cjs +68 -433
  48. package/dist/auth.cjs.map +1 -1
  49. package/dist/auth.d.cts +14 -14
  50. package/dist/auth.d.ts +14 -14
  51. package/dist/auth.js +65 -18
  52. package/dist/auth.js.map +1 -1
  53. package/dist/chunk-CKQMccvm.cjs +28 -0
  54. package/dist/commonConstants.cjs +14 -393
  55. package/dist/commonConstants.d.cts +2 -83
  56. package/dist/commonConstants.d.ts +2 -83
  57. package/dist/commonConstants.js +2 -33
  58. package/dist/commonSelectors.cjs +284 -1269
  59. package/dist/commonSelectors.cjs.map +1 -1
  60. package/dist/commonSelectors.d.cts +1623 -1416
  61. package/dist/commonSelectors.d.ts +1623 -1416
  62. package/dist/commonSelectors.js +277 -51
  63. package/dist/commonSelectors.js.map +1 -1
  64. package/dist/constants-5cdwz1iH.d.ts +160 -0
  65. package/dist/constants-BWEsNG5c.d.ts +28 -0
  66. package/dist/constants-BciiayPt.d.ts +17 -0
  67. package/dist/constants-C5AU0mCY.d.ts +157 -0
  68. package/dist/constants-CIx3fnBv.d.cts +17 -0
  69. package/dist/constants-CNhpIMME.d.cts +93 -0
  70. package/dist/constants-Cpgyuy_r.d.ts +57 -0
  71. package/dist/constants-D41U_jbR.d.cts +160 -0
  72. package/dist/constants-DK7fI3Rh.d.cts +28 -0
  73. package/dist/constants-DPLHhjVN.d.cts +157 -0
  74. package/dist/constants-DrwXHsJ1.d.ts +120 -0
  75. package/dist/constants-G3wymKIl.d.cts +57 -0
  76. package/dist/constants-MPLfugsi.d.cts +120 -0
  77. package/dist/constants-y2XVLQWf.d.ts +93 -0
  78. package/dist/constants.cjs +784 -972
  79. package/dist/constants.cjs.map +1 -1
  80. package/dist/constants.d.cts +8 -14
  81. package/dist/constants.d.ts +8 -14
  82. package/dist/constants.js +674 -232
  83. package/dist/constants.js.map +1 -1
  84. package/dist/deploymentsSlice/constants.cjs +15 -214
  85. package/dist/deploymentsSlice/constants.d.cts +2 -163
  86. package/dist/deploymentsSlice/constants.d.ts +2 -163
  87. package/dist/deploymentsSlice/constants.js +2 -35
  88. package/dist/deploymentsSlice/index.cjs +168 -302
  89. package/dist/deploymentsSlice/index.cjs.map +1 -1
  90. package/dist/deploymentsSlice/index.d.cts +2 -157
  91. package/dist/deploymentsSlice/index.d.ts +2 -157
  92. package/dist/deploymentsSlice/index.js +161 -18
  93. package/dist/deploymentsSlice/index.js.map +1 -1
  94. package/dist/deploymentsSlice/mocks.cjs +178 -433
  95. package/dist/deploymentsSlice/mocks.cjs.map +1 -1
  96. package/dist/deploymentsSlice/mocks.d.cts +176 -178
  97. package/dist/deploymentsSlice/mocks.d.ts +176 -178
  98. package/dist/deploymentsSlice/mocks.js +178 -144
  99. package/dist/deploymentsSlice/mocks.js.map +1 -1
  100. package/dist/deploymentsSlice/selectors.cjs +44 -223
  101. package/dist/deploymentsSlice/selectors.cjs.map +1 -1
  102. package/dist/deploymentsSlice/selectors.d.cts +73 -87
  103. package/dist/deploymentsSlice/selectors.d.ts +73 -87
  104. package/dist/deploymentsSlice/selectors.js +37 -25
  105. package/dist/deploymentsSlice/selectors.js.map +1 -1
  106. package/dist/deploymentsSlice/thunks.cjs +16 -4654
  107. package/dist/deploymentsSlice/thunks.d.cts +222 -235
  108. package/dist/deploymentsSlice/thunks.d.ts +222 -235
  109. package/dist/deploymentsSlice/thunks.js +2 -65
  110. package/dist/devicesSlice/constants.cjs +9 -68
  111. package/dist/devicesSlice/constants.d.cts +2 -37
  112. package/dist/devicesSlice/constants.d.ts +2 -37
  113. package/dist/devicesSlice/constants.js +2 -23
  114. package/dist/devicesSlice/index.cjs +215 -225
  115. package/dist/devicesSlice/index.cjs.map +1 -1
  116. package/dist/devicesSlice/index.d.cts +2 -202
  117. package/dist/devicesSlice/index.d.ts +2 -202
  118. package/dist/devicesSlice/index.js +209 -18
  119. package/dist/devicesSlice/index.js.map +1 -1
  120. package/dist/devicesSlice/mocks.cjs +146 -339
  121. package/dist/devicesSlice/mocks.cjs.map +1 -1
  122. package/dist/devicesSlice/mocks.d.cts +150 -148
  123. package/dist/devicesSlice/mocks.d.ts +150 -148
  124. package/dist/devicesSlice/mocks.js +145 -132
  125. package/dist/devicesSlice/mocks.js.map +1 -1
  126. package/dist/devicesSlice/selectors.cjs +145 -539
  127. package/dist/devicesSlice/selectors.cjs.map +1 -1
  128. package/dist/devicesSlice/selectors.d.cts +685 -699
  129. package/dist/devicesSlice/selectors.d.ts +685 -699
  130. package/dist/devicesSlice/selectors.js +123 -59
  131. package/dist/devicesSlice/selectors.js.map +1 -1
  132. package/dist/devicesSlice/thunks.cjs +48 -4718
  133. package/dist/devicesSlice/thunks.d.cts +800 -752
  134. package/dist/devicesSlice/thunks.d.ts +800 -752
  135. package/dist/devicesSlice/thunks.js +2 -129
  136. package/dist/index-4eaLEXy_.d.cts +152 -0
  137. package/dist/index-BEVkIiNa.d.cts +95 -0
  138. package/dist/index-BP0uAq36.d.cts +159 -0
  139. package/dist/index-Bwx9jEiL.d.cts +71 -0
  140. package/dist/index-CJkrL0oA.d.ts +64 -0
  141. package/dist/index-CO-py5d4.d.ts +95 -0
  142. package/dist/index-CTt-eIY8.d.cts +154 -0
  143. package/dist/index-CkwVnIqd.d.ts +159 -0
  144. package/dist/index-Cvkvcz4r.d.ts +115 -0
  145. package/dist/index-DJSlDPRX.d.ts +71 -0
  146. package/dist/index-DqyY6oZ3.d.ts +205 -0
  147. package/dist/index-DtePEQPT.d.ts +152 -0
  148. package/dist/index-Dv3Hfxk_.d.ts +154 -0
  149. package/dist/index-FyYBBeN-.d.cts +115 -0
  150. package/dist/index-Lz5JsJ6O.d.cts +205 -0
  151. package/dist/index-UPc3wvVd.d.cts +64 -0
  152. package/dist/liststatehook.cjs +83 -948
  153. package/dist/liststatehook.cjs.map +1 -1
  154. package/dist/liststatehook.d.cts +29 -239
  155. package/dist/liststatehook.d.ts +29 -239
  156. package/dist/liststatehook.js +77 -85
  157. package/dist/liststatehook.js.map +1 -1
  158. package/dist/locationutils.cjs +459 -916
  159. package/dist/locationutils.cjs.map +1 -1
  160. package/dist/locationutils.d.cts +244 -110
  161. package/dist/locationutils.d.ts +244 -110
  162. package/dist/locationutils.js +440 -44
  163. package/dist/locationutils.js.map +1 -1
  164. package/dist/monitorSlice/constants.cjs +0 -19
  165. package/dist/monitorSlice/constants.d.cts +2 -5
  166. package/dist/monitorSlice/constants.d.ts +2 -5
  167. package/dist/monitorSlice/constants.js +1 -2
  168. package/dist/monitorSlice/index.cjs +65 -82
  169. package/dist/monitorSlice/index.cjs.map +1 -1
  170. package/dist/monitorSlice/index.d.cts +2 -94
  171. package/dist/monitorSlice/index.d.ts +2 -94
  172. package/dist/monitorSlice/index.js +59 -18
  173. package/dist/monitorSlice/index.js.map +1 -1
  174. package/dist/monitorSlice/mocks.cjs +50 -126
  175. package/dist/monitorSlice/mocks.cjs.map +1 -1
  176. package/dist/monitorSlice/mocks.d.cts +49 -45
  177. package/dist/monitorSlice/mocks.d.ts +49 -45
  178. package/dist/monitorSlice/mocks.js +49 -62
  179. package/dist/monitorSlice/mocks.js.map +1 -1
  180. package/dist/monitorSlice/selectors.cjs +5 -29
  181. package/dist/monitorSlice/selectors.cjs.map +1 -1
  182. package/dist/monitorSlice/selectors.d.cts +10 -1
  183. package/dist/monitorSlice/selectors.d.ts +10 -1
  184. package/dist/monitorSlice/selectors.js +5 -6
  185. package/dist/monitorSlice/selectors.js.map +1 -1
  186. package/dist/monitorSlice/thunks.cjs +83 -1914
  187. package/dist/monitorSlice/thunks.cjs.map +1 -1
  188. package/dist/monitorSlice/thunks.d.cts +112 -120
  189. package/dist/monitorSlice/thunks.d.ts +112 -120
  190. package/dist/monitorSlice/thunks.js +78 -42
  191. package/dist/monitorSlice/thunks.js.map +1 -1
  192. package/dist/onboardingSlice/constants.cjs +44 -69
  193. package/dist/onboardingSlice/constants.cjs.map +1 -1
  194. package/dist/onboardingSlice/constants.d.cts +2 -26
  195. package/dist/onboardingSlice/constants.d.ts +2 -26
  196. package/dist/onboardingSlice/constants.js +43 -7
  197. package/dist/onboardingSlice/constants.js.map +1 -1
  198. package/dist/onboardingSlice/index.cjs +53 -73
  199. package/dist/onboardingSlice/index.cjs.map +1 -1
  200. package/dist/onboardingSlice/index.d.cts +2 -62
  201. package/dist/onboardingSlice/index.d.ts +2 -62
  202. package/dist/onboardingSlice/index.js +47 -13
  203. package/dist/onboardingSlice/index.js.map +1 -1
  204. package/dist/onboardingSlice/mocks.cjs +12 -81
  205. package/dist/onboardingSlice/mocks.cjs.map +1 -1
  206. package/dist/onboardingSlice/mocks.d.cts +14 -15
  207. package/dist/onboardingSlice/mocks.d.ts +14 -15
  208. package/dist/onboardingSlice/mocks.js +12 -15
  209. package/dist/onboardingSlice/mocks.js.map +1 -1
  210. package/dist/onboardingSlice/selectors.cjs +5 -29
  211. package/dist/onboardingSlice/selectors.cjs.map +1 -1
  212. package/dist/onboardingSlice/selectors.d.cts +6 -1
  213. package/dist/onboardingSlice/selectors.d.ts +6 -1
  214. package/dist/onboardingSlice/selectors.js +5 -6
  215. package/dist/onboardingSlice/selectors.js.map +1 -1
  216. package/dist/onboardingSlice/thunks.cjs +8 -4746
  217. package/dist/onboardingSlice/thunks.d.cts +124 -143
  218. package/dist/onboardingSlice/thunks.d.ts +124 -143
  219. package/dist/onboardingSlice/thunks.js +2 -49
  220. package/dist/organizationSlice/constants.cjs +11 -95
  221. package/dist/organizationSlice/constants.d.cts +2 -91
  222. package/dist/organizationSlice/constants.d.ts +2 -91
  223. package/dist/organizationSlice/constants.js +2 -27
  224. package/dist/organizationSlice/index.cjs +113 -152
  225. package/dist/organizationSlice/index.cjs.map +1 -1
  226. package/dist/organizationSlice/index.d.cts +2 -74
  227. package/dist/organizationSlice/index.d.ts +2 -74
  228. package/dist/organizationSlice/index.js +106 -18
  229. package/dist/organizationSlice/index.js.map +1 -1
  230. package/dist/organizationSlice/mocks.cjs +215 -406
  231. package/dist/organizationSlice/mocks.cjs.map +1 -1
  232. package/dist/organizationSlice/mocks.d.cts +209 -212
  233. package/dist/organizationSlice/mocks.d.ts +209 -212
  234. package/dist/organizationSlice/mocks.js +214 -184
  235. package/dist/organizationSlice/mocks.js.map +1 -1
  236. package/dist/organizationSlice/selectors.cjs +97 -474
  237. package/dist/organizationSlice/selectors.cjs.map +1 -1
  238. package/dist/organizationSlice/selectors.d.cts +381 -389
  239. package/dist/organizationSlice/selectors.d.ts +381 -389
  240. package/dist/organizationSlice/selectors.js +78 -50
  241. package/dist/organizationSlice/selectors.js.map +1 -1
  242. package/dist/organizationSlice/thunks.cjs +43 -5150
  243. package/dist/organizationSlice/thunks.d.cts +638 -649
  244. package/dist/organizationSlice/thunks.d.ts +638 -649
  245. package/dist/organizationSlice/thunks.js +2 -119
  246. package/dist/organizationSlice/types.cjs +0 -19
  247. package/dist/organizationSlice/types.d.cts +2 -88
  248. package/dist/organizationSlice/types.d.ts +2 -88
  249. package/dist/organizationSlice/types.js +1 -1
  250. package/dist/releasesSlice/constants.cjs +17 -41
  251. package/dist/releasesSlice/constants.cjs.map +1 -1
  252. package/dist/releasesSlice/constants.d.cts +2 -15
  253. package/dist/releasesSlice/constants.d.ts +2 -15
  254. package/dist/releasesSlice/constants.js +13 -14
  255. package/dist/releasesSlice/constants.js.map +1 -1
  256. package/dist/releasesSlice/index.cjs +106 -179
  257. package/dist/releasesSlice/index.cjs.map +1 -1
  258. package/dist/releasesSlice/index.d.cts +2 -113
  259. package/dist/releasesSlice/index.d.ts +2 -113
  260. package/dist/releasesSlice/index.js +100 -18
  261. package/dist/releasesSlice/index.js.map +1 -1
  262. package/dist/releasesSlice/mocks.cjs +44 -220
  263. package/dist/releasesSlice/mocks.cjs.map +1 -1
  264. package/dist/releasesSlice/mocks.d.cts +63 -61
  265. package/dist/releasesSlice/mocks.d.ts +63 -61
  266. package/dist/releasesSlice/mocks.js +43 -59
  267. package/dist/releasesSlice/mocks.js.map +1 -1
  268. package/dist/releasesSlice/selectors.cjs +44 -439
  269. package/dist/releasesSlice/selectors.cjs.map +1 -1
  270. package/dist/releasesSlice/selectors.d.cts +268 -280
  271. package/dist/releasesSlice/selectors.d.ts +268 -280
  272. package/dist/releasesSlice/selectors.js +31 -36
  273. package/dist/releasesSlice/selectors.js.map +1 -1
  274. package/dist/releasesSlice/thunks.cjs +422 -2175
  275. package/dist/releasesSlice/thunks.cjs.map +1 -1
  276. package/dist/releasesSlice/thunks.d.cts +305 -307
  277. package/dist/releasesSlice/thunks.d.ts +305 -307
  278. package/dist/releasesSlice/thunks.js +413 -65
  279. package/dist/releasesSlice/thunks.js.map +1 -1
  280. package/dist/selectors.cjs +136 -1530
  281. package/dist/selectors.d.cts +10 -36
  282. package/dist/selectors.d.ts +10 -36
  283. package/dist/selectors.js +10 -280
  284. package/dist/sockethook.cjs +140 -515
  285. package/dist/sockethook.cjs.map +1 -1
  286. package/dist/sockethook.d.cts +25 -9
  287. package/dist/sockethook.d.ts +25 -9
  288. package/dist/sockethook.js +134 -135
  289. package/dist/sockethook.js.map +1 -1
  290. package/dist/store-BQxOSRC1.d.ts +234 -0
  291. package/dist/store-BiIA0r0A.d.cts +234 -0
  292. package/dist/store.cjs +117 -1290
  293. package/dist/store.cjs.map +1 -1
  294. package/dist/store.d.cts +3 -206
  295. package/dist/store.d.ts +3 -206
  296. package/dist/store.js +110 -32
  297. package/dist/store.js.map +1 -1
  298. package/dist/storehooks.cjs +240 -5783
  299. package/dist/storehooks.cjs.map +1 -1
  300. package/dist/storehooks.d.cts +76 -4
  301. package/dist/storehooks.d.ts +76 -4
  302. package/dist/storehooks.js +229 -265
  303. package/dist/storehooks.js.map +1 -1
  304. package/dist/thunks.cjs +2614 -5918
  305. package/dist/thunks.cjs.map +1 -1
  306. package/dist/thunks.d.cts +9 -36
  307. package/dist/thunks.d.ts +9 -36
  308. package/dist/thunks.js +2439 -385
  309. package/dist/thunks.js.map +1 -1
  310. package/dist/types-B2NRQLFw.d.ts +88 -0
  311. package/dist/types-ClEfo0dK.d.cts +88 -0
  312. package/dist/useDeploymentDevice.cjs +26 -4650
  313. package/dist/useDeploymentDevice.cjs.map +1 -1
  314. package/dist/useDeploymentDevice.d.cts +4 -2
  315. package/dist/useDeploymentDevice.d.ts +4 -2
  316. package/dist/useDeploymentDevice.js +21 -60
  317. package/dist/useDeploymentDevice.js.map +1 -1
  318. package/dist/usersSlice/constants.cjs +8 -55
  319. package/dist/usersSlice/constants.d.cts +2 -52
  320. package/dist/usersSlice/constants.d.ts +2 -52
  321. package/dist/usersSlice/constants.js +2 -21
  322. package/dist/usersSlice/index.cjs +132 -172
  323. package/dist/usersSlice/index.cjs.map +1 -1
  324. package/dist/usersSlice/index.d.cts +2 -152
  325. package/dist/usersSlice/index.d.ts +2 -152
  326. package/dist/usersSlice/index.js +125 -18
  327. package/dist/usersSlice/index.js.map +1 -1
  328. package/dist/usersSlice/mocks.cjs +55 -196
  329. package/dist/usersSlice/mocks.cjs.map +1 -1
  330. package/dist/usersSlice/mocks.d.cts +68 -72
  331. package/dist/usersSlice/mocks.d.ts +68 -72
  332. package/dist/usersSlice/mocks.js +54 -46
  333. package/dist/usersSlice/mocks.js.map +1 -1
  334. package/dist/usersSlice/selectors.cjs +65 -567
  335. package/dist/usersSlice/selectors.cjs.map +1 -1
  336. package/dist/usersSlice/selectors.d.cts +364 -376
  337. package/dist/usersSlice/selectors.d.ts +364 -376
  338. package/dist/usersSlice/selectors.js +44 -50
  339. package/dist/usersSlice/selectors.js.map +1 -1
  340. package/dist/usersSlice/thunks.cjs +39 -4698
  341. package/dist/usersSlice/thunks.d.cts +807 -843
  342. package/dist/usersSlice/thunks.d.ts +807 -843
  343. package/dist/usersSlice/thunks.js +2 -111
  344. package/dist/utils-B4I595rf.d.cts +104 -0
  345. package/dist/utils-DNnSR4S_.d.ts +104 -0
  346. package/dist/utils.cjs +229 -850
  347. package/dist/utils.cjs.map +1 -1
  348. package/dist/utils.d.cts +2 -80
  349. package/dist/utils.d.ts +2 -80
  350. package/dist/utils.js +210 -50
  351. package/dist/utils.js.map +1 -1
  352. package/package.json +11 -13
  353. package/dist/appSlice/thunks.cjs.map +0 -1
  354. package/dist/appSlice/thunks.js.map +0 -1
  355. package/dist/chunk-2DYA3X77.js +0 -15
  356. package/dist/chunk-2DYA3X77.js.map +0 -1
  357. package/dist/chunk-4BHM6WVX.js +0 -50
  358. package/dist/chunk-4BHM6WVX.js.map +0 -1
  359. package/dist/chunk-4UNLEL5A.js +0 -143
  360. package/dist/chunk-4UNLEL5A.js.map +0 -1
  361. package/dist/chunk-6V5IIIF7.js +0 -396
  362. package/dist/chunk-6V5IIIF7.js.map +0 -1
  363. package/dist/chunk-ARMI6SZS.js +0 -446
  364. package/dist/chunk-ARMI6SZS.js.map +0 -1
  365. package/dist/chunk-AZF4YY3P.js +0 -108
  366. package/dist/chunk-AZF4YY3P.js.map +0 -1
  367. package/dist/chunk-B5AI2YPV.js +0 -156
  368. package/dist/chunk-B5AI2YPV.js.map +0 -1
  369. package/dist/chunk-CQXDAXQF.js +0 -51
  370. package/dist/chunk-CQXDAXQF.js.map +0 -1
  371. package/dist/chunk-DBBE6D36.js +0 -115
  372. package/dist/chunk-DBBE6D36.js.map +0 -1
  373. package/dist/chunk-ECVQVQEL.js +0 -68
  374. package/dist/chunk-ECVQVQEL.js.map +0 -1
  375. package/dist/chunk-FAJ3I2UQ.js +0 -47
  376. package/dist/chunk-FAJ3I2UQ.js.map +0 -1
  377. package/dist/chunk-FCY7BUGK.js +0 -2876
  378. package/dist/chunk-FCY7BUGK.js.map +0 -1
  379. package/dist/chunk-FG37HJLC.js +0 -157
  380. package/dist/chunk-FG37HJLC.js.map +0 -1
  381. package/dist/chunk-FQAUVV6C.js +0 -246
  382. package/dist/chunk-FQAUVV6C.js.map +0 -1
  383. package/dist/chunk-HKN3RN2Z.js +0 -41
  384. package/dist/chunk-HKN3RN2Z.js.map +0 -1
  385. package/dist/chunk-HPKXWNEF.js +0 -100
  386. package/dist/chunk-HPKXWNEF.js.map +0 -1
  387. package/dist/chunk-JIS4PA3R.js +0 -7
  388. package/dist/chunk-JIS4PA3R.js.map +0 -1
  389. package/dist/chunk-JXBTIFMS.js +0 -82
  390. package/dist/chunk-JXBTIFMS.js.map +0 -1
  391. package/dist/chunk-JYPSCCT4.js +0 -58
  392. package/dist/chunk-JYPSCCT4.js.map +0 -1
  393. package/dist/chunk-L53CPHJU.js +0 -721
  394. package/dist/chunk-L53CPHJU.js.map +0 -1
  395. package/dist/chunk-MNJXEB7S.js +0 -304
  396. package/dist/chunk-MNJXEB7S.js.map +0 -1
  397. package/dist/chunk-NMAXZ3ZY.js +0 -1
  398. package/dist/chunk-NMAXZ3ZY.js.map +0 -1
  399. package/dist/chunk-NXLXPRYW.js +0 -142
  400. package/dist/chunk-NXLXPRYW.js.map +0 -1
  401. package/dist/chunk-O6VCSLNE.js +0 -59
  402. package/dist/chunk-O6VCSLNE.js.map +0 -1
  403. package/dist/chunk-PQADM3M3.js +0 -115
  404. package/dist/chunk-PQADM3M3.js.map +0 -1
  405. package/dist/chunk-SJ75YKOA.js +0 -44
  406. package/dist/chunk-SJ75YKOA.js.map +0 -1
  407. package/dist/chunk-TUPBZ6MQ.js +0 -162
  408. package/dist/chunk-TUPBZ6MQ.js.map +0 -1
  409. package/dist/chunk-XF3TZSZS.js +0 -25
  410. package/dist/chunk-XF3TZSZS.js.map +0 -1
  411. package/dist/chunk-YB3US6OT.js +0 -61
  412. package/dist/chunk-YB3US6OT.js.map +0 -1
  413. package/dist/chunk-YDDE5TIH.js +0 -204
  414. package/dist/chunk-YDDE5TIH.js.map +0 -1
  415. package/dist/chunk-YO22XLHI.js +0 -7
  416. package/dist/chunk-YO22XLHI.js.map +0 -1
  417. package/dist/chunk-Z2O6LYVP.js +0 -144
  418. package/dist/chunk-Z2O6LYVP.js.map +0 -1
  419. package/dist/chunk-ZKAH3APE.js +0 -1
  420. package/dist/chunk-ZKAH3APE.js.map +0 -1
  421. package/dist/commonConstants.cjs.map +0 -1
  422. package/dist/commonConstants.js.map +0 -1
  423. package/dist/deploymentsSlice/constants.cjs.map +0 -1
  424. package/dist/deploymentsSlice/constants.js.map +0 -1
  425. package/dist/deploymentsSlice/thunks.cjs.map +0 -1
  426. package/dist/deploymentsSlice/thunks.js.map +0 -1
  427. package/dist/devicesSlice/constants.cjs.map +0 -1
  428. package/dist/devicesSlice/constants.js.map +0 -1
  429. package/dist/devicesSlice/thunks.cjs.map +0 -1
  430. package/dist/devicesSlice/thunks.js.map +0 -1
  431. package/dist/monitorSlice/constants.cjs.map +0 -1
  432. package/dist/monitorSlice/constants.js.map +0 -1
  433. package/dist/onboardingSlice/thunks.cjs.map +0 -1
  434. package/dist/onboardingSlice/thunks.js.map +0 -1
  435. package/dist/organizationSlice/constants.cjs.map +0 -1
  436. package/dist/organizationSlice/constants.js.map +0 -1
  437. package/dist/organizationSlice/thunks.cjs.map +0 -1
  438. package/dist/organizationSlice/thunks.js.map +0 -1
  439. package/dist/organizationSlice/types.cjs.map +0 -1
  440. package/dist/organizationSlice/types.js.map +0 -1
  441. package/dist/selectors.cjs.map +0 -1
  442. package/dist/selectors.js.map +0 -1
  443. package/dist/usersSlice/constants.cjs.map +0 -1
  444. package/dist/usersSlice/constants.js.map +0 -1
  445. package/dist/usersSlice/thunks.cjs.map +0 -1
  446. package/dist/usersSlice/thunks.js.map +0 -1
package/dist/thunks.js CHANGED
@@ -1,387 +1,2441 @@
1
- import {
2
- abortDeployment,
3
- addDevicesToGroup,
4
- addDynamicGroup,
5
- addStaticGroup,
6
- addTenant,
7
- addUserToCurrentTenant,
8
- advanceOnboarding,
9
- applyDeviceConfig,
10
- cancelRequest,
11
- cancelUpgrade,
12
- changeIntegration,
13
- changeSsoConfig,
14
- checkEmailExists,
15
- completeUpgrade,
16
- confirmCardUpdate,
17
- createBillingProfile,
18
- createDeployment,
19
- createIntegration,
20
- createOrganizationTrial,
21
- createRole,
22
- createUser,
23
- decommissionDevice,
24
- deleteAuthset,
25
- deleteIntegration,
26
- deleteSsoConfig,
27
- deriveDeploymentGroup,
28
- deviceFileUpload,
29
- disableUser2fa,
30
- downloadLicenseReport,
31
- editBillingProfile,
32
- editRole,
33
- editTenant,
34
- editUser,
35
- enableUser2fa,
36
- generateDeploymentLogAnalysis,
37
- generateToken,
38
- get2FAQRCode,
39
- getAllDeviceCounts,
40
- getAllDevicesByStatus,
41
- getAllDynamicGroupDevices,
42
- getAllGroupDevices,
43
- getAuditLogs,
44
- getAuditLogsCsvLink,
45
- getBillingPreview,
46
- getCurrentCard,
47
- getCurrentSubscription,
48
- getDeploymentDevices,
49
- getDeploymentsByStatus,
50
- getDeploymentsConfig,
51
- getDeviceAttributes,
52
- getDeviceAuth,
53
- getDeviceById,
54
- getDeviceConfig,
55
- getDeviceConnect,
56
- getDeviceDeployments,
57
- getDeviceFileDownloadLink,
58
- getDeviceInfo,
59
- getDeviceLimits,
60
- getDeviceLog,
61
- getDeviceTwin,
62
- getDevicesByStatus,
63
- getDevicesWithAuth,
64
- getDynamicGroup,
65
- getDynamicGroups,
66
- getGatewayDevices,
67
- getGlobalSettings,
68
- getGroupDevices,
69
- getGroups,
70
- getIntegrations,
71
- getLatestReleaseInfo,
72
- getOnboardingState,
73
- getPermissionSets,
74
- getProducts,
75
- getReportDataWithoutBackendSupport,
76
- getRoles,
77
- getSessionDetails,
78
- getSingleDeployment,
79
- getSsoConfigById,
80
- getSsoConfigs,
81
- getSystemDevices,
82
- getTargetLocation,
83
- getTenants,
84
- getTokens,
85
- getUser,
86
- getUserBilling,
87
- getUserList,
88
- getUserOrganization,
89
- getUserSettings,
90
- getUserSubscription,
91
- getWebhookEvents,
92
- initializeSelf,
93
- loginUser,
94
- logoutUser,
95
- normalizeRbacRoles,
96
- passwordResetComplete,
97
- passwordResetStart,
98
- preauthDevice,
99
- removeDevicesFromGroup,
100
- removeDynamicGroup,
101
- removeReportsByGroupName,
102
- removeRole,
103
- removeStaticGroup,
104
- removeTenant,
105
- removeUser,
106
- requestPlanChange,
107
- requestPlanUpgrade,
108
- resetDeviceDeployments,
109
- revokeToken,
110
- saveDeltaDeploymentsConfig,
111
- saveGlobalSettings,
112
- saveUserSettings,
113
- searchDevices,
114
- selectGroup,
115
- sendSupportMessage,
116
- setAllTooltipsReadState,
117
- setAuditlogsState,
118
- setDeploymentsState,
119
- setDeviceConfig,
120
- setDeviceListState,
121
- setDeviceTags,
122
- setDeviceTwin,
123
- setFirstLoginAfterSignup,
124
- setHideAnnouncement,
125
- setOfflineThreshold,
126
- setOnboardingApproach,
127
- setOnboardingCanceled,
128
- setOnboardingComplete,
129
- setOnboardingDeviceType,
130
- setSearchState,
131
- setTenantsListState,
132
- setTooltipReadState,
133
- startCardUpdate,
134
- startUpgrade,
135
- storeSsoConfig,
136
- submitUserFeedback,
137
- switchUserOrganization,
138
- tenantDataDivergedMessage,
139
- transformProductResponse,
140
- triggerDeviceUpdate,
141
- updateDeploymentControlMap,
142
- updateDeviceAuth,
143
- updateDevicesAuth,
144
- updateDynamicGroup,
145
- updateReportData,
146
- updateUserColumnSettings,
147
- verify2FA,
148
- verifyEmailComplete,
149
- verifyEmailStart
150
- } from "./chunk-FCY7BUGK.js";
151
- import {
152
- cancelFileUpload,
153
- createArtifact,
154
- editArtifact,
155
- getArtifactInstallCount,
156
- getArtifactUrl,
157
- getDeltaGenerationJobDetails,
158
- getDeltaGenerationJobs,
159
- getExistingReleaseTags,
160
- getRelease,
161
- getReleases,
162
- getUpdateTypes,
163
- removeArtifact,
164
- removeRelease,
165
- removeReleases,
166
- selectRelease,
167
- setReleaseTags,
168
- setReleasesListState,
169
- setReleasesTags,
170
- setSingleReleaseTags,
171
- updateReleaseInfo,
172
- uploadArtifact
173
- } from "./chunk-ARMI6SZS.js";
174
- import {
175
- changeNotificationSetting,
176
- getDeviceAlerts,
177
- getDeviceMonitorConfig,
178
- getIssueCountsByType,
179
- getLatestDeviceAlerts
180
- } from "./chunk-AZF4YY3P.js";
181
- import "./chunk-NXLXPRYW.js";
182
- import "./chunk-XF3TZSZS.js";
183
- import "./chunk-JYPSCCT4.js";
184
- import "./chunk-HKN3RN2Z.js";
185
- import "./chunk-FG37HJLC.js";
186
- import "./chunk-Z2O6LYVP.js";
187
- import "./chunk-PQADM3M3.js";
188
- import "./chunk-YB3US6OT.js";
189
- import "./chunk-CQXDAXQF.js";
190
- import "./chunk-YDDE5TIH.js";
191
- import "./chunk-B5AI2YPV.js";
192
- import "./chunk-4UNLEL5A.js";
193
- import "./chunk-ECVQVQEL.js";
194
- import "./chunk-6V5IIIF7.js";
195
- import "./chunk-NMAXZ3ZY.js";
196
- import "./chunk-MNJXEB7S.js";
197
- import "./chunk-SJ75YKOA.js";
198
- import "./chunk-JXBTIFMS.js";
199
- import "./chunk-HPKXWNEF.js";
200
- import "./chunk-YO22XLHI.js";
201
- import "./chunk-JIS4PA3R.js";
202
- import "./chunk-O6VCSLNE.js";
203
- import "./chunk-TUPBZ6MQ.js";
204
- import "./chunk-4BHM6WVX.js";
205
- import "./chunk-FQAUVV6C.js";
206
- import "./chunk-L53CPHJU.js";
207
- import "./chunk-2DYA3X77.js";
208
- import "./chunk-FAJ3I2UQ.js";
209
- import "./chunk-ZKAH3APE.js";
210
- import "./chunk-DBBE6D36.js";
211
- export {
212
- abortDeployment,
213
- addDevicesToGroup,
214
- addDynamicGroup,
215
- addStaticGroup,
216
- addTenant,
217
- addUserToCurrentTenant,
218
- advanceOnboarding,
219
- applyDeviceConfig,
220
- cancelFileUpload,
221
- cancelRequest,
222
- cancelUpgrade,
223
- changeIntegration,
224
- changeNotificationSetting,
225
- changeSsoConfig,
226
- checkEmailExists,
227
- completeUpgrade,
228
- confirmCardUpdate,
229
- createArtifact,
230
- createBillingProfile,
231
- createDeployment,
232
- createIntegration,
233
- createOrganizationTrial,
234
- createRole,
235
- createUser,
236
- decommissionDevice,
237
- deleteAuthset,
238
- deleteIntegration,
239
- deleteSsoConfig,
240
- deriveDeploymentGroup,
241
- deviceFileUpload,
242
- disableUser2fa,
243
- downloadLicenseReport,
244
- editArtifact,
245
- editBillingProfile,
246
- editRole,
247
- editTenant,
248
- editUser,
249
- enableUser2fa,
250
- generateDeploymentLogAnalysis,
251
- generateToken,
252
- get2FAQRCode,
253
- getAllDeviceCounts,
254
- getAllDevicesByStatus,
255
- getAllDynamicGroupDevices,
256
- getAllGroupDevices,
257
- getArtifactInstallCount,
258
- getArtifactUrl,
259
- getAuditLogs,
260
- getAuditLogsCsvLink,
261
- getBillingPreview,
262
- getCurrentCard,
263
- getCurrentSubscription,
264
- getDeltaGenerationJobDetails,
265
- getDeltaGenerationJobs,
266
- getDeploymentDevices,
267
- getDeploymentsByStatus,
268
- getDeploymentsConfig,
269
- getDeviceAlerts,
270
- getDeviceAttributes,
271
- getDeviceAuth,
272
- getDeviceById,
273
- getDeviceConfig,
274
- getDeviceConnect,
275
- getDeviceDeployments,
276
- getDeviceFileDownloadLink,
277
- getDeviceInfo,
278
- getDeviceLimits,
279
- getDeviceLog,
280
- getDeviceMonitorConfig,
281
- getDeviceTwin,
282
- getDevicesByStatus,
283
- getDevicesWithAuth,
284
- getDynamicGroup,
285
- getDynamicGroups,
286
- getExistingReleaseTags,
287
- getGatewayDevices,
288
- getGlobalSettings,
289
- getGroupDevices,
290
- getGroups,
291
- getIntegrations,
292
- getIssueCountsByType,
293
- getLatestDeviceAlerts,
294
- getLatestReleaseInfo,
295
- getOnboardingState,
296
- getPermissionSets,
297
- getProducts,
298
- getRelease,
299
- getReleases,
300
- getReportDataWithoutBackendSupport,
301
- getRoles,
302
- getSessionDetails,
303
- getSingleDeployment,
304
- getSsoConfigById,
305
- getSsoConfigs,
306
- getSystemDevices,
307
- getTargetLocation,
308
- getTenants,
309
- getTokens,
310
- getUpdateTypes,
311
- getUser,
312
- getUserBilling,
313
- getUserList,
314
- getUserOrganization,
315
- getUserSettings,
316
- getUserSubscription,
317
- getWebhookEvents,
318
- initializeSelf,
319
- loginUser,
320
- logoutUser,
321
- normalizeRbacRoles,
322
- passwordResetComplete,
323
- passwordResetStart,
324
- preauthDevice,
325
- removeArtifact,
326
- removeDevicesFromGroup,
327
- removeDynamicGroup,
328
- removeRelease,
329
- removeReleases,
330
- removeReportsByGroupName,
331
- removeRole,
332
- removeStaticGroup,
333
- removeTenant,
334
- removeUser,
335
- requestPlanChange,
336
- requestPlanUpgrade,
337
- resetDeviceDeployments,
338
- revokeToken,
339
- saveDeltaDeploymentsConfig,
340
- saveGlobalSettings,
341
- saveUserSettings,
342
- searchDevices,
343
- selectGroup,
344
- selectRelease,
345
- sendSupportMessage,
346
- setAllTooltipsReadState,
347
- setAuditlogsState,
348
- setDeploymentsState,
349
- setDeviceConfig,
350
- setDeviceListState,
351
- setDeviceTags,
352
- setDeviceTwin,
353
- setFirstLoginAfterSignup,
354
- setHideAnnouncement,
355
- setOfflineThreshold,
356
- setOnboardingApproach,
357
- setOnboardingCanceled,
358
- setOnboardingComplete,
359
- setOnboardingDeviceType,
360
- setReleaseTags,
361
- setReleasesListState,
362
- setReleasesTags,
363
- setSearchState,
364
- setSingleReleaseTags,
365
- setTenantsListState,
366
- setTooltipReadState,
367
- startCardUpdate,
368
- startUpgrade,
369
- storeSsoConfig,
370
- submitUserFeedback,
371
- switchUserOrganization,
372
- tenantDataDivergedMessage,
373
- transformProductResponse,
374
- triggerDeviceUpdate,
375
- updateDeploymentControlMap,
376
- updateDeviceAuth,
377
- updateDevicesAuth,
378
- updateDynamicGroup,
379
- updateReleaseInfo,
380
- updateReportData,
381
- updateUserColumnSettings,
382
- uploadArtifact,
383
- verify2FA,
384
- verifyEmailComplete,
385
- verifyEmailStart
1
+ import { ADDONS, PLANS, locations } from "./appSlice/constants.js";
2
+ import { onboardingSteps, orderedOnboardingSteps } from "./onboardingSlice/constants.js";
3
+ import { rootfsImageVersion } from "./releasesSlice/constants.js";
4
+ import { ALL_DEVICE_STATES, ALL_RELEASES, APPLICATION_JSON_CONTENT_TYPE, APPLICATION_JWT_CONTENT_TYPE, DEPLOYMENT_ROUTES, DEPLOYMENT_STATES, DEPLOYMENT_TYPES, DEVICE_FILTERING_OPTIONS, DEVICE_LIST_DEFAULTS, DEVICE_STATES, EXTERNAL_PROVIDER, PermissionTypes, READ_STATES, SORTING_OPTIONS, SSO_TYPES, TENANT_LIST_DEFAULT, TIMEOUTS, UNGROUPED_GROUP, USER_LOGOUT, apiRoot, auditLogsApiUrl, defaultPermissionSets, deploymentPrototype, deploymentsApiUrl, deploymentsApiUrlV2, deviceAuthV2, deviceConfig, deviceConnect, emptyFilter, emptyRole, emptyUiPermissions, headerNames, inventoryApiUrl, inventoryApiUrlV2, iotManagerBaseURL, itemUiPermissionsReducer, maxSessionAge, rolesById, scopedPermissionAreas, settingsKeys, ssoIdpApiUrlv1, tenantadmApiUrlv1, tenantadmApiUrlv2, twoFAStates, uiPermissionsByArea, uiPermissionsById, useradmApiUrl, useradmApiUrlv2 } from "./constants.js";
5
+ import { actions } from "./appSlice/index.js";
6
+ import { actions as actions$1, sliceName as sliceName$1 } from "./deploymentsSlice/index.js";
7
+ import { actions as actions$2, sliceName as sliceName$2 } from "./devicesSlice/index.js";
8
+ import { actions as actions$3, sliceName as sliceName$3 } from "./onboardingSlice/index.js";
9
+ import { actions as actions$4, sliceName as sliceName$4 } from "./organizationSlice/index.js";
10
+ import { actions as actions$5, sliceName as sliceName$5 } from "./usersSlice/index.js";
11
+ import actions_default from "./actions.js";
12
+ import { cleanUp, getSessionInfo, setSessionInfo } from "./auth.js";
13
+ import { getFeatures, getHostedAnnouncement, getSearchState } from "./appSlice/selectors.js";
14
+ import { getDeploymentsById, getDeploymentsByStatus as getDeploymentsByStatus$1 } from "./deploymentsSlice/selectors.js";
15
+ import { getAcceptedDevices, getDeviceById as getDeviceById$1, getDeviceCountsByStatus, getDeviceFilters, getDeviceListState, getDeviceReports, getDevicesById, getGroupsById, getSelectedGroup } from "./devicesSlice/selectors.js";
16
+ import { getAuditlogState, getDeviceTwinIntegrations, getOrganization, getSpLimits, getTenantsList } from "./organizationSlice/selectors.js";
17
+ import { convertDeviceListStateToFilters, convertToBackendSPLimits, extractErrorMessage as extractErrorMessage$1, filtersFilter, getComparisonCompatibleVersion, mapDeviceAttributes, mapFiltersToTerms, mapTermsToFilters, mergePermissions, parseSubscriptionPreview, progress } from "./utils.js";
18
+ import { getCurrentUser, getGlobalSettings as getGlobalSettings$1, getIdAttribute, getOfflineThresholdSettings, getRolesById, getSelectedDeviceAttribute, getTooltipsState, getUserSettings as getUserSettings$1, getUsersById } from "./usersSlice/selectors.js";
19
+ import { getDeviceReportsForUser, getOnboardingState as getOnboardingState$1, getTenantCapabilities, getUserCapabilities } from "./commonSelectors.js";
20
+ import { commonErrorFallback, commonErrorHandler, createAppAsyncThunk } from "./store.js";
21
+ import Api from "./api/general-api.js";
22
+ import { changeNotificationSetting, getDeviceAlerts, getDeviceMonitorConfig, getIssueCountsByType, getLatestDeviceAlerts } from "./monitorSlice/thunks.js";
23
+ import { cancelFileUpload, createArtifact, editArtifact, getArtifactInstallCount, getArtifactUrl, getDeltaGenerationJobDetails, getDeltaGenerationJobs, getExistingReleaseTags, getRelease, getReleases, getUpdateTypes, removeArtifact, removeRelease, removeReleases, selectRelease, setReleaseTags, setReleasesListState, setReleasesTags, setSingleReleaseTags, updateReleaseInfo, uploadArtifact } from "./releasesSlice/thunks.js";
24
+ import Api$1 from "./api/users-api.js";
25
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
26
+ import { attributeDuplicateFilter, customSort, dateRangeToUnix, deepCompare, duplicateFilter, extractErrorMessage, getDemoDeviceAddress, getSnackbarMessage, isEmpty, standardizePhases } from "@northern.tech/utils/helpers";
27
+ import Cookies from "universal-cookie";
28
+ import dayjs from "dayjs";
29
+ import { Link } from "react-router-dom";
30
+ import { isCancel } from "axios";
31
+ import Tracking from "@northern.tech/utils/tracking";
32
+ import validator from "validator";
33
+ import pluralize from "pluralize";
34
+ import { v4 } from "uuid";
35
+ import utc from "dayjs/plugin/utc.js";
36
+ import hashString from "md5";
37
+ import { clearAllRetryTimers } from "@northern.tech/utils/retrytimer";
38
+ //#region src/appSlice/thunks.ts
39
+ const cookies$3 = new Cookies();
40
+ const setFirstLoginAfterSignup = createAppAsyncThunk(`app/setFirstLoginAfterSignup`, (firstLoginAfterSignup, { dispatch }) => {
41
+ cookies$3.set("firstLoginAfterSignup", !!firstLoginAfterSignup, {
42
+ maxAge: 60,
43
+ path: "/",
44
+ domain: ".mender.io",
45
+ sameSite: false
46
+ });
47
+ dispatch(actions.setFirstLoginAfterSignup(!!firstLoginAfterSignup));
48
+ });
49
+ const dateFunctionMap = {
50
+ getDays: "getDate",
51
+ setDays: "setDate"
386
52
  };
53
+ const setOfflineThreshold = createAppAsyncThunk(`app/setOfflineThreshold`, async (_, { dispatch, getState }) => {
54
+ const { interval, intervalUnit } = getOfflineThresholdSettings(getState());
55
+ const today = /* @__PURE__ */ new Date();
56
+ const intervalName = `${intervalUnit.charAt(0).toUpperCase()}${intervalUnit.substring(1)}`;
57
+ const setter = dateFunctionMap[`set${intervalName}`] ?? `set${intervalName}`;
58
+ const getter = dateFunctionMap[`get${intervalName}`] ?? `get${intervalName}`;
59
+ today[setter](today[getter]() - interval);
60
+ let value;
61
+ try {
62
+ value = today.toISOString();
63
+ } catch {
64
+ dispatch(actions.setSnackbar("There was an error saving the offline threshold, please check your settings."));
65
+ return;
66
+ }
67
+ return dispatch(actions.setOfflineThreshold(value));
68
+ });
69
+ const versionRegex = /* @__PURE__ */ new RegExp(/\d+\.\d+/);
70
+ const getLatestRelease = (thing) => {
71
+ return thing[Object.keys(thing).filter((key) => versionRegex.test(key)).sort().reverse()[0]];
72
+ };
73
+ const repoKeyMap = {
74
+ integration: "Integration",
75
+ "mender-artifact": "Mender-Artifact"
76
+ };
77
+ const deductSaasState = (latestRelease, guiTags) => {
78
+ const latestGuiTag = guiTags.length ? guiTags[0].name : "";
79
+ return latestGuiTag ? latestGuiTag : latestRelease.release;
80
+ };
81
+ const getLatestReleaseInfo = createAppAsyncThunk(`app/getLatestReleaseInfo`, async (_, { dispatch, getState }) => {
82
+ if (!getFeatures(getState()).isHosted) return;
83
+ const [{ data }, { data: guiTags }] = await Promise.all([Api.get("/versions.json"), Api.get("/tags.json")]).catch((err) => {
84
+ console.log("init error:", extractErrorMessage(err));
85
+ return [{ data: {} }, { data: [] }];
86
+ });
87
+ if (!guiTags.length) return;
88
+ const { releases } = data;
89
+ const latestRelease = getLatestRelease(getLatestRelease(releases));
90
+ const { latestRepos, latestVersions } = latestRelease.repos.reduce((accu, item) => {
91
+ if (repoKeyMap[item.name]) accu.latestVersions[repoKeyMap[item.name]] = getComparisonCompatibleVersion(item.version);
92
+ accu.latestRepos[item.name] = getComparisonCompatibleVersion(item.version);
93
+ return accu;
94
+ }, {
95
+ latestVersions: { ...getState().app.versionInformation },
96
+ latestRepos: {}
97
+ });
98
+ const info = deductSaasState(latestRelease, guiTags);
99
+ return dispatch(actions.setVersionInformation({
100
+ ...latestVersions,
101
+ Server: info,
102
+ latestRelease: {
103
+ releaseDate: latestRelease.release_date,
104
+ repos: latestRepos
105
+ }
106
+ }));
107
+ });
108
+ const setSearchState = createAppAsyncThunk(`app/setSearchState`, (searchState, { dispatch, getState }) => {
109
+ const currentState = getSearchState(getState());
110
+ const nextState = {
111
+ ...currentState,
112
+ ...searchState,
113
+ sort: {
114
+ ...currentState.sort,
115
+ ...searchState.sort
116
+ }
117
+ };
118
+ const tasks = [];
119
+ const { isSearching: currentSearching, deviceIds: currentDevices, searchTotal: currentTotal, ...currentRequestState } = currentState;
120
+ const { isSearching: nextSearching, deviceIds: nextDevices, searchTotal: nextTotal, ...nextRequestState } = nextState;
121
+ if (nextRequestState.searchTerm && !deepCompare(currentRequestState, nextRequestState)) {
122
+ nextState.isSearching = true;
123
+ tasks.push(dispatch(searchDevices(nextState)).unwrap().then((searchResult) => dispatch(actions.setSearchState({
124
+ ...searchResult,
125
+ isSearching: false
126
+ }))).catch(() => dispatch(actions.setSearchState({
127
+ isSearching: false,
128
+ searchTotal: 0
129
+ }))));
130
+ }
131
+ tasks.push(Promise.resolve(dispatch(actions.setSearchState(nextState))));
132
+ return Promise.all(tasks);
133
+ });
134
+ //#endregion
135
+ //#region src/deploymentsSlice/thunks.ts
136
+ const { isUUID } = validator;
137
+ const { receivedDevice, setSnackbar: setSnackbar$3 } = actions_default;
138
+ const { page: defaultPage$2, perPage: defaultPerPage$2 } = DEVICE_LIST_DEFAULTS;
139
+ const deriveDeploymentGroup = ({ filter, group, groups = [], name }) => group || groups.length === 1 && !isUUID(name) ? groups[0] : filter?.name;
140
+ const transformDeployments = (deployments, deploymentsById) => deployments.sort(customSort(true, "created")).reduce((accu, item) => {
141
+ const filter = item.filter;
142
+ let deployment = {
143
+ ...deploymentPrototype,
144
+ ...deploymentsById[item.id],
145
+ ...item,
146
+ filter: filter ? {
147
+ ...filter,
148
+ name: filter.name ?? filter.id,
149
+ filters: mapTermsToFilters(filter.terms)
150
+ } : void 0,
151
+ name: decodeURIComponent(item.name)
152
+ };
153
+ deployment = {
154
+ ...deployment,
155
+ group: deriveDeploymentGroup(deployment)
156
+ };
157
+ accu.deployments[item.id] = deployment;
158
+ accu.deploymentIds.push(item.id);
159
+ return accu;
160
+ }, {
161
+ deployments: {},
162
+ deploymentIds: []
163
+ });
164
+ const getDeploymentsByStatus = createAppAsyncThunk(`${sliceName$1}/getDeploymentsByStatus`, (options, { dispatch, getState }) => {
165
+ const { status, page = defaultPage$2, perPage = defaultPerPage$2, startDate, endDate, group, type, shouldSelect = true, sort = SORTING_OPTIONS.desc } = options;
166
+ const created_after = startDate ? `&created_after=${startDate}` : "";
167
+ const created_before = endDate ? `&created_before=${endDate}` : "";
168
+ const { attribute, scope } = getIdAttribute(getState());
169
+ const attributeHint = `&id_attribute=${attribute}&id_scope=${scope}`;
170
+ const search = group ? `&name=${group}${attributeHint}` : "";
171
+ const typeFilter = type ? `&type=${type}` : "";
172
+ return Api.get(`${deploymentsApiUrlV2}/deployments?status=${status}&per_page=${perPage}&page=${page}${created_after}${created_before}${search}${typeFilter}&sort=${sort}`).then((res) => {
173
+ const { deployments, deploymentIds } = transformDeployments(res.data, getState().deployments.byId);
174
+ const total = Number(res.headers[headerNames.total]);
175
+ const tasks = [Promise.resolve(dispatch(actions$1.receivedDeployments(deployments))), Promise.resolve(dispatch(actions$1.receivedDeploymentsForStatus({
176
+ deploymentIds,
177
+ status,
178
+ total: !(startDate || endDate || group || type) ? total : getState().deployments.byStatus[status].total
179
+ })))];
180
+ deploymentIds.forEach((deploymentId) => {
181
+ if (deployments[deploymentId].type === DEPLOYMENT_TYPES.configuration) tasks.push(dispatch(getSingleDeployment(deploymentId)).unwrap());
182
+ });
183
+ if (shouldSelect) tasks.push(Promise.resolve(dispatch(actions$1.selectDeploymentsForStatus({
184
+ deploymentIds,
185
+ status,
186
+ total
187
+ }))));
188
+ tasks.push(Promise.resolve({
189
+ deploymentIds,
190
+ total
191
+ }));
192
+ return Promise.all(tasks);
193
+ });
194
+ });
195
+ const isWithinFirstMonth = (expirationDate) => {
196
+ if (!expirationDate) return false;
197
+ const endOfFirstMonth = new Date(expirationDate);
198
+ endOfFirstMonth.setMonth(endOfFirstMonth.getMonth() - 11);
199
+ return endOfFirstMonth > /* @__PURE__ */ new Date();
200
+ };
201
+ const trackDeploymentCreation = (totalDeploymentCount, hasDeployments, trial_expiration) => {
202
+ Tracking.event({
203
+ category: "deployments",
204
+ action: "create"
205
+ });
206
+ if (!totalDeploymentCount) {
207
+ if (!hasDeployments) {
208
+ Tracking.event({
209
+ category: "deployments",
210
+ action: "create_initial_deployment"
211
+ });
212
+ if (isWithinFirstMonth(trial_expiration)) Tracking.event({
213
+ category: "deployments",
214
+ action: "create_initial_deployment_first_month"
215
+ });
216
+ }
217
+ Tracking.event({
218
+ category: "deployments",
219
+ action: "create_initial_deployment_user"
220
+ });
221
+ }
222
+ };
223
+ const MAX_PREVIOUS_PHASES_COUNT = 5;
224
+ const createDeployment = createAppAsyncThunk(`${sliceName$1}/createDeployment`, ({ newDeployment, hasNewRetryDefault = false }, { dispatch, getState }) => {
225
+ let request;
226
+ if ("filter_id" in newDeployment && newDeployment.filter_id) request = Api.post(`${deploymentsApiUrlV2}/deployments`, newDeployment);
227
+ else if ("group" in newDeployment && newDeployment.group) request = Api.post(`${deploymentsApiUrl}/deployments/group/${newDeployment.group}`, newDeployment);
228
+ else request = Api.post(`${deploymentsApiUrl}/deployments`, newDeployment);
229
+ const totalDeploymentCount = Object.values(getDeploymentsByStatus$1(getState())).reduce((accu, item) => accu + item.total, 0);
230
+ const { hasDeployments } = getGlobalSettings$1(getState());
231
+ const { trial_expiration } = getOrganization(getState());
232
+ return request.catch((err) => commonErrorHandler(err, "Error creating deployment.", dispatch)).then((data) => {
233
+ const lastslashindex = data.headers.location.lastIndexOf("/");
234
+ const deploymentId = data.headers.location.substring(lastslashindex + 1);
235
+ const deployment = {
236
+ ...newDeployment,
237
+ id: deploymentId,
238
+ devices: "devices" in newDeployment && newDeployment.devices ? newDeployment.devices.map((id) => ({
239
+ id,
240
+ status: "pending"
241
+ })) : [],
242
+ statistics: { status: {} }
243
+ };
244
+ const tasks = [
245
+ Promise.resolve(dispatch(actions$1.createdDeployment(deployment))),
246
+ dispatch(getSingleDeployment(deploymentId)),
247
+ Promise.resolve(dispatch(setSnackbar$3({
248
+ message: "Deployment created successfully",
249
+ autoHideDuration: TIMEOUTS.fiveSeconds
250
+ })))
251
+ ];
252
+ trackDeploymentCreation(totalDeploymentCount, hasDeployments, trial_expiration);
253
+ const { canManageUsers } = getUserCapabilities(getState());
254
+ if (canManageUsers) {
255
+ const { phases, retries } = newDeployment;
256
+ const { previousPhases = [], retries: previousRetries = 0 } = getGlobalSettings$1(getState());
257
+ const newSettings = {
258
+ retries: hasNewRetryDefault ? retries : previousRetries,
259
+ hasDeployments: true
260
+ };
261
+ if (phases) {
262
+ const standardPhases = standardizePhases(phases);
263
+ const prevPhases = previousPhases.map(standardizePhases);
264
+ if (!prevPhases.find((previousPhaseList) => previousPhaseList.every((oldPhase) => standardPhases.find((phase) => deepCompare(phase, oldPhase))))) prevPhases.push(standardPhases);
265
+ newSettings.previousPhases = prevPhases.slice(-1 * MAX_PREVIOUS_PHASES_COUNT);
266
+ }
267
+ tasks.push(dispatch(saveGlobalSettings(newSettings)));
268
+ }
269
+ return Promise.all(tasks);
270
+ });
271
+ });
272
+ const getDeploymentDevices = createAppAsyncThunk(`${sliceName$1}/getDeploymentDevices`, (options, { dispatch, getState }) => {
273
+ const { id, page = defaultPage$2, perPage = defaultPerPage$2 } = options;
274
+ return Api.get(`${deploymentsApiUrl}/deployments/${id}/devices/list?&page=${page}&per_page=${perPage}`).then((response) => {
275
+ const { devices: deploymentDevices = {} } = getState().deployments.byId[id] || {};
276
+ const devices = response.data.reduce((accu, item) => {
277
+ accu[item.id] = item;
278
+ const log = (deploymentDevices[item.id] || {}).log;
279
+ if (log) accu[item.id].log = log;
280
+ return accu;
281
+ }, {});
282
+ const selectedDeviceIds = Object.keys(devices);
283
+ const tasks = [Promise.resolve(dispatch(actions$1.receivedDeploymentDevices({
284
+ id,
285
+ devices,
286
+ selectedDeviceIds,
287
+ totalDeviceCount: Number(response.headers[headerNames.total])
288
+ })))];
289
+ const devicesById = getDevicesById(getState());
290
+ selectedDeviceIds.reduce((accu, deviceId) => {
291
+ const device = devicesById[deviceId];
292
+ if (!device || !device.identity_data || !device.attributes || Object.keys(device.attributes).length === 0) accu.push(deviceId);
293
+ return accu;
294
+ }, []).forEach((deviceId) => {
295
+ tasks.push(dispatch(getDeviceById(deviceId)).unwrap(), dispatch(getDeviceAuth(deviceId)).unwrap());
296
+ });
297
+ return Promise.all(tasks);
298
+ });
299
+ });
300
+ const parseDeviceDeployment = ({ deployment: { id, artifact_name: release, status: deploymentStatus }, device: { created, deleted, id: deviceId, finished, status, log } }) => ({
301
+ id,
302
+ release,
303
+ created,
304
+ deleted,
305
+ deviceId,
306
+ finished,
307
+ status,
308
+ log,
309
+ route: Object.values(DEPLOYMENT_ROUTES).reduce((accu, { key, states }) => {
310
+ if (!accu) return states.includes(deploymentStatus) ? key : accu;
311
+ return accu;
312
+ }, "")
313
+ });
314
+ const getDeviceDeployments = createAppAsyncThunk(`${sliceName$1}/getDeviceDeployments`, (options, { dispatch }) => {
315
+ const { deviceId, filterSelection = [], page = defaultPage$2, perPage = defaultPerPage$2 } = options;
316
+ const filters = filterSelection.map((item) => `&status=${item}`).join("");
317
+ return Api.get(`${deploymentsApiUrl}/deployments/devices/${deviceId}?page=${page}&per_page=${perPage}${filters}`).then(({ data, headers }) => Promise.resolve(dispatch(receivedDevice({
318
+ id: deviceId,
319
+ deviceDeployments: data.map(parseDeviceDeployment),
320
+ deploymentsCount: Number(headers[headerNames.total])
321
+ })))).catch((err) => commonErrorHandler(err, "There was an error retrieving the device deployment history:", dispatch));
322
+ });
323
+ const resetDeviceDeployments = createAppAsyncThunk(`${sliceName$1}/resetDeviceDeployments`, (deviceId, { dispatch }) => Api.delete(`${deploymentsApiUrl}/deployments/devices/${deviceId}/history`).then(() => Promise.resolve(dispatch(getDeviceDeployments({ deviceId })))).catch((err) => commonErrorHandler(err, "There was an error resetting the device deployment history:", dispatch)));
324
+ const getSingleDeployment = createAppAsyncThunk(`${sliceName$1}/getSingleDeployment`, (id, { dispatch, getState }) => Api.get(`${deploymentsApiUrl}/deployments/${id}`).then(({ data }) => {
325
+ const { deployments } = transformDeployments([data], getState().deployments.byId);
326
+ return Promise.resolve(dispatch(actions$1.receivedDeployment(deployments[id])));
327
+ }));
328
+ const getDeviceLog = createAppAsyncThunk(`${sliceName$1}/getDeviceLog`, ({ deploymentId, deviceId }, { dispatch }) => Api.get(`${deploymentsApiUrl}/deployments/${deploymentId}/devices/${deviceId}/log`).catch((e) => {
329
+ console.log("no log here", e);
330
+ return Promise.reject();
331
+ }).then(({ data: log }) => Promise.all([Promise.resolve(dispatch(actions$1.receivedDeploymentDeviceLog({
332
+ id: deploymentId,
333
+ deviceId,
334
+ log
335
+ }))), Promise.resolve(log)])));
336
+ const abortDeployment = createAppAsyncThunk(`${sliceName$1}/abortDeployment`, (deploymentId, { dispatch, getState }) => Api.put(`${deploymentsApiUrl}/deployments/${deploymentId}/status`, { status: "aborted" }).then(() => {
337
+ const deploymentsByStatus = getDeploymentsByStatus$1(getState());
338
+ let status = DEPLOYMENT_STATES.pending;
339
+ let index = deploymentsByStatus.pending.deploymentIds.findIndex((id) => id === deploymentId);
340
+ if (index < 0) {
341
+ status = DEPLOYMENT_STATES.inprogress;
342
+ index = deploymentsByStatus.inprogress.deploymentIds.findIndex((id) => id === deploymentId);
343
+ }
344
+ const deploymentIds = [...deploymentsByStatus[status].deploymentIds.slice(0, index), ...deploymentsByStatus[status].deploymentIds.slice(index + 1)];
345
+ const deploymentsById = getDeploymentsById(getState());
346
+ const deployments = deploymentIds.reduce((accu, id) => {
347
+ accu[id] = deploymentsById[id];
348
+ return accu;
349
+ }, {});
350
+ const total = Math.max(deploymentsByStatus[status].total - 1, 0);
351
+ return Promise.all([
352
+ dispatch(actions$1.receivedDeployments(deployments)),
353
+ dispatch(actions$1.receivedDeploymentsForStatus({
354
+ deploymentIds,
355
+ status,
356
+ total
357
+ })),
358
+ dispatch(actions$1.removedDeployment(deploymentId)),
359
+ dispatch(setSnackbar$3("The deployment was successfully aborted"))
360
+ ]);
361
+ }).catch((err) => commonErrorHandler(err, "There was an error while aborting the deployment:", dispatch)));
362
+ const updateDeploymentControlMap = createAppAsyncThunk(`${sliceName$1}/updateDeploymentControlMap`, ({ deploymentId, updateControlMap }, { dispatch }) => Api.patch(`${deploymentsApiUrl}/deployments/${deploymentId}`, { update_control_map: updateControlMap }).catch((err) => commonErrorHandler(err, "There was an error while updating the deployment status:", dispatch)).then(() => Promise.resolve(dispatch(getSingleDeployment(deploymentId)))));
363
+ const setDeploymentsState = createAppAsyncThunk(`${sliceName$1}/setDeploymentsState`, (selection, { dispatch, getState }) => {
364
+ const { page, perPage, ...selectionState } = selection;
365
+ const currentState = getState().deployments.selectionState;
366
+ const nextState = {
367
+ ...currentState,
368
+ ...selectionState,
369
+ ...Object.keys(DEPLOYMENT_STATES).reduce((accu, item) => {
370
+ accu[item] = {
371
+ ...currentState[item],
372
+ ...selectionState[item]
373
+ };
374
+ return accu;
375
+ }, {}),
376
+ general: {
377
+ ...currentState.general,
378
+ ...selectionState.general
379
+ }
380
+ };
381
+ const tasks = [Promise.resolve(dispatch(actions$1.setDeploymentsState(nextState)))];
382
+ if (nextState.selectedId && currentState.selectedId !== nextState.selectedId) tasks.push(dispatch(getSingleDeployment(nextState.selectedId)));
383
+ return Promise.all(tasks);
384
+ });
385
+ const deltaAttributeMappings = [
386
+ {
387
+ here: "compressionLevel",
388
+ there: "compression_level"
389
+ },
390
+ {
391
+ here: "disableChecksum",
392
+ there: "disable_checksum"
393
+ },
394
+ {
395
+ here: "disableDecompression",
396
+ there: "disable_external_decompression"
397
+ },
398
+ {
399
+ here: "sourceWindow",
400
+ there: "source_window_size"
401
+ },
402
+ {
403
+ here: "inputWindow",
404
+ there: "input_window_size"
405
+ },
406
+ {
407
+ here: "duplicatesWindow",
408
+ there: "compression_duplicates_window"
409
+ },
410
+ {
411
+ here: "instructionBuffer",
412
+ there: "instruction_buffer_size"
413
+ }
414
+ ];
415
+ const mapExternalDeltaConfig = (config = {}) => deltaAttributeMappings.reduce((accu, { here, there }) => {
416
+ if (config[there] !== void 0) accu[here] = config[there];
417
+ return accu;
418
+ }, {});
419
+ const getDeploymentsConfig = createAppAsyncThunk(`${sliceName$1}/getDeploymentsConfig`, (_, { dispatch, getState }) => Api.get(`${deploymentsApiUrl}/config`).then(({ data }) => {
420
+ const oldConfig = getState().deployments.config;
421
+ const { delta = {} } = data;
422
+ const { binary_delta = {}, binary_delta_limits = {} } = delta;
423
+ const { xdelta_args = {} } = binary_delta;
424
+ const { xdelta_args_limits = {} } = binary_delta_limits;
425
+ const config = {
426
+ ...oldConfig,
427
+ hasDelta: Boolean(delta.enabled),
428
+ binaryDelta: {
429
+ ...oldConfig.binaryDelta,
430
+ ...mapExternalDeltaConfig(xdelta_args)
431
+ },
432
+ binaryDeltaLimits: {
433
+ ...oldConfig.binaryDeltaLimits,
434
+ ...mapExternalDeltaConfig(xdelta_args_limits)
435
+ }
436
+ };
437
+ return Promise.resolve(dispatch(actions$1.setDeploymentsConfig(config)));
438
+ }));
439
+ const deepClean = (source) => Object.entries(source).reduce((accu, [key, value]) => {
440
+ if (value !== void 0) {
441
+ const cleanedValue = typeof value === "object" ? deepClean(value) : value;
442
+ if (cleanedValue === void 0 || typeof cleanedValue === "object" && isEmpty(cleanedValue)) return accu;
443
+ accu = {
444
+ ...accu ?? {},
445
+ [key]: cleanedValue
446
+ };
447
+ }
448
+ return accu;
449
+ }, void 0);
450
+ const saveDeltaDeploymentsConfig = createAppAsyncThunk(`${sliceName$1}/saveDeltaDeploymentsConfig`, (config, { dispatch, getState }) => {
451
+ const result = deepClean({ xdelta_args: deltaAttributeMappings.reduce((accu, { here, there }) => {
452
+ if (config[here] !== void 0) accu[there] = config[here];
453
+ return accu;
454
+ }, {}) });
455
+ if (!result) return Promise.resolve();
456
+ return Api.put(`${deploymentsApiUrl}/config/binary_delta`, result).catch((err) => commonErrorHandler(err, "There was a problem storing your delta artifact generation configuration.", dispatch)).then(() => {
457
+ const oldConfig = getState().deployments.config;
458
+ const newConfig = {
459
+ ...oldConfig,
460
+ binaryDelta: {
461
+ ...oldConfig.binaryDelta,
462
+ ...config
463
+ }
464
+ };
465
+ return Promise.all([dispatch(actions$1.setDeploymentsConfig(newConfig)), dispatch(setSnackbar$3("Settings saved successfully"))]);
466
+ });
467
+ });
468
+ const generateDeploymentLogAnalysis = createAppAsyncThunk(`${sliceName$1}/generateDeploymentLogAnalysis`, ({ deploymentId, deviceId }, { dispatch, rejectWithValue }) => Api.get(`${apiRoot}/v1alpha1/deployments/deployments/${deploymentId}/devices/${deviceId}/log/explain`, { timeout: 60 * TIMEOUTS.oneSecond }).then(({ data: result }) => Promise.resolve(result)).catch((err) => {
469
+ if (err.response.status === 429) return rejectWithValue(err.response);
470
+ commonErrorHandler(err, "There was an error analysing the deployment log:", dispatch);
471
+ }));
472
+ //#endregion
473
+ //#region src/devicesSlice/thunks.tsx
474
+ const { cleanUpUpload, initUpload, setSnackbar: setSnackbar$2, uploadProgress } = actions_default;
475
+ const { page: defaultPage$1, perPage: defaultPerPage$1 } = DEVICE_LIST_DEFAULTS;
476
+ const defaultAttributes = [
477
+ {
478
+ scope: "identity",
479
+ attribute: "status"
480
+ },
481
+ {
482
+ scope: "inventory",
483
+ attribute: "artifact_name"
484
+ },
485
+ {
486
+ scope: "inventory",
487
+ attribute: "device_type"
488
+ },
489
+ {
490
+ scope: "inventory",
491
+ attribute: "mender_is_gateway"
492
+ },
493
+ {
494
+ scope: "inventory",
495
+ attribute: "mender_gateway_system_id"
496
+ },
497
+ {
498
+ scope: "inventory",
499
+ attribute: rootfsImageVersion
500
+ },
501
+ {
502
+ scope: "monitor",
503
+ attribute: "alerts"
504
+ },
505
+ {
506
+ scope: "system",
507
+ attribute: "created_ts"
508
+ },
509
+ {
510
+ scope: "system",
511
+ attribute: "updated_ts"
512
+ },
513
+ {
514
+ scope: "system",
515
+ attribute: "check_in_time"
516
+ },
517
+ {
518
+ scope: "system",
519
+ attribute: "group"
520
+ },
521
+ {
522
+ scope: "tags",
523
+ attribute: "name"
524
+ }
525
+ ];
526
+ const getGroups = createAppAsyncThunk(`${sliceName$2}/getGroups`, async (_, { dispatch, getState }) => {
527
+ const res = await Api.get(`${inventoryApiUrl}/groups`);
528
+ const state = getGroupsById(getState());
529
+ const dynamicGroups = Object.entries(state).reduce((accu, [id, group]) => {
530
+ if (group.id || group.filters?.length && id !== UNGROUPED_GROUP.id) accu[id] = group;
531
+ return accu;
532
+ }, {});
533
+ const groups = res.data.reduce((accu, group) => {
534
+ accu[group] = {
535
+ deviceIds: [],
536
+ filters: [],
537
+ total: 0,
538
+ ...state[group]
539
+ };
540
+ return accu;
541
+ }, dynamicGroups);
542
+ const filters = [{
543
+ key: "group",
544
+ value: res.data,
545
+ operator: DEVICE_FILTERING_OPTIONS.$nin.key,
546
+ scope: "system"
547
+ }];
548
+ const [, devicesRetrieval] = await Promise.all([dispatch(actions$2.receivedGroups(groups)), dispatch(getDevicesByStatus({
549
+ filterSelection: filters,
550
+ group: "",
551
+ page: 1,
552
+ perPage: 1,
553
+ status: void 0
554
+ }))]);
555
+ const { total } = devicesRetrieval?.payload ?? {};
556
+ if (!total) return;
557
+ return dispatch(actions$2.addGroup({
558
+ groupName: UNGROUPED_GROUP.id,
559
+ group: { filters: [{
560
+ key: "group",
561
+ value: res.data,
562
+ operator: DEVICE_FILTERING_OPTIONS.$nin.key,
563
+ scope: "system"
564
+ }] }
565
+ }));
566
+ });
567
+ const addDevicesToGroup = createAppAsyncThunk(`${sliceName$2}/addDevicesToGroup`, ({ group, deviceIds, isCreation }, { dispatch }) => Api.patch(`${inventoryApiUrl}/groups/${group}/devices`, deviceIds).then(() => dispatch(actions$2.addToGroup({
568
+ group,
569
+ deviceIds
570
+ }))).finally(() => isCreation ? Promise.resolve(dispatch(getGroups())) : {}));
571
+ const removeDevicesFromGroup = createAppAsyncThunk(`${sliceName$2}/removeDevicesFromGroup`, ({ group, deviceIds }, { dispatch }) => Api.delete(`${inventoryApiUrl}/groups/${group}/devices`, deviceIds).then(() => Promise.all([dispatch(actions$2.removeFromGroup({
572
+ group,
573
+ deviceIds
574
+ })), dispatch(setSnackbar$2({
575
+ message: `The ${pluralize("devices", deviceIds.length)} ${pluralize("were", deviceIds.length)} removed from the group`,
576
+ autoHideDuration: TIMEOUTS.fiveSeconds
577
+ }))])));
578
+ const getGroupNotification = (newGroup, selectedGroup) => {
579
+ const successMessage = "The group was updated successfully";
580
+ if (newGroup === selectedGroup) return {
581
+ message: successMessage,
582
+ autoHideDuration: TIMEOUTS.fiveSeconds
583
+ };
584
+ return {
585
+ action: "",
586
+ autoHideDuration: TIMEOUTS.fiveSeconds,
587
+ message: /* @__PURE__ */ jsxs(Fragment, { children: [
588
+ successMessage,
589
+ " - ",
590
+ /* @__PURE__ */ jsx(Link, {
591
+ to: `/devices?inventory=group:eq:${newGroup}`,
592
+ children: "click here"
593
+ }),
594
+ " to see it."
595
+ ] }),
596
+ preventClickToCopy: true
597
+ };
598
+ };
599
+ const addStaticGroup = createAppAsyncThunk(`${sliceName$2}/addStaticGroup`, ({ group, devices }, { dispatch, getState }) => Promise.resolve(dispatch(addDevicesToGroup({
600
+ group,
601
+ deviceIds: devices.map(({ id }) => id),
602
+ isCreation: true
603
+ }))).then(() => Promise.resolve(dispatch(actions$2.addGroup({
604
+ group: {
605
+ deviceIds: [],
606
+ total: 0,
607
+ filters: [],
608
+ ...getState().devices.groups.byId[group]
609
+ },
610
+ groupName: group
611
+ }))).then(() => Promise.all([
612
+ dispatch(setDeviceListState({ setOnly: true })),
613
+ dispatch(getGroups()),
614
+ dispatch(setSnackbar$2(getGroupNotification(group, getState().devices.groups.selectedGroup)))
615
+ ]))).catch((err) => commonErrorHandler(err, `Group could not be updated:`, dispatch)));
616
+ const removeReportsByGroupName = createAppAsyncThunk(`${sliceName$2}/removeReportsByGroupName`, (groupName, { dispatch, getState }) => {
617
+ if (!groupName) return Promise.resolve();
618
+ dispatch(saveUserSettings({ reports: getDeviceReportsForUser(getState()).filter((report) => report.group !== groupName) }));
619
+ });
620
+ const removeStaticGroup = createAppAsyncThunk(`${sliceName$2}/removeStaticGroup`, (groupName, { dispatch }) => Api.delete(`${inventoryApiUrl}/groups/${groupName}`).then(() => Promise.all([
621
+ dispatch(actions$2.removeGroup(groupName)),
622
+ dispatch(removeReportsByGroupName(groupName)),
623
+ dispatch(getGroups()),
624
+ dispatch(setSnackbar$2({
625
+ message: "Group was removed successfully",
626
+ autoHideDuration: TIMEOUTS.fiveSeconds
627
+ }))
628
+ ])));
629
+ const getDynamicGroup = createAppAsyncThunk(`${sliceName$2}/getDynamicGroupById`, (id, { dispatch }) => Api.get(`${inventoryApiUrlV2}/filters/${id}`).catch((err) => {
630
+ if (err.response && err.response.status === 404) throw new Error("Request failed with status code 404");
631
+ return commonErrorHandler(err, `Error retrieving the group: `, dispatch, commonErrorFallback);
632
+ }));
633
+ const getDynamicGroups = createAppAsyncThunk(`${sliceName$2}/getDynamicGroups`, (_, { dispatch, getState }) => Api.get(`${inventoryApiUrlV2}/filters?per_page=500`).then(({ data: filters }) => {
634
+ const state = getGroupsById(getState());
635
+ const staticGroups = Object.entries(state).reduce((accu, [id, group]) => {
636
+ if (!(group.id || group.filters?.length)) accu[id] = group;
637
+ return accu;
638
+ }, {});
639
+ const groups = (filters || []).reduce((accu, filter) => {
640
+ accu[filter.name] = {
641
+ deviceIds: [],
642
+ total: 0,
643
+ ...state[filter.name],
644
+ id: filter.id,
645
+ filters: mapTermsToFilters(filter.terms)
646
+ };
647
+ return accu;
648
+ }, staticGroups);
649
+ return Promise.resolve(dispatch(actions$2.receivedGroups(groups)));
650
+ }).catch(() => console.log("Dynamic group retrieval failed - likely accessing a non-enterprise backend")));
651
+ const addDynamicGroup = createAppAsyncThunk(`${sliceName$2}/addDynamicGroup`, ({ groupName, filterPredicates }, { dispatch, getState }) => Api.post(`${inventoryApiUrlV2}/filters`, {
652
+ name: groupName,
653
+ terms: mapFiltersToTerms(filterPredicates)
654
+ }).then((res) => Promise.resolve(dispatch(actions$2.addGroup({
655
+ groupName,
656
+ group: {
657
+ id: res.headers[headerNames.location].substring(res.headers[headerNames.location].lastIndexOf("/") + 1),
658
+ filters: filterPredicates
659
+ }
660
+ }))).then(() => {
661
+ const { cleanedFilters } = getGroupFilters(groupName, getState().devices.groups);
662
+ return Promise.all([
663
+ dispatch(actions$2.setDeviceFilters(cleanedFilters)),
664
+ dispatch(setSnackbar$2(getGroupNotification(groupName, getState().devices.groups.selectedGroup))),
665
+ dispatch(getDynamicGroups())
666
+ ]);
667
+ })).catch((err) => commonErrorHandler(err, `Group could not be updated:`, dispatch)));
668
+ const updateDynamicGroup = createAppAsyncThunk(`${sliceName$2}/updateDynamicGroup`, ({ groupName, filterPredicates }, { dispatch, getState }) => {
669
+ const filterId = getState().devices.groups.byId[groupName].id;
670
+ return Api.delete(`${inventoryApiUrlV2}/filters/${filterId}`).then(() => dispatch(addDynamicGroup({
671
+ groupName,
672
+ filterPredicates
673
+ })).unwrap());
674
+ });
675
+ const removeDynamicGroup = createAppAsyncThunk(`${sliceName$2}/removeDynamicGroup`, (groupName, { dispatch, getState }) => {
676
+ const filterId = getState().devices.groups.byId[groupName].id;
677
+ return Api.delete(`${inventoryApiUrlV2}/filters/${filterId}`).then(() => Promise.all([
678
+ dispatch(actions$2.removeGroup(groupName)),
679
+ dispatch(removeReportsByGroupName(groupName)),
680
+ dispatch(setSnackbar$2({
681
+ message: "Group was removed successfully",
682
+ autoHideDuration: TIMEOUTS.fiveSeconds
683
+ }))
684
+ ]));
685
+ });
686
+ const getGroupFilters = (group, groupsState, filters = []) => {
687
+ const groupName = group === UNGROUPED_GROUP.id || group === UNGROUPED_GROUP.name ? UNGROUPED_GROUP.id : group;
688
+ const selectedGroup = groupsState.byId[groupName];
689
+ const groupFilterLength = selectedGroup?.filters?.length || 0;
690
+ return {
691
+ cleanedFilters: groupFilterLength ? [...filters, ...selectedGroup.filters || []].filter(filtersFilter) : filters,
692
+ groupName,
693
+ selectedGroup,
694
+ groupFilterLength
695
+ };
696
+ };
697
+ const selectGroup = createAppAsyncThunk(`${sliceName$2}/selectGroup`, ({ group, filters = [] }, { dispatch, getState }) => {
698
+ const { cleanedFilters, groupName, selectedGroup, groupFilterLength } = getGroupFilters(group, getState().devices.groups, filters);
699
+ if (getSelectedGroup(getState()) === groupName && (filters.length === 0 && !groupFilterLength || filters.length === cleanedFilters.length)) return Promise.resolve();
700
+ const tasks = [];
701
+ if (groupFilterLength) tasks.push(Promise.resolve(dispatch(actions$2.setDeviceFilters(cleanedFilters))));
702
+ else {
703
+ tasks.push(Promise.resolve(dispatch(actions$2.setDeviceFilters(filters))));
704
+ tasks.push(dispatch(getGroupDevices({
705
+ group: groupName,
706
+ perPage: 1,
707
+ shouldIncludeAllStates: true
708
+ })));
709
+ }
710
+ const selectedGroupName = selectedGroup || !Object.keys(getGroupsById(getState())).length ? groupName : void 0;
711
+ tasks.push(Promise.resolve(dispatch(actions$2.selectGroup(selectedGroupName))));
712
+ return Promise.all(tasks);
713
+ });
714
+ const getEarliestTs = (dateA = "", dateB = "") => !dateA || !dateB ? dateA || dateB : dateA < dateB ? dateA : dateB;
715
+ const reduceReceivedDevices = (devices, ids, state, status) => devices.reduce((accu, device) => {
716
+ const stateDevice = getDeviceById$1(state, device.id);
717
+ const { attributes: storedAttributes = {}, identity_data: storedIdentity = {}, monitor: storedMonitor = {}, tags: storedTags = {}, group: storedGroup } = stateDevice;
718
+ const { identity, inventory, monitor, system = {}, tags } = mapDeviceAttributes(device.attributes);
719
+ device.tags = {
720
+ ...storedTags,
721
+ ...tags
722
+ };
723
+ device.group = system.group ?? storedGroup;
724
+ device.monitor = {
725
+ ...storedMonitor,
726
+ ...monitor
727
+ };
728
+ device.identity_data = {
729
+ ...storedIdentity,
730
+ ...identity,
731
+ ...device.identity_data ? device.identity_data : {}
732
+ };
733
+ device.status = status ? status : device.status || identity.status;
734
+ device.check_in_time_rounded = system.check_in_time ?? stateDevice.check_in_time_rounded;
735
+ device.check_in_time_exact = device.check_in_time ?? stateDevice.check_in_time_exact;
736
+ device.created_ts = getEarliestTs(getEarliestTs(system.created_ts, device.created_ts), stateDevice.created_ts);
737
+ device.updated_ts = device.attributes ? device.updated_ts : stateDevice.updated_ts;
738
+ device.isNew = new Date(device.created_ts) > new Date(state.app.newThreshold);
739
+ device.isOffline = new Date(device.check_in_time_rounded) < new Date(state.app.offlineThreshold) || device.check_in_time_rounded === void 0;
740
+ device.attributes = device.attributes ? {
741
+ ...storedAttributes,
742
+ ...inventory
743
+ } : storedAttributes;
744
+ accu.devicesById[device.id] = {
745
+ ...stateDevice,
746
+ ...device
747
+ };
748
+ accu.ids.push(device.id);
749
+ return accu;
750
+ }, {
751
+ ids,
752
+ devicesById: {}
753
+ });
754
+ const getGroupDevices = createAppAsyncThunk(`${sliceName$2}/getGroupDevices`, async (options, { dispatch, getState }) => {
755
+ const { group, shouldIncludeAllStates, ...remainder } = options;
756
+ const { cleanedFilters: filterSelection } = getGroupFilters(group, getState().devices.groups);
757
+ const { deviceAccu, total } = await dispatch(getDevicesByStatus({
758
+ ...remainder,
759
+ filterSelection,
760
+ group,
761
+ status: shouldIncludeAllStates ? void 0 : DEVICE_STATES.accepted
762
+ })).unwrap();
763
+ if (!group) return;
764
+ const stateGroup = getState().devices.groups.byId[group];
765
+ if (!stateGroup && !total && !deviceAccu.ids.length) return;
766
+ return dispatch(actions$2.addGroup({
767
+ group: {
768
+ deviceIds: deviceAccu.ids.length === total || stateGroup && stateGroup.deviceIds && deviceAccu.ids.length > stateGroup.deviceIds.length ? deviceAccu.ids : stateGroup.deviceIds,
769
+ total
770
+ },
771
+ groupName: group
772
+ }));
773
+ });
774
+ const getAllGroupDevices = createAppAsyncThunk(`${sliceName$2}/getAllGroupDevices`, ({ group, attribute }, { dispatch, getState }) => {
775
+ if (!group || !!group && (!getGroupsById(getState())[group] || getGroupsById(getState())[group].filters.length)) return Promise.resolve();
776
+ const { attributes, filterTerms } = prepareSearchArguments({
777
+ filters: [],
778
+ group,
779
+ state: getState(),
780
+ status: DEVICE_STATES.accepted
781
+ });
782
+ const getAllDevices = (perPage = 500, page = defaultPage$1, devices = []) => Api.post(`${inventoryApiUrlV2}/filters/search`, {
783
+ page,
784
+ per_page: perPage,
785
+ filters: filterTerms,
786
+ attributes: [...attributes, {
787
+ scope: "inventory",
788
+ attribute
789
+ }]
790
+ }).then((res) => {
791
+ const state = getState();
792
+ const deviceAccu = reduceReceivedDevices(res.data, devices, state);
793
+ dispatch(actions$2.receivedDevices(deviceAccu.devicesById));
794
+ if (Number(res.headers[headerNames.total]) > perPage * page) return getAllDevices(perPage, page + 1, deviceAccu.ids);
795
+ return Promise.resolve(dispatch(actions$2.addGroup({
796
+ group: {
797
+ deviceIds: deviceAccu.ids,
798
+ total: deviceAccu.ids.length
799
+ },
800
+ groupName: group
801
+ })));
802
+ });
803
+ return getAllDevices();
804
+ });
805
+ const getAllDynamicGroupDevices = createAppAsyncThunk(`${sliceName$2}/getAllDynamicGroupDevices`, ({ group, attribute }, { dispatch, getState }) => {
806
+ if (!!group && (!getGroupsById(getState())[group] || !getGroupsById(getState())[group].filters.length)) return Promise.resolve();
807
+ const { attributes, filterTerms: filters } = prepareSearchArguments({
808
+ filters: getState().devices.groups.byId[group].filters,
809
+ state: getState(),
810
+ status: DEVICE_STATES.accepted
811
+ });
812
+ const getAllDevices = (perPage = 500, page = defaultPage$1, devices = []) => Api.post(`${inventoryApiUrlV2}/filters/search`, {
813
+ page,
814
+ per_page: perPage,
815
+ filters,
816
+ attributes: [...attributes, {
817
+ scope: "inventory",
818
+ attribute
819
+ }]
820
+ }).then((res) => {
821
+ const state = getState();
822
+ const deviceAccu = reduceReceivedDevices(res.data, devices, state);
823
+ dispatch(actions$2.receivedDevices(deviceAccu.devicesById));
824
+ const total = Number(res.headers[headerNames.total]);
825
+ if (total > deviceAccu.ids.length) return getAllDevices(perPage, page + 1, deviceAccu.ids);
826
+ return Promise.resolve(dispatch(actions$2.addGroup({
827
+ group: {
828
+ deviceIds: deviceAccu.ids,
829
+ total
830
+ },
831
+ groupName: group
832
+ })));
833
+ });
834
+ return getAllDevices();
835
+ });
836
+ const getDeviceById = createAppAsyncThunk(`${sliceName$2}/getDeviceById`, (id, { dispatch, getState }) => Api.get(`${inventoryApiUrl}/devices/${id}`).then((res) => {
837
+ const device = reduceReceivedDevices([res.data], [], getState()).devicesById[id];
838
+ device.etag = res.headers.etag;
839
+ dispatch(actions$2.receivedDevice(device));
840
+ return Promise.resolve(device);
841
+ }).catch((err) => {
842
+ if (extractErrorMessage$1(err).includes("Not Found")) {
843
+ console.log(`${id} does not have any inventory information`);
844
+ const device = reduceReceivedDevices([{
845
+ id,
846
+ attributes: [{
847
+ name: "status",
848
+ value: "decomissioned",
849
+ scope: "identity"
850
+ }, {
851
+ name: "decomissioned",
852
+ value: "true",
853
+ scope: "inventory"
854
+ }],
855
+ log: false
856
+ }], [], getState()).devicesById[id];
857
+ dispatch(actions$2.receivedDevice(device));
858
+ }
859
+ }));
860
+ const getDeviceInfo = createAppAsyncThunk(`${sliceName$2}/getDeviceInfo`, (deviceId, { dispatch, getState }) => {
861
+ const device = getDeviceById$1(getState(), deviceId);
862
+ const { hasDeviceConfig, hasDeviceConnect, hasMonitor } = getTenantCapabilities(getState());
863
+ const { canConfigure } = getUserCapabilities(getState());
864
+ const integrations = getDeviceTwinIntegrations(getState());
865
+ const tasks = [
866
+ dispatch(getDeviceAuth(deviceId)),
867
+ dispatch(getDeviceById(deviceId)),
868
+ ...integrations.map((integration) => dispatch(getDeviceTwin({
869
+ deviceId,
870
+ integration
871
+ })))
872
+ ];
873
+ if (hasDeviceConfig && canConfigure && (device.status === DEVICE_STATES.accepted || device.status === DEVICE_STATES.preauth)) tasks.push(dispatch(getDeviceConfig(deviceId)));
874
+ if (device.status === DEVICE_STATES.accepted) {
875
+ if (hasDeviceConnect) tasks.push(dispatch(getDeviceConnect(deviceId)));
876
+ if (hasMonitor) {
877
+ tasks.push(dispatch(getLatestDeviceAlerts({ id: deviceId })));
878
+ tasks.push(dispatch(getDeviceMonitorConfig(deviceId)));
879
+ }
880
+ }
881
+ return Promise.all(tasks);
882
+ });
883
+ const getAllDeviceCounts = createAppAsyncThunk(`${sliceName$2}/getAllDeviceCounts`, (_, { dispatch }) => Api.get(`${inventoryApiUrlV2}/statistics`).then(({ data }) => {
884
+ const { devices_by_status } = data;
885
+ Object.entries(devices_by_status).map(([status, countsPerTier]) => dispatch(actions$2.setDevicesCountByStatus({
886
+ countsPerTier,
887
+ status
888
+ })));
889
+ }));
890
+ const getDeviceLimits = createAppAsyncThunk(`${sliceName$2}/getDeviceLimit`, (_, { dispatch }) => Api.get(`${deviceAuthV2}/limits/devices`).then((res) => dispatch(actions$2.setDeviceLimits(res.data))));
891
+ const setDeviceListState = createAppAsyncThunk(`${sliceName$2}/setDeviceListState`, ({ shouldSelectDevices = true, forceRefresh, fetchAuth = true, ...selectionState }, { dispatch, getState }) => {
892
+ const currentState = getDeviceListState(getState());
893
+ const refreshTrigger = forceRefresh ? !currentState.refreshTrigger : selectionState.refreshTrigger;
894
+ const nextState = {
895
+ ...currentState,
896
+ setOnly: false,
897
+ refreshTrigger,
898
+ ...selectionState,
899
+ sort: {
900
+ ...currentState.sort,
901
+ ...selectionState.sort
902
+ }
903
+ };
904
+ const tasks = [];
905
+ const { isLoading: currentLoading, deviceIds: currentDevices, selection: currentSelection, ...currentRequestState } = currentState;
906
+ const { isLoading: nextLoading, deviceIds: nextDevices, selection: nextSelection, ...nextRequestState } = nextState;
907
+ if (!nextState.setOnly && !deepCompare(currentRequestState, nextRequestState)) {
908
+ const { direction: sortDown = SORTING_OPTIONS.desc, key: sortCol, scope: sortScope = "" } = nextState.sort ?? {};
909
+ const sortBy = sortCol ? [{
910
+ attribute: sortCol,
911
+ order: sortDown,
912
+ scope: sortScope
913
+ }] : void 0;
914
+ const applicableSelectedState = nextState.state === ALL_DEVICE_STATES ? void 0 : nextState.state;
915
+ nextState.isLoading = true;
916
+ tasks.push(dispatch(getDevicesByStatus({
917
+ ...nextState,
918
+ status: applicableSelectedState,
919
+ sortOptions: sortBy,
920
+ fetchAuth
921
+ })).unwrap().then(({ deviceAccu, total }) => {
922
+ const devicesState = shouldSelectDevices ? {
923
+ deviceIds: deviceAccu.ids,
924
+ total,
925
+ isLoading: false
926
+ } : { isLoading: false };
927
+ return Promise.resolve(dispatch(actions$2.setDeviceListState(devicesState)));
928
+ }).catch(() => Promise.resolve({ isLoading: false })));
929
+ }
930
+ if (currentState.page !== nextState.page || currentState.perPage > nextState.perPage || currentState.state !== nextState.state || !deepCompare(currentState.sort, nextState.sort)) nextState.selection = [];
931
+ tasks.push(Promise.resolve(dispatch(actions$2.setDeviceListState(nextState))));
932
+ return Promise.all(tasks);
933
+ });
934
+ const getDevicesByStatus = createAppAsyncThunk(`${sliceName$2}/getDevicesByStatus`, async (options, { dispatch, getState }) => {
935
+ const { status, fetchAuth = true, filterSelection, group, selectedIssues = [], page = defaultPage$1, perPage = defaultPerPage$1, sortOptions = [], selectedAttributes = getSelectedDeviceAttribute(getState()) } = options;
936
+ const state = getState();
937
+ const { applicableFilters, filterTerms } = convertDeviceListStateToFilters({
938
+ filters: filterSelection ?? getDeviceFilters(state),
939
+ group: group ?? getSelectedGroup(state),
940
+ groups: state.devices.groups,
941
+ offlineThreshold: state.app.offlineThreshold,
942
+ selectedIssues,
943
+ status
944
+ });
945
+ const attributes = [
946
+ ...defaultAttributes,
947
+ getIdAttribute(getState()),
948
+ ...selectedAttributes
949
+ ];
950
+ const response = await Api.post(`${inventoryApiUrlV2}/filters/search`, {
951
+ page,
952
+ per_page: perPage,
953
+ filters: filterTerms,
954
+ sort: sortOptions,
955
+ attributes
956
+ }).catch((err) => commonErrorHandler(err, `${status} devices couldn't be loaded.`, dispatch, commonErrorFallback));
957
+ const currentState = getState();
958
+ const deviceAccu = reduceReceivedDevices(response.data, [], currentState, status);
959
+ let total = !applicableFilters.length ? Number(response.headers[headerNames.total]) : 0;
960
+ if (status && currentState.devices.byStatus[status].counts.total === deviceAccu.ids.length) total = deviceAccu.ids.length;
961
+ const sideEffects = [Promise.resolve(dispatch(actions$2.receivedDevices(deviceAccu.devicesById)))];
962
+ if (status) sideEffects.push(Promise.resolve(dispatch(actions$2.setDevicesByStatus({
963
+ deviceIds: deviceAccu.ids,
964
+ status,
965
+ total
966
+ }))));
967
+ const receivedDevices = Object.values(deviceAccu.devicesById);
968
+ if (receivedDevices.length && fetchAuth) sideEffects.push(dispatch(getDevicesWithAuth(receivedDevices)));
969
+ await Promise.all(sideEffects);
970
+ return {
971
+ deviceAccu,
972
+ total: Number(response.headers[headerNames.total])
973
+ };
974
+ });
975
+ const getAllDevicesByStatus = createAppAsyncThunk(`${sliceName$2}/getAllDevicesByStatus`, ({ status, attribute }, { dispatch, getState }) => {
976
+ const attributes = [...defaultAttributes, getIdAttribute(getState())];
977
+ const getAllDevices = (perPage = 500, page = 1, devices = []) => Api.post(`${inventoryApiUrlV2}/filters/search`, {
978
+ page,
979
+ per_page: perPage,
980
+ filters: mapFiltersToTerms([{
981
+ key: "status",
982
+ value: status,
983
+ operator: DEVICE_FILTERING_OPTIONS.$eq.key,
984
+ scope: "identity"
985
+ }]),
986
+ attributes: [...attributes, {
987
+ scope: "inventory",
988
+ attribute
989
+ }]
990
+ }).then((res) => {
991
+ const state = getState();
992
+ const deviceAccu = reduceReceivedDevices(res.data, devices, state, status);
993
+ dispatch(actions$2.receivedDevices(deviceAccu.devicesById));
994
+ const total = Number(res.headers[headerNames.total]);
995
+ if (total > state.deployments.deploymentDeviceLimit) return Promise.resolve();
996
+ if (total > perPage * page) return getAllDevices(perPage, page + 1, deviceAccu.ids);
997
+ return Promise.resolve();
998
+ });
999
+ return getAllDevices();
1000
+ });
1001
+ const searchDevices = createAppAsyncThunk(`${sliceName$2}/searchDevices`, async (passedOptions = {}, { dispatch, getState }) => {
1002
+ const state = getState();
1003
+ const { page = defaultPage$1, searchTerm, sortOptions = [] } = {
1004
+ ...state.app.searchState,
1005
+ ...passedOptions
1006
+ };
1007
+ const { columnSelection = [] } = getUserSettings$1(state);
1008
+ const selectedAttributes = columnSelection.map((column) => ({
1009
+ attribute: column.key,
1010
+ scope: column.scope
1011
+ }));
1012
+ const attributes = attributeDuplicateFilter([
1013
+ ...defaultAttributes,
1014
+ getIdAttribute(state),
1015
+ ...selectedAttributes
1016
+ ], "attribute");
1017
+ const response = await Api.post(`${inventoryApiUrlV2}/filters/search`, {
1018
+ page,
1019
+ per_page: 10,
1020
+ filters: [],
1021
+ sort: sortOptions,
1022
+ text: searchTerm,
1023
+ attributes
1024
+ }).catch((err) => commonErrorHandler(err, `devices couldn't be searched.`, dispatch, commonErrorFallback));
1025
+ const deviceAccu = reduceReceivedDevices(response.data, [], getState());
1026
+ dispatch(actions$2.receivedDevices(deviceAccu.devicesById));
1027
+ return {
1028
+ deviceIds: deviceAccu.ids,
1029
+ searchTotal: Number(response.headers[headerNames.total])
1030
+ };
1031
+ });
1032
+ const ATTRIBUTE_LIST_CUTOFF = 100;
1033
+ const attributeReducer = (attributes = []) => attributes.slice(0, ATTRIBUTE_LIST_CUTOFF).reduce((accu, { name, scope }) => {
1034
+ if (!accu[scope]) accu[scope] = [];
1035
+ accu[scope].push(name);
1036
+ return accu;
1037
+ }, {
1038
+ identity: [],
1039
+ inventory: [],
1040
+ system: [],
1041
+ tags: []
1042
+ });
1043
+ const getDeviceAttributes = createAppAsyncThunk(`${sliceName$2}/getDeviceAttributes`, (_, { dispatch }) => Api.get(`${inventoryApiUrlV2}/filters/attributes`).then(({ data }) => {
1044
+ const { identity: identityAttributes, inventory: inventoryAttributes, system: systemAttributes, tags: tagAttributes } = attributeReducer(data || []);
1045
+ return dispatch(actions$2.setFilterAttributes({
1046
+ identityAttributes,
1047
+ inventoryAttributes,
1048
+ systemAttributes,
1049
+ tagAttributes
1050
+ }));
1051
+ }));
1052
+ const initializeDistributionData = (report, groups, devices, totalDeviceCount) => {
1053
+ const { attribute, group = "", software = "" } = report;
1054
+ const effectiveAttribute = software ? software : attribute;
1055
+ const { deviceIds, total = 0 } = groups[group] || {};
1056
+ const distributionByAttribute = (deviceIds ? deviceIds.map((id) => devices[id]) : Object.values(devices)).reduce((accu, item) => {
1057
+ if (!item.attributes || item.status !== DEVICE_STATES.accepted) return accu;
1058
+ const attributeValue = item.attributes[effectiveAttribute];
1059
+ if (!accu[attributeValue]) accu[attributeValue] = 0;
1060
+ accu[attributeValue] = accu[attributeValue] + 1;
1061
+ return accu;
1062
+ }, {});
1063
+ const items = Object.entries(distributionByAttribute).sort((pairA, pairB) => pairB[1] - pairA[1]).map(([key, count]) => ({
1064
+ key,
1065
+ count
1066
+ }));
1067
+ const dataCount = items.reduce((accu, item) => accu + item.count, 0);
1068
+ const otherCount = (groups[group] ? total : totalDeviceCount) - dataCount;
1069
+ return {
1070
+ items,
1071
+ otherCount,
1072
+ total: otherCount + dataCount
1073
+ };
1074
+ };
1075
+ const updateReportData = createAppAsyncThunk(`${sliceName$2}/updateReportData`, (reportIndex, { dispatch, getState }) => {
1076
+ const report = getDeviceReportsForUser(getState())[reportIndex];
1077
+ const { group = "" } = report;
1078
+ const devicesById = getDevicesById(getState());
1079
+ const groups = getGroupsById(getState());
1080
+ const { accepted: acceptedDevicesCount } = getDeviceCountsByStatus(getState());
1081
+ const totalDeviceCount = groups[group] ? groups[group].total : acceptedDevicesCount;
1082
+ const newReports = [...getDeviceReports(getState())];
1083
+ newReports[reportIndex] = initializeDistributionData(report, groups, devicesById, totalDeviceCount);
1084
+ return Promise.resolve(dispatch(actions$2.setDeviceReports(newReports)));
1085
+ });
1086
+ const getReportDataWithoutBackendSupport = createAppAsyncThunk(`${sliceName$2}/getReportDataWithoutBackendSupport`, (reportIndex, { dispatch, getState }) => {
1087
+ const report = getDeviceReportsForUser(getState())[reportIndex];
1088
+ if (!report) return;
1089
+ const { attribute, group = "", software = "" } = report;
1090
+ const effectiveAttribute = software ? software : attribute;
1091
+ const devicesById = getDevicesById(getState());
1092
+ const acceptedDevices = getAcceptedDevices(getState());
1093
+ const { accepted: acceptedDevicesCount } = getDeviceCountsByStatus(getState());
1094
+ const { deviceIds = [], filters = [], total = 0 } = getGroupsById(getState())[group] || {};
1095
+ let groupDevicesRequest = Promise.resolve({ payload: {
1096
+ groupName: "",
1097
+ group: {
1098
+ deviceIds: Object.keys(devicesById),
1099
+ total: Object.keys(devicesById).length
1100
+ }
1101
+ } });
1102
+ if (group && (!(deviceIds.length && total) || deviceIds.length !== total || !deviceIds.every((id) => !!devicesById[id]))) groupDevicesRequest = filters.length ? dispatch(getAllDynamicGroupDevices({
1103
+ group,
1104
+ attribute: effectiveAttribute
1105
+ })).unwrap() : dispatch(getAllGroupDevices({
1106
+ group,
1107
+ attribute: effectiveAttribute
1108
+ })).unwrap();
1109
+ else if (!group && (acceptedDevices.deviceIds.length !== acceptedDevicesCount || !acceptedDevices.deviceIds.every((id) => !!devicesById[id]))) groupDevicesRequest = dispatch(getAllDevicesByStatus({
1110
+ status: DEVICE_STATES.accepted,
1111
+ attribute: effectiveAttribute
1112
+ })).unwrap();
1113
+ return groupDevicesRequest.then(() => dispatch(updateReportData(reportIndex)));
1114
+ });
1115
+ const getDeviceConnect = createAppAsyncThunk(`${sliceName$2}/getDeviceConnect`, (id, { dispatch }) => Api.get(`${deviceConnect}/devices/${id}`).then(({ data }) => Promise.all([dispatch(actions$2.receivedDevice({
1116
+ connect_status: data.status,
1117
+ connect_updated_ts: data.updated_ts,
1118
+ id
1119
+ })), Promise.resolve(data)])));
1120
+ const updateTypeMap = {
1121
+ deploymentUpdate: "check-update",
1122
+ inventoryUpdate: "send-inventory"
1123
+ };
1124
+ const triggerDeviceUpdate = createAppAsyncThunk(`${sliceName$2}/triggerDeviceUpdate`, async ({ id, type }, { dispatch }) => {
1125
+ await Api.post(`${deviceConnect}/devices/${id}/${updateTypeMap[type] ?? updateTypeMap.deploymentUpdate}`).catch((err) => commonErrorHandler(err, `The request couldn't be sent.`, dispatch));
1126
+ dispatch(setSnackbar$2("Request has been sent."));
1127
+ await new Promise((resolve) => setTimeout(resolve, TIMEOUTS.threeSeconds));
1128
+ return dispatch(getDeviceById(id));
1129
+ });
1130
+ const getSessionDetails = createAppAsyncThunk(`${sliceName$2}/getSessionDetails`, ({ sessionId, deviceId, userId, startDate, endDate }) => {
1131
+ const { start: startUnix, end: endUnix } = dateRangeToUnix(startDate, endDate);
1132
+ const createdAfter = startDate ? `&created_after=${startUnix}` : "";
1133
+ const createdBefore = endDate ? `&created_before=${endUnix}` : "";
1134
+ const objectSearch = `&object_id=${deviceId}`;
1135
+ return Api.get(`${auditLogsApiUrl}/logs?per_page=500${createdAfter}${createdBefore}&actor_id=${userId}${objectSearch}`).then(({ data: auditLogEntries }) => {
1136
+ const { start, end } = auditLogEntries.reduce((accu, item) => {
1137
+ if (item.meta?.session_id?.includes(sessionId)) {
1138
+ accu.start = new Date(item.action.startsWith("open") ? item.time : accu.start);
1139
+ accu.end = new Date(item.action.startsWith("close") ? item.time : accu.end);
1140
+ }
1141
+ return accu;
1142
+ }, {
1143
+ start: startDate || endDate,
1144
+ end: endDate || startDate
1145
+ });
1146
+ return Promise.resolve({
1147
+ start,
1148
+ end
1149
+ });
1150
+ });
1151
+ });
1152
+ const getDeviceFileDownloadLink = createAppAsyncThunk(`${sliceName$2}/getDeviceFileDownloadLink`, ({ deviceId, path }) => Promise.resolve(`${window.location.origin}${deviceConnect}/devices/${deviceId}/download?path=${encodeURIComponent(path)}`));
1153
+ const deviceFileUpload = createAppAsyncThunk(`${sliceName$2}/deviceFileUpload`, ({ deviceId, path, file }, { dispatch }) => {
1154
+ const formData = new FormData();
1155
+ formData.append("path", path);
1156
+ formData.append("file", file);
1157
+ const uploadId = v4();
1158
+ const cancelSource = new AbortController();
1159
+ return Promise.all([
1160
+ dispatch(setSnackbar$2("Uploading file")),
1161
+ dispatch(initUpload({
1162
+ id: uploadId,
1163
+ upload: {
1164
+ progress: 0,
1165
+ cancelSource
1166
+ }
1167
+ })),
1168
+ Api.uploadPut(`${deviceConnect}/devices/${deviceId}/upload`, formData, (e) => dispatch(uploadProgress({
1169
+ id: uploadId,
1170
+ progress: progress(e)
1171
+ })), cancelSource.signal)
1172
+ ]).then(() => Promise.resolve(dispatch(setSnackbar$2({
1173
+ message: "Upload successful",
1174
+ autoHideDuration: TIMEOUTS.fiveSeconds
1175
+ })))).catch((err) => {
1176
+ if (isCancel(err)) return dispatch(setSnackbar$2({
1177
+ message: "The upload has been cancelled",
1178
+ autoHideDuration: TIMEOUTS.fiveSeconds
1179
+ }));
1180
+ return commonErrorHandler(err, `Error uploading file to device.`, dispatch);
1181
+ }).finally(() => dispatch(cleanUpUpload(uploadId)));
1182
+ });
1183
+ const getDeviceAuth = createAppAsyncThunk(`${sliceName$2}/getDeviceAuth`, async (id, { dispatch }) => {
1184
+ return (await dispatch(getDevicesWithAuth([{ id }])).unwrap())?.[0];
1185
+ });
1186
+ const getDevicesWithAuth = createAppAsyncThunk(`${sliceName$2}/getDevicesWithAuth`, async (devices, { dispatch, getState }) => {
1187
+ if (!devices.length) return [];
1188
+ const { data: receivedDevices } = await Api.get(`${deviceAuthV2}/devices?id=${devices.map((device) => device.id).join("&id=")}`).catch((err) => commonErrorHandler(err, `Error: ${err}`, dispatch));
1189
+ const { devicesById } = reduceReceivedDevices(receivedDevices, [], getState());
1190
+ dispatch(actions$2.receivedDevices(devicesById));
1191
+ return receivedDevices;
1192
+ });
1193
+ const updateDeviceAuth = createAppAsyncThunk(`${sliceName$2}/updateDeviceAuth`, ({ deviceId, authId, status }, { dispatch, getState }) => Api.put(`${deviceAuthV2}/devices/${deviceId}/auth/${authId}/status`, { status }).then(() => Promise.all([dispatch(getDeviceAuth(deviceId)), dispatch(setSnackbar$2("Device authorization status was updated successfully"))])).catch((err) => commonErrorHandler(err, "There was a problem updating the device authorization status:", dispatch)).then(() => Promise.resolve(dispatch(actions$2.maybeUpdateDevicesByStatus({
1194
+ deviceId,
1195
+ authId
1196
+ })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getDeviceListState(getState()).refreshTrigger }))));
1197
+ const updateDevicesAuth = createAppAsyncThunk(`${sliceName$2}/updateDevicesAuth`, ({ deviceIds, status }, { dispatch, getState }) => {
1198
+ let devices = getDevicesById(getState());
1199
+ return dispatch(getDevicesWithAuth(deviceIds.reduce((accu, id) => devices[id].auth_sets ? accu : [...accu, { id }], []))).then(() => {
1200
+ devices = getDevicesById(getState());
1201
+ const deviceAuthUpdates = deviceIds.map((id) => {
1202
+ const device = devices[id];
1203
+ if (device.auth_sets && device.auth_sets.length !== 1) return Promise.reject();
1204
+ return dispatch(updateDeviceAuth({
1205
+ authId: device.auth_sets[0].id,
1206
+ deviceId: device.id,
1207
+ status
1208
+ })).unwrap().catch((err) => commonErrorHandler(err, "The action was stopped as there was a problem updating a device authorization status: ", dispatch, "", false));
1209
+ });
1210
+ return Promise.allSettled(deviceAuthUpdates).then((results) => {
1211
+ const { skipped, count } = results.reduce((accu, item) => {
1212
+ if (item.status === "rejected") accu.skipped = accu.skipped + 1;
1213
+ else accu.count = accu.count + 1;
1214
+ return accu;
1215
+ }, {
1216
+ skipped: 0,
1217
+ count: 0
1218
+ });
1219
+ return dispatch(setSnackbar$2(getSnackbarMessage(skipped, count)));
1220
+ });
1221
+ });
1222
+ });
1223
+ const deleteAuthset = createAppAsyncThunk(`${sliceName$2}/deleteAuthset`, ({ deviceId, authId }, { dispatch, getState }) => Api.delete(`${deviceAuthV2}/devices/${deviceId}/auth/${authId}`).then(() => Promise.all([dispatch(setSnackbar$2("Device authorization status was updated successfully"))])).catch((err) => commonErrorHandler(err, "There was a problem updating the device authorization status:", dispatch)).then(() => Promise.resolve(dispatch(actions$2.maybeUpdateDevicesByStatus({
1224
+ deviceId,
1225
+ authId
1226
+ })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getState().devices.deviceList.refreshTrigger }))));
1227
+ const preauthDevice = createAppAsyncThunk(`${sliceName$2}/preauthDevice`, (authset, { dispatch, rejectWithValue }) => Api.post(`${deviceAuthV2}/devices`, authset).then(() => Promise.resolve(dispatch(setSnackbar$2({
1228
+ message: "Device was successfully added to the preauthorization list",
1229
+ autoHideDuration: TIMEOUTS.fiveSeconds
1230
+ })))).catch((err) => {
1231
+ if (err.response.status === 409) return rejectWithValue("A device with a matching identity data set already exists");
1232
+ return commonErrorHandler(err, "The device could not be added:", dispatch);
1233
+ }));
1234
+ const decommissionDevice = createAppAsyncThunk(`${sliceName$2}/decommissionDevice`, ({ deviceId, authId }, { dispatch, getState }) => Api.delete(`${deviceAuthV2}/devices/${deviceId}`).then(() => Promise.resolve(dispatch(setSnackbar$2("Device was decommissioned successfully")))).catch((err) => commonErrorHandler(err, "There was a problem decommissioning the device:", dispatch)).then(() => Promise.resolve(dispatch(actions$2.maybeUpdateDevicesByStatus({
1235
+ deviceId,
1236
+ authId
1237
+ })))).finally(() => dispatch(setDeviceListState({ refreshTrigger: !getState().devices.deviceList.refreshTrigger }))));
1238
+ const getDeviceConfig = createAppAsyncThunk(`${sliceName$2}/getDeviceConfig`, (deviceId, { dispatch }) => Api.get(`${deviceConfig}/${deviceId}`).then(({ data }) => Promise.all([dispatch(actions$2.receivedDevice({
1239
+ id: deviceId,
1240
+ config: data
1241
+ })), Promise.resolve(data)])).catch((err) => {
1242
+ if (err.response?.data?.error.status_code !== 404) return commonErrorHandler(err, `There was an error retrieving the configuration for device ${deviceId}.`, dispatch, commonErrorFallback);
1243
+ }));
1244
+ const setDeviceConfig = createAppAsyncThunk(`${sliceName$2}/setDeviceConfig`, ({ deviceId, config }, { dispatch }) => Api.put(`${deviceConfig}/${deviceId}`, config).catch((err) => commonErrorHandler(err, `There was an error setting the configuration for device ${deviceId}.`, dispatch, commonErrorFallback)).then(() => Promise.resolve(dispatch(getDeviceConfig(deviceId)))));
1245
+ const applyDeviceConfig = createAppAsyncThunk(`${sliceName$2}/applyDeviceConfig`, ({ deviceId, configDeploymentConfiguration, isDefault, config }, { dispatch, getState }) => Api.post(`${deviceConfig}/${deviceId}/deploy`, configDeploymentConfiguration).catch((err) => commonErrorHandler(err, `There was an error deploying the configuration to device ${deviceId}.`, dispatch, commonErrorFallback)).then(({ data }) => {
1246
+ const device = getDeviceById$1(getState(), deviceId);
1247
+ const { canManageUsers } = getUserCapabilities(getState());
1248
+ const tasks = [Promise.resolve(dispatch(actions$2.receivedDevice({
1249
+ ...device,
1250
+ config: {
1251
+ ...device.config,
1252
+ deployment_id: data.deployment_id
1253
+ }
1254
+ }))), new Promise((resolve) => setTimeout(() => resolve(dispatch(getSingleDeployment(data.deployment_id))), TIMEOUTS.oneSecond))];
1255
+ if (isDefault && canManageUsers) {
1256
+ const { previous } = getGlobalSettings$1(getState()).defaultDeviceConfig ?? {};
1257
+ tasks.push(dispatch(saveGlobalSettings({ defaultDeviceConfig: {
1258
+ current: config,
1259
+ previous
1260
+ } })));
1261
+ }
1262
+ return Promise.all(tasks);
1263
+ }));
1264
+ const setDeviceTags = createAppAsyncThunk(`${sliceName$2}/setDeviceTags`, ({ deviceId, tags }, { dispatch }) => dispatch(getDeviceById(deviceId)).unwrap().then((device) => {
1265
+ const headers = device.etag ? { "If-Match": device.etag } : {};
1266
+ const tagList = Object.entries(tags).map(([name, value]) => ({
1267
+ name,
1268
+ value
1269
+ }));
1270
+ const isNameChange = tagList.some(({ name }) => name === "name");
1271
+ return Api.put(`${inventoryApiUrl}/devices/${deviceId}/tags`, tagList, { headers }).catch((err) => commonErrorHandler(err, `There was an error setting tags for device ${deviceId}.`, dispatch, "Please check your connection.")).then(() => Promise.all([dispatch(actions$2.receivedDevice({
1272
+ ...device,
1273
+ id: deviceId,
1274
+ tags
1275
+ })), dispatch(setSnackbar$2(`Device ${tagList.length === 1 && isNameChange ? "name" : "tags"} changed`))]));
1276
+ }));
1277
+ const getDeviceTwin = createAppAsyncThunk(`${sliceName$2}/getDeviceTwin`, ({ deviceId, integration }, { dispatch, getState }) => {
1278
+ let providerResult = {};
1279
+ return Api.get(`${iotManagerBaseURL}/devices/${deviceId}/state`).then(({ data }) => {
1280
+ providerResult = {
1281
+ ...data,
1282
+ twinError: ""
1283
+ };
1284
+ }).catch((err) => {
1285
+ providerResult = { twinError: `There was an error getting the ${EXTERNAL_PROVIDER[integration.provider].twinTitle.toLowerCase()} for device ${deviceId}. ${err}` };
1286
+ }).finally(() => {
1287
+ const device = getDeviceById$1(getState(), deviceId);
1288
+ Promise.resolve(dispatch(actions$2.receivedDevice({
1289
+ ...device,
1290
+ twinsByIntegration: {
1291
+ ...device.twinsByIntegration,
1292
+ ...providerResult
1293
+ }
1294
+ })));
1295
+ });
1296
+ });
1297
+ const setDeviceTwin = createAppAsyncThunk(`${sliceName$2}/setDeviceTwin`, ({ deviceId, integration, settings }, { dispatch, getState }) => Api.put(`${iotManagerBaseURL}/devices/${deviceId}/state/${integration.id}`, { desired: settings }).catch((err) => commonErrorHandler(err, `There was an error updating the ${EXTERNAL_PROVIDER[integration.provider].twinTitle.toLowerCase()} for device ${deviceId}.`, dispatch)).then(() => {
1298
+ const device = getDeviceById$1(getState(), deviceId);
1299
+ const { twinsByIntegration = {} } = device;
1300
+ const { [integration.id]: currentState = {} } = twinsByIntegration;
1301
+ return Promise.resolve(dispatch(actions$2.receivedDevice({
1302
+ ...device,
1303
+ twinsByIntegration: {
1304
+ ...twinsByIntegration,
1305
+ [integration.id]: {
1306
+ ...currentState,
1307
+ desired: settings
1308
+ }
1309
+ }
1310
+ })));
1311
+ }));
1312
+ const prepareSearchArguments = ({ filters, group, state, status }) => {
1313
+ const { filterTerms } = convertDeviceListStateToFilters({
1314
+ filters,
1315
+ group,
1316
+ offlineThreshold: state.app.offlineThreshold,
1317
+ selectedIssues: [],
1318
+ status
1319
+ });
1320
+ const { columnSelection = [] } = getUserSettings$1(state);
1321
+ const selectedAttributes = columnSelection.map((column) => ({
1322
+ attribute: column.key,
1323
+ scope: column.scope
1324
+ }));
1325
+ return {
1326
+ attributes: [
1327
+ ...defaultAttributes,
1328
+ getIdAttribute(state),
1329
+ ...selectedAttributes
1330
+ ],
1331
+ filterTerms
1332
+ };
1333
+ };
1334
+ const getSystemDevices = createAppAsyncThunk(`${sliceName$2}/getSystemDevices`, (options, { dispatch, getState }) => {
1335
+ const { id, page = defaultPage$1, perPage = defaultPerPage$1, sortOptions = [] } = options;
1336
+ const state = getState();
1337
+ const { hasFullFiltering } = getTenantCapabilities(state);
1338
+ if (!hasFullFiltering) return Promise.resolve();
1339
+ const { attributes: deviceAttributes = {} } = getDeviceById$1(state, id);
1340
+ const { mender_gateway_system_id = "" } = deviceAttributes;
1341
+ const { attributes, filterTerms } = prepareSearchArguments({
1342
+ filters: [{
1343
+ ...emptyFilter,
1344
+ key: "mender_is_gateway",
1345
+ operator: DEVICE_FILTERING_OPTIONS.$ne.key,
1346
+ value: "true",
1347
+ scope: "inventory"
1348
+ }, {
1349
+ ...emptyFilter,
1350
+ key: "mender_gateway_system_id",
1351
+ value: mender_gateway_system_id,
1352
+ scope: "inventory"
1353
+ }],
1354
+ state
1355
+ });
1356
+ return Api.post(`${inventoryApiUrlV2}/filters/search`, {
1357
+ page,
1358
+ per_page: perPage,
1359
+ filters: filterTerms,
1360
+ sort: sortOptions,
1361
+ attributes
1362
+ }).catch((err) => commonErrorHandler(err, `There was an error getting system devices device ${id}.`, dispatch, "Please check your connection.")).then(({ data, headers }) => {
1363
+ const state = getState();
1364
+ const { devicesById, ids } = reduceReceivedDevices(data, [], state);
1365
+ const device = {
1366
+ ...getDeviceById$1(state, id),
1367
+ systemDeviceIds: ids,
1368
+ systemDeviceTotal: Number(headers[headerNames.total])
1369
+ };
1370
+ return Promise.resolve(dispatch(actions$2.receivedDevices({
1371
+ ...devicesById,
1372
+ [id]: device
1373
+ })));
1374
+ });
1375
+ });
1376
+ const getGatewayDevices = createAppAsyncThunk(`${sliceName$2}/getGatewayDevices`, (deviceId, { dispatch, getState }) => {
1377
+ const state = getState();
1378
+ const { attributes = {} } = getDeviceById$1(state, deviceId);
1379
+ const { mender_gateway_system_id = "" } = attributes;
1380
+ const { attributes: attributeSelection, filterTerms } = prepareSearchArguments({
1381
+ filters: [
1382
+ {
1383
+ ...emptyFilter,
1384
+ key: "id",
1385
+ operator: DEVICE_FILTERING_OPTIONS.$ne.key,
1386
+ value: deviceId,
1387
+ scope: "identity"
1388
+ },
1389
+ {
1390
+ ...emptyFilter,
1391
+ key: "mender_is_gateway",
1392
+ value: "true",
1393
+ scope: "inventory"
1394
+ },
1395
+ {
1396
+ ...emptyFilter,
1397
+ key: "mender_gateway_system_id",
1398
+ value: mender_gateway_system_id,
1399
+ scope: "inventory"
1400
+ }
1401
+ ],
1402
+ state
1403
+ });
1404
+ return Api.post(`${inventoryApiUrlV2}/filters/search`, {
1405
+ page: 1,
1406
+ per_page: 500,
1407
+ filters: filterTerms,
1408
+ attributes: attributeSelection
1409
+ }).then(({ data }) => {
1410
+ const { ids } = reduceReceivedDevices(data, [], getState());
1411
+ const tasks = ids.map((deviceId) => dispatch(getDeviceInfo(deviceId)));
1412
+ tasks.push(Promise.resolve(dispatch(actions$2.receivedDevice({
1413
+ id: deviceId,
1414
+ gatewayIds: ids
1415
+ }))));
1416
+ return Promise.all(tasks);
1417
+ });
1418
+ });
1419
+ //#endregion
1420
+ //#region src/onboardingSlice/thunks.ts
1421
+ const cookies$2 = new Cookies();
1422
+ const determineProgress = (acceptedDevices, pendingDevices, releases, pastDeployments) => {
1423
+ const steps = orderedOnboardingSteps;
1424
+ let progress = -1;
1425
+ progress = pendingDevices.length > 1 ? steps.findIndex((step) => step === onboardingSteps.DEVICES_PENDING_ACCEPTING_ONBOARDING) : progress;
1426
+ progress = acceptedDevices.length >= 1 ? steps.findIndex((step) => step === onboardingSteps.DEVICES_ACCEPTED_ONBOARDING) : progress;
1427
+ progress = acceptedDevices.length > 1 && releases.length > 1 && pastDeployments.length > 1 ? steps.findIndex((step) => step === onboardingSteps.DEPLOYMENTS_PAST_COMPLETED) : progress;
1428
+ return steps[progress];
1429
+ };
1430
+ const deductOnboardingState = ({ devicesById, devicesByStatus, onboardingState, pastDeployments, releases, userCapabilities, userId }) => {
1431
+ const { canDeploy, canManageDevices, canReadDeployments, canReadDevices, canReadReleases, canUploadReleases } = userCapabilities;
1432
+ const userCookie = cookies$2.get(`${userId}-onboarded`);
1433
+ const acceptedDevices = devicesByStatus[DEVICE_STATES.accepted].deviceIds;
1434
+ const pendingDevices = devicesByStatus[DEVICE_STATES.pending].deviceIds;
1435
+ let deviceType = onboardingState.deviceType ?? [];
1436
+ deviceType = !deviceType.length && acceptedDevices.length && devicesById[acceptedDevices[0]].hasOwnProperty("attributes") ? devicesById[acceptedDevices[0]].attributes.device_type : deviceType;
1437
+ const deviceTier = acceptedDevices.length && devicesById[acceptedDevices[0]].tier;
1438
+ let approach = null;
1439
+ if (deviceType.some((type) => type.startsWith("qemu"))) approach = "virtual";
1440
+ else if (deviceType.some((type) => type.startsWith("esp32")) || deviceTier === "micro") approach = "mcu";
1441
+ else if (deviceType.length) approach = "physical";
1442
+ const progress = onboardingState.progress || determineProgress(acceptedDevices, pendingDevices, releases, pastDeployments);
1443
+ return {
1444
+ ...onboardingState,
1445
+ complete: !!(Boolean(userCookie) || onboardingState.complete || acceptedDevices.length > 1 && pendingDevices.length > 0 && releases.length > 1 && pastDeployments.length > 1 || acceptedDevices.length >= 1 && releases.length >= 2 && pastDeployments.length > 2 || acceptedDevices.length >= 1 && pendingDevices.length > 0 && releases.length >= 2 && pastDeployments.length >= 2 || orderedOnboardingSteps.findIndex((step) => step === progress) >= orderedOnboardingSteps.length - 1 || onboardingState.disable || ![
1446
+ canDeploy,
1447
+ canManageDevices,
1448
+ canReadDeployments,
1449
+ canReadDevices,
1450
+ canReadReleases,
1451
+ canUploadReleases
1452
+ ].every((i) => i)),
1453
+ showTips: onboardingState.showTips != null ? onboardingState.showTips : true,
1454
+ deviceType,
1455
+ approach: onboardingState.approach || approach,
1456
+ progress
1457
+ };
1458
+ };
1459
+ const getOnboardingState = createAppAsyncThunk(`${sliceName$3}/getOnboardingState`, (_, { dispatch, getState }) => {
1460
+ const state = getState();
1461
+ let onboardingState = getOnboardingState$1(state);
1462
+ if (!onboardingState.complete) {
1463
+ const userId = state.users.currentUser;
1464
+ onboardingState = deductOnboardingState({
1465
+ devicesById: state.devices.byId,
1466
+ devicesByStatus: state.devices.byStatus,
1467
+ onboardingState,
1468
+ pastDeployments: state.deployments.byStatus.finished.deploymentIds,
1469
+ releases: Object.values(state.releases.byId),
1470
+ userCapabilities: getUserCapabilities(state),
1471
+ userId
1472
+ });
1473
+ }
1474
+ onboardingState.progress = onboardingState.progress || onboardingSteps.DASHBOARD_ONBOARDING_START;
1475
+ const demoDeviceAddress = `http://${getDemoDeviceAddress(Object.values(state.devices.byId), onboardingState.approach)}`;
1476
+ onboardingState.address = state.onboarding.demoArtifactPort ? `${demoDeviceAddress}:${state.onboarding.demoArtifactPort}` : demoDeviceAddress;
1477
+ return Promise.all([
1478
+ dispatch(actions$3.setOnboardingComplete(onboardingState.complete)),
1479
+ dispatch(actions$3.setOnboardingState(onboardingState)),
1480
+ dispatch(saveUserSettings({ onboarding: onboardingState }))
1481
+ ]);
1482
+ });
1483
+ const setOnboardingDeviceType = createAppAsyncThunk(`${sliceName$3}/setOnboardingDeviceType`, (value, { dispatch }) => Promise.all([dispatch(actions$3.setOnboardingDeviceType(value)), dispatch(saveUserSettings({ onboarding: { deviceType: value } }))]));
1484
+ const setOnboardingApproach = createAppAsyncThunk(`${sliceName$3}/setOnboardingApproach`, (value, { dispatch }) => Promise.all([dispatch(actions$3.setOnboardingApproach(value)), dispatch(saveUserSettings({ onboarding: { approach: value } }))]));
1485
+ const setOnboardingComplete = createAppAsyncThunk(`${sliceName$3}/setOnboardingComplete`, (value, { dispatch }) => {
1486
+ const tasks = [Promise.resolve(dispatch(actions$3.setOnboardingComplete(value)))];
1487
+ if (value) {
1488
+ tasks.push(Promise.resolve(dispatch(actions$3.setShowOnboardingHelp(false))));
1489
+ tasks.push(Promise.resolve(dispatch(advanceOnboarding(onboardingSteps.DEPLOYMENTS_PAST_COMPLETED))));
1490
+ }
1491
+ return Promise.all(tasks);
1492
+ });
1493
+ const setOnboardingCanceled = createAppAsyncThunk(`${sliceName$3}/setOnboardingCanceled`, (_, { dispatch }) => Promise.all([
1494
+ Promise.resolve(dispatch(actions$3.setShowOnboardingHelp(false))),
1495
+ Promise.resolve(dispatch(actions$3.setShowDismissOnboardingTipsDialog(false))),
1496
+ Promise.resolve(dispatch(actions$3.setOnboardingComplete(true)))
1497
+ ]).then(() => dispatch(advanceOnboarding(onboardingSteps.DEPLOYMENTS_PAST_COMPLETED_FAILURE))).then(() => Tracking.event({
1498
+ category: "onboarding",
1499
+ action: onboardingSteps.ONBOARDING_CANCELED
1500
+ })));
1501
+ const advanceOnboarding = createAppAsyncThunk(`${sliceName$3}/advanceOnboarding`, (stepId, { dispatch, getState }) => {
1502
+ const steps = orderedOnboardingSteps;
1503
+ const progress = steps.findIndex((step) => step === getState().onboarding.progress);
1504
+ const stepIndex = steps.findIndex((step) => step === stepId);
1505
+ if (progress > stepIndex || getState().onboarding.progress === null) return;
1506
+ const madeProgress = steps[stepIndex + 1];
1507
+ const state = {
1508
+ ...getOnboardingState$1(getState()),
1509
+ progress: madeProgress
1510
+ };
1511
+ state.complete = stepIndex + 1 >= orderedOnboardingSteps.findIndex((step) => step === onboardingSteps.DEPLOYMENTS_PAST_COMPLETED_FAILURE) ? true : state.complete;
1512
+ Tracking.event({
1513
+ category: "onboarding",
1514
+ action: stepId
1515
+ });
1516
+ return Promise.all([dispatch(actions$3.setOnboardingProgress(madeProgress)), dispatch(saveUserSettings({ onboarding: state }))]);
1517
+ });
1518
+ //#endregion
1519
+ //#region src/organizationSlice/thunks.ts
1520
+ const cookies$1 = new Cookies();
1521
+ dayjs.extend(utc);
1522
+ const { setAnnouncement: setAnnouncement$1, setSnackbar: setSnackbar$1 } = actions_default;
1523
+ const { page: defaultPage, perPage: defaultPerPage } = DEVICE_LIST_DEFAULTS;
1524
+ const cancelRequest = createAppAsyncThunk(`${sliceName$4}/cancelRequest`, (reason, { dispatch, getState }) => {
1525
+ const { id: tenantId } = getOrganization(getState());
1526
+ return Api.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/cancel`, { reason }).then(() => Promise.resolve(dispatch(setSnackbar$1({
1527
+ message: "Deactivation request was sent successfully",
1528
+ autoHideDuration: TIMEOUTS.fiveSeconds
1529
+ }))));
1530
+ });
1531
+ const getTierId = (tierName) => tierName.replace("mender_", "");
1532
+ const getProductPlans = (products) => {
1533
+ return {
1534
+ ...products.reduce((plansById, product) => {
1535
+ const { name, prices } = product;
1536
+ const tierId = getTierId(name);
1537
+ prices.forEach((price) => {
1538
+ const existing = plansById[price.plan] ?? {
1539
+ ...PLANS[price.plan],
1540
+ tierLimitsConstrains: {}
1541
+ };
1542
+ const tierConstraints = price.constraints ? { [tierId]: {
1543
+ min: price.constraints.min,
1544
+ max: price.constraints.max,
1545
+ div: price.constraints.div
1546
+ } } : {};
1547
+ plansById[price.plan] = {
1548
+ ...existing,
1549
+ tierLimitsConstrains: {
1550
+ ...existing.tierLimitsConstrains,
1551
+ ...tierConstraints
1552
+ }
1553
+ };
1554
+ });
1555
+ return plansById;
1556
+ }, {}),
1557
+ enterprise: { ...PLANS.enterprise }
1558
+ };
1559
+ };
1560
+ const getProductAddons = (products) => products.reduce((accu, product) => {
1561
+ const { addons = [] } = product;
1562
+ addons.forEach((addon) => {
1563
+ const { name: addonName = "", prices: addonPrices = [] } = addon;
1564
+ const existingEligible = accu[addonName]?.eligible ?? [];
1565
+ const newEligible = addonPrices.map((p) => p.plan);
1566
+ accu[addonName] = {
1567
+ ...ADDONS[addonName],
1568
+ eligible: [...new Set([
1569
+ ...existingEligible,
1570
+ ...newEligible,
1571
+ PLANS.enterprise.id
1572
+ ])]
1573
+ };
1574
+ });
1575
+ return accu;
1576
+ }, {});
1577
+ const transformProductResponse = (products) => {
1578
+ const tiers = [];
1579
+ products.sort((a, b) => a.name.localeCompare(b.name)).forEach((tier) => {
1580
+ const addonsSupported = Object.fromEntries((tier.addons || []).map((addon) => [addon.name, addon.prices?.map((p) => p.plan)]));
1581
+ const addonsTransposed = tier.prices.map((price) => price.plan).reduce((acc, plan) => {
1582
+ acc[plan] = Object.entries(addonsSupported).filter(([, addonSupportedPlans]) => addonSupportedPlans.includes(plan)).map(([addon]) => addon);
1583
+ return acc;
1584
+ }, {});
1585
+ const tierId = getTierId(tier.name);
1586
+ tiers.push({
1587
+ id: tierId,
1588
+ title: tierId,
1589
+ stripeProductName: tier.name,
1590
+ limitConstrains: Object.fromEntries(tier.prices.map((p) => [p.plan, p.constraints])),
1591
+ addons: addonsSupported,
1592
+ addonsByPlan: addonsTransposed
1593
+ });
1594
+ });
1595
+ return {
1596
+ plans: getProductPlans(products),
1597
+ tiers,
1598
+ addons: getProductAddons(products)
1599
+ };
1600
+ };
1601
+ const getTargetLocation = (key) => {
1602
+ if (devLocations.includes(window.location.hostname)) return "";
1603
+ let subdomainSections = window.location.hostname.substring(0, window.location.hostname.indexOf(locations.us.location)).split(".");
1604
+ subdomainSections = subdomainSections.splice(0, subdomainSections.length - 1);
1605
+ if (!subdomainSections.find((section) => section === key)) {
1606
+ subdomainSections = key === locations.us.key ? subdomainSections.filter((section) => !locations[section]) : [...subdomainSections, key];
1607
+ return `https://${[...subdomainSections, ...locations.us.location.split(".")].join(".")}`;
1608
+ }
1609
+ return `https://${window.location.hostname}`;
1610
+ };
1611
+ const devLocations = ["localhost", "docker.mender.io"];
1612
+ const createOrganizationTrial = createAppAsyncThunk(`${sliceName$4}/createOrganizationTrial`, async (data, { dispatch }) => {
1613
+ const { key } = locations[data.location];
1614
+ const targetLocation = getTargetLocation(key);
1615
+ const target = `${targetLocation}${tenantadmApiUrlv2}/tenants/trial`;
1616
+ const { headers } = await Api.postUnauthorized(target, data).catch((err) => {
1617
+ if (err.response?.status >= 400 && err.response?.status < 500) dispatch(setSnackbar$1({
1618
+ message: err.response.data.error,
1619
+ autoHideDuration: TIMEOUTS.fiveSeconds
1620
+ }));
1621
+ else dispatch(setSnackbar$1({
1622
+ message: "There was an error creating your account",
1623
+ autoHideDuration: TIMEOUTS.fiveSeconds
1624
+ }));
1625
+ return Promise.reject(err);
1626
+ });
1627
+ cookies$1.remove("oauth");
1628
+ cookies$1.remove("externalID");
1629
+ cookies$1.remove("email");
1630
+ dispatch(setFirstLoginAfterSignup(true));
1631
+ return new Promise((resolve) => setTimeout(() => {
1632
+ window.location.assign(`${targetLocation}${headers.location || ""}`);
1633
+ return resolve();
1634
+ }, TIMEOUTS.fiveSeconds));
1635
+ });
1636
+ const startCardUpdate = createAppAsyncThunk(`${sliceName$4}/startCardUpdate`, (_, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/billing/card`).then(({ data }) => {
1637
+ dispatch(actions$4.receiveSetupIntent(data.intent_id));
1638
+ return Promise.resolve(data.secret);
1639
+ }).catch((err) => commonErrorHandler(err, `Updating the card failed:`, dispatch)));
1640
+ const confirmCardUpdate = createAppAsyncThunk(`${sliceName$4}/confirmCardUpdate`, (_, { dispatch, getState }) => Api.post(`${tenantadmApiUrlv2}/billing/card/${getState().organization.intentId}/confirm`).then(() => Promise.all([dispatch(setSnackbar$1("Payment card was updated successfully")), dispatch(actions$4.receiveSetupIntent(null))])).catch((err) => commonErrorHandler(err, `Updating the card failed:`, dispatch)));
1641
+ const getCurrentCard = createAppAsyncThunk(`${sliceName$4}/getCurrentCard`, (_, { dispatch }) => Api.get(`${tenantadmApiUrlv2}/billing`).then((res) => {
1642
+ const { last4, exp_month, exp_year, brand } = res.data.card || {};
1643
+ return Promise.resolve(dispatch(actions$4.receiveCurrentCard({
1644
+ brand,
1645
+ last4,
1646
+ expiration: {
1647
+ month: exp_month,
1648
+ year: exp_year
1649
+ }
1650
+ })));
1651
+ }));
1652
+ const startUpgrade = createAppAsyncThunk(`${sliceName$4}/startUpgrade`, (tenantId, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/upgrade/start`).then(({ data }) => Promise.resolve(data.secret)).catch((err) => commonErrorHandler(err, `There was an error upgrading your account:`, dispatch)));
1653
+ const cancelUpgrade = createAppAsyncThunk(`${sliceName$4}/cancelUpgrade`, (tenantId) => Api.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/upgrade/cancel`));
1654
+ const completeUpgrade = createAppAsyncThunk(`${sliceName$4}/completeUpgrade`, ({ tenantId, plan, billing_profile }, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/upgrade/complete`, {
1655
+ plan,
1656
+ billing_profile
1657
+ }).catch((err) => commonErrorHandler(err, `There was an error upgrading your account:`, dispatch)).then(() => Promise.all([dispatch(getDeviceLimits()), dispatch(getUserOrganization())])));
1658
+ const prepareAuditlogQuery = ({ startDate, endDate, user: userFilter, type, detail: detailFilter, sort = { direction: SORTING_OPTIONS.desc } }) => {
1659
+ const userId = typeof userFilter === "object" && userFilter ? userFilter.id : userFilter;
1660
+ const detail = typeof detailFilter === "object" && detailFilter ? detailFilter.id : detailFilter;
1661
+ const { start: startUnix, end: endUnix } = dateRangeToUnix(startDate, endDate);
1662
+ const createdAfter = startDate ? `&created_after=${startUnix}` : "";
1663
+ const createdBefore = endDate ? `&created_before=${endUnix}` : "";
1664
+ const typeSearch = type ? `&object_type=${type.value}`.toLowerCase() : "";
1665
+ const userSearch = userId ? `&actor_id=${userId}` : "";
1666
+ const objectSearch = type && detail ? `&${type.queryParameter}=${encodeURIComponent(detail)}` : "";
1667
+ const { direction = SORTING_OPTIONS.desc } = sort;
1668
+ return `${createdAfter}${createdBefore}${userSearch}${typeSearch}${objectSearch}&sort=${direction}`;
1669
+ };
1670
+ const getAuditLogs = createAppAsyncThunk(`${sliceName$4}/getAuditLogs`, async (selectionState, { dispatch, getState }) => {
1671
+ const { page, perPage } = selectionState;
1672
+ const { hasAuditlogs } = getTenantCapabilities(getState());
1673
+ if (!hasAuditlogs) return;
1674
+ const { data, headers } = await Api.get(`${auditLogsApiUrl}/logs?page=${page}&per_page=${perPage}${prepareAuditlogQuery(selectionState)}`).catch((err) => commonErrorHandler(err, `There was an error retrieving audit logs:`, dispatch));
1675
+ const total = Number(headers[headerNames.total] || data.length);
1676
+ return dispatch(actions$4.receiveAuditLogs({
1677
+ events: data,
1678
+ total
1679
+ }));
1680
+ });
1681
+ const getAuditLogsCsvLink = createAppAsyncThunk(`${sliceName$4}/getAuditLogsCsvLink`, (_, { getState }) => Promise.resolve(`${window.location.origin}${auditLogsApiUrl}/logs/export?limit=20000${prepareAuditlogQuery(getAuditlogState(getState()))}`));
1682
+ const setAuditlogsState = createAppAsyncThunk(`${sliceName$4}/setAuditlogsState`, (selectionState, { dispatch, getState }) => {
1683
+ const currentState = getAuditlogState(getState());
1684
+ const nextState = {
1685
+ ...currentState,
1686
+ ...selectionState,
1687
+ sort: {
1688
+ ...currentState.sort,
1689
+ ...selectionState.sort
1690
+ }
1691
+ };
1692
+ const tasks = [];
1693
+ const { isLoading: currentLoading, selectedIssue: currentIssue, ...currentRequestState } = currentState;
1694
+ const { isLoading: selectionLoading, selectedIssue: selectionIssue, ...selectionRequestState } = nextState;
1695
+ if (!deepCompare(currentRequestState, selectionRequestState)) {
1696
+ nextState.isLoading = true;
1697
+ tasks.push(dispatch(getAuditLogs(nextState)).finally(() => dispatch(actions$4.setAuditLogState({ isLoading: false }))));
1698
+ }
1699
+ tasks.push(Promise.resolve(dispatch(actions$4.setAuditLogState(nextState))));
1700
+ return Promise.all(tasks);
1701
+ });
1702
+ const tenantDataDivergedMessage = "The system detected there is a change in your plan or purchased add-ons. Please log out and log in again";
1703
+ const addTenant = createAppAsyncThunk(`${sliceName$4}/createTenant`, (selectionState, { dispatch, getState }) => {
1704
+ const spLimits = getSpLimits(getState());
1705
+ const { deviceLimits, ...rest } = selectionState;
1706
+ const device_limits = convertToBackendSPLimits(deviceLimits, spLimits);
1707
+ return Api.post(`${tenantadmApiUrlv2}/tenants`, {
1708
+ ...rest,
1709
+ device_limits
1710
+ }).then(() => Promise.all([dispatch(setSnackbar$1("Tenant was created successfully.")), new Promise((resolve) => setTimeout(() => resolve(dispatch(getTenants())), TIMEOUTS.oneSecond))])).catch((err) => commonErrorHandler(err, "There was an error creating tenant", dispatch, commonErrorFallback));
1711
+ });
1712
+ const tenantListRetrieval = async (config) => {
1713
+ const { page, perPage } = config;
1714
+ const params = new URLSearchParams({
1715
+ page,
1716
+ per_page: perPage,
1717
+ tiers: "true"
1718
+ }).toString();
1719
+ const tenantList = await Api.get(`${tenantadmApiUrlv2}/tenants?${params}`);
1720
+ const totalCount = tenantList.headers[headerNames.total] || TENANT_LIST_DEFAULT.perPage;
1721
+ return [tenantList.data, Number(totalCount)];
1722
+ };
1723
+ const getTenants = createAppAsyncThunk(`${sliceName$4}/getTenants`, async (_, { dispatch, getState }) => {
1724
+ const currentState = getTenantsList(getState());
1725
+ const [tenants, pageCount] = await tenantListRetrieval(currentState);
1726
+ dispatch(actions$4.setTenantListState({
1727
+ ...currentState,
1728
+ total: pageCount,
1729
+ tenants
1730
+ }));
1731
+ });
1732
+ const setTenantsListState = createAppAsyncThunk(`${sliceName$4}/setTenantsListState`, async (selectionState, { dispatch, getState }) => {
1733
+ const currentState = getTenantsList(getState());
1734
+ const nextState = {
1735
+ ...currentState,
1736
+ ...selectionState
1737
+ };
1738
+ if (!deepCompare(currentState, selectionState)) {
1739
+ const [tenants, pageCount] = await tenantListRetrieval(nextState);
1740
+ return dispatch(actions$4.setTenantListState({
1741
+ ...nextState,
1742
+ tenants,
1743
+ total: pageCount
1744
+ }));
1745
+ }
1746
+ return dispatch(actions$4.setTenantListState({ ...nextState }));
1747
+ });
1748
+ const editTenant = createAppAsyncThunk(`${sliceName$4}/editDeviceLimit`, ({ deviceLimits, id, name }, { dispatch, getState }) => {
1749
+ const device_limits = convertToBackendSPLimits(deviceLimits, getSpLimits(getState()));
1750
+ return Api.put(`${tenantadmApiUrlv2}/tenants/${id}/child`, {
1751
+ device_limits,
1752
+ name
1753
+ }).catch((err) => commonErrorHandler(err, `Device Limit cannot be changed`, dispatch)).then(() => Promise.all([
1754
+ dispatch(setSnackbar$1("Tenant was changed successfully")),
1755
+ dispatch(getUserOrganization()),
1756
+ new Promise((resolve) => setTimeout(() => resolve(dispatch(getTenants())), TIMEOUTS.oneSecond))
1757
+ ]));
1758
+ });
1759
+ const editBillingProfile = createAppAsyncThunk(`${sliceName$4}/editBillingProfileEmail`, ({ billingProfile }, { dispatch }) => Api.patch(`${tenantadmApiUrlv2}/billing/profile`, billingProfile).catch((err) => commonErrorHandler(err, `Failed to change billing profile`, dispatch)).then(() => Promise.all([dispatch(setSnackbar$1("Billing Profile was changed successfully")), dispatch(getUserBilling())])));
1760
+ const createBillingProfile = createAppAsyncThunk(`${sliceName$4}/createBillingProfileEmail`, ({ billingProfile }, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/billing/profile`, billingProfile).catch((err) => commonErrorHandler(err, `Failed to create billing profile`, dispatch)).then(() => Promise.all([dispatch(setSnackbar$1("Billing Profile was created successfully")), dispatch(getUserBilling())])));
1761
+ const removeTenant = createAppAsyncThunk(`${sliceName$4}/editDeviceLimit`, ({ id }, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/tenants/${id}/remove/start`).catch((err) => commonErrorHandler(err, `There was an error removing the tenant`, dispatch)).then(() => Promise.all([
1762
+ dispatch(setSnackbar$1("The tenant was removed successfully")),
1763
+ dispatch(getUserOrganization()),
1764
+ new Promise((resolve) => setTimeout(() => resolve(dispatch(getTenants())), TIMEOUTS.oneSecond))
1765
+ ])));
1766
+ const getUserOrganization = createAppAsyncThunk(`${sliceName$4}/getUserOrganization`, (_, { dispatch, getState }) => Api.get(`${tenantadmApiUrlv1}/user/tenant?tiers=true`).then((res) => {
1767
+ const { addons, plan, trial } = res.data;
1768
+ const { addons: currentAddons, id: currentId, plan: currentPlan, trial: currentTrial } = getOrganization(getState());
1769
+ const tasks = [dispatch(actions$4.setOrganization(res.data))];
1770
+ if (currentId && !deepCompare({
1771
+ addons,
1772
+ plan,
1773
+ trial
1774
+ }, {
1775
+ addons: currentAddons,
1776
+ plan: currentPlan,
1777
+ trial: currentTrial
1778
+ })) {
1779
+ const hash = hashString(tenantDataDivergedMessage);
1780
+ const { id: currentUserId } = getCurrentUser(getState());
1781
+ cookies$1.remove(`${currentUserId}${hash}`);
1782
+ tasks.push(dispatch(setAnnouncement$1(tenantDataDivergedMessage)));
1783
+ }
1784
+ return Promise.all(tasks);
1785
+ }));
1786
+ const getUserBilling = createAppAsyncThunk(`${sliceName$4}/getUserBilling`, (_, { dispatch }) => Api.get(`${tenantadmApiUrlv2}/billing/profile`).catch((err) => commonErrorHandler(err, "There was an error getting your billing profile:", dispatch, commonErrorFallback)).then((res) => dispatch(actions$4.setBillingProfile(res.data))));
1787
+ const getUserSubscription = createAppAsyncThunk(`${sliceName$4}/getUserSubscription`, async (_, { dispatch }) => {
1788
+ const currentSubscription = await dispatch(getCurrentSubscription()).unwrap();
1789
+ const currentPreview = await dispatch(getBillingPreview({ preview_mode: "next" })).unwrap();
1790
+ return dispatch(actions$4.setSubscription({
1791
+ ...currentPreview,
1792
+ ...currentSubscription
1793
+ }));
1794
+ });
1795
+ const getBillingPreview = createAppAsyncThunk(`${sliceName$4}/getBillingPreview`, (order, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/billing/subscription/invoices/preview`, order).catch((err) => commonErrorHandler(err, "There was an error getting your billing information:", dispatch, commonErrorFallback)).then(({ data }) => order.preview_mode === "recurring" ? {
1796
+ items: parseSubscriptionPreview(data.lines),
1797
+ total: data.total
1798
+ } : data));
1799
+ const getCurrentSubscription = createAppAsyncThunk(`${sliceName$4}/getCurrentSubscription`, (_, { dispatch }) => Api.get(`${tenantadmApiUrlv2}/billing/subscription`).then((res) => res.data).catch((err) => {
1800
+ if (err.response && err.response.status === 404) throw new Error("Request failed with status code 404");
1801
+ return commonErrorHandler(err, "There was an error retrieving your current subscription", dispatch, commonErrorFallback);
1802
+ }));
1803
+ const getProducts = createAppAsyncThunk(`${sliceName$4}/getEnabledTiers`, (_, { dispatch }) => Api.get(`${tenantadmApiUrlv2}/billing/products`).catch((err) => commonErrorHandler(err, "There was an error getting Mender products:", dispatch, commonErrorFallback)).then((res) => dispatch(actions$4.setProducts(transformProductResponse(res.data)))));
1804
+ const requestPlanUpgrade = createAppAsyncThunk(`${sliceName$4}/requestPlanUpgrade`, (order, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/billing/subscription`, order).catch((err) => commonErrorHandler(err, "There was an error sending your request", dispatch, commonErrorFallback)).then(() => Promise.all([setTimeout(() => dispatch(getDeviceLimits()), TIMEOUTS.threeSeconds), dispatch(getUserOrganization())])));
1805
+ const sendSupportMessage = createAppAsyncThunk(`${sliceName$4}/sendSupportMessage`, (content, { dispatch }) => Api.post(`${tenantadmApiUrlv2}/contact/support`, content).catch((err) => commonErrorHandler(err, "There was an error sending your request", dispatch, commonErrorFallback)).then(() => Promise.resolve(dispatch(setSnackbar$1({
1806
+ message: "Your request was sent successfully",
1807
+ autoHideDuration: TIMEOUTS.fiveSeconds
1808
+ })))));
1809
+ const requestPlanChange = createAppAsyncThunk(`${sliceName$4}/requestPlanChange`, ({ content, tenantId }, { dispatch, rejectWithValue }) => Api.post(`${tenantadmApiUrlv2}/tenants/${tenantId}/plan`, content).catch(async (err) => {
1810
+ await commonErrorHandler(err, "There was an error sending your request", dispatch, commonErrorFallback);
1811
+ rejectWithValue(err);
1812
+ }).then(() => Promise.resolve(dispatch(setSnackbar$1({
1813
+ message: "Your request was sent successfully",
1814
+ autoHideDuration: TIMEOUTS.fiveSeconds
1815
+ })))));
1816
+ const downloadLicenseReport = createAppAsyncThunk(`${sliceName$4}/downloadLicenseReport`, (_, { dispatch }) => Api.get(`${deviceAuthV2}/license`).catch((err) => commonErrorHandler(err, "There was an error downloading the report", dispatch, commonErrorFallback)).then((res) => res.data));
1817
+ const createIntegration = createAppAsyncThunk(`${sliceName$4}/createIntegration`, ({ id, ...integration }, { dispatch }) => Api.post(`${iotManagerBaseURL}/integrations`, integration).catch((err) => commonErrorHandler(err, "There was an error creating the integration", dispatch, commonErrorFallback)).then(() => Promise.all([dispatch(setSnackbar$1("The integration was set up successfully")), dispatch(getIntegrations())])));
1818
+ const changeIntegration = createAppAsyncThunk(`${sliceName$4}/changeIntegration`, ({ id, credentials }, { dispatch }) => Api.put(`${iotManagerBaseURL}/integrations/${id}/credentials`, credentials).catch((err) => commonErrorHandler(err, "There was an error updating the integration", dispatch, commonErrorFallback)).then(() => Promise.all([dispatch(setSnackbar$1("The integration was updated successfully")), dispatch(getIntegrations())])));
1819
+ const deleteIntegration = createAppAsyncThunk(`${sliceName$4}/deleteIntegration`, ({ id, provider }, { dispatch, getState }) => Api.delete(`${iotManagerBaseURL}/integrations/${id}`, {}).catch((err) => commonErrorHandler(err, "There was an error removing the integration", dispatch, commonErrorFallback)).then(() => {
1820
+ const integrations = getState().organization.externalDeviceIntegrations.filter((item) => provider !== item.provider);
1821
+ return Promise.all([dispatch(setSnackbar$1("The integration was removed successfully")), dispatch(actions$4.receiveExternalDeviceIntegrations(integrations))]);
1822
+ }));
1823
+ const getIntegrations = createAppAsyncThunk(`${sliceName$4}/getIntegrations`, (_, { dispatch, getState }) => Api.get(`${iotManagerBaseURL}/integrations`).catch((err) => commonErrorHandler(err, "There was an error retrieving the integration", dispatch, commonErrorFallback)).then(({ data }) => {
1824
+ const existingIntegrations = getState().organization.externalDeviceIntegrations;
1825
+ const integrations = data.reduce((accu, item) => {
1826
+ const integration = {
1827
+ ...existingIntegrations.find((integration) => item.id === integration.id) ?? {},
1828
+ ...item
1829
+ };
1830
+ accu.push(integration);
1831
+ return accu;
1832
+ }, []);
1833
+ return Promise.resolve(dispatch(actions$4.receiveExternalDeviceIntegrations(integrations)));
1834
+ }));
1835
+ const getWebhookEvents = createAppAsyncThunk(`${sliceName$4}/getWebhookEvents`, (config = {}, { dispatch, getState }) => {
1836
+ const { isFollowUp, page = defaultPage, perPage = defaultPerPage } = config;
1837
+ return Api.get(`${iotManagerBaseURL}/events?page=${page}&per_page=${perPage}`).catch((err) => commonErrorHandler(err, "There was an error retrieving activity for this integration", dispatch, commonErrorFallback)).then(({ data }) => {
1838
+ const tasks = [Promise.resolve(dispatch(actions$4.receiveWebhookEvents({
1839
+ value: isFollowUp ? getState().organization.webhooks.events : data,
1840
+ total: (page - 1) * perPage + data.length
1841
+ })))];
1842
+ if (data.length >= perPage && !isFollowUp) tasks.push(dispatch(getWebhookEvents({
1843
+ isFollowUp: true,
1844
+ page: page + 1,
1845
+ perPage: 1
1846
+ })));
1847
+ return Promise.all(tasks);
1848
+ });
1849
+ });
1850
+ const ssoConfigActions = {
1851
+ create: {
1852
+ success: "stored",
1853
+ error: "storing"
1854
+ },
1855
+ edit: {
1856
+ success: "updated",
1857
+ error: "updating"
1858
+ },
1859
+ read: {
1860
+ success: "",
1861
+ error: "retrieving"
1862
+ },
1863
+ remove: {
1864
+ success: "removed",
1865
+ error: "removing"
1866
+ },
1867
+ readMultiple: {
1868
+ success: "",
1869
+ error: "retrieving"
1870
+ }
1871
+ };
1872
+ const ssoConfigActionErrorHandler = (err, type) => (dispatch) => commonErrorHandler(err, `There was an error ${ssoConfigActions[type].error} the SSO configuration.`, dispatch, commonErrorFallback);
1873
+ const ssoConfigActionSuccessHandler = (type) => (dispatch) => dispatch(setSnackbar$1(`The SSO configuration was ${ssoConfigActions[type].success} successfully`));
1874
+ const storeSsoConfig = createAppAsyncThunk(`${sliceName$4}/storeSsoConfig`, ({ config, contentType }, { dispatch }) => Api.post(ssoIdpApiUrlv1, config, { headers: {
1875
+ "Content-Type": contentType,
1876
+ Accept: "application/json"
1877
+ } }).catch((err) => dispatch(ssoConfigActionErrorHandler(err, "create"))).then(() => Promise.all([dispatch(ssoConfigActionSuccessHandler("create")), dispatch(getSsoConfigs())])));
1878
+ const changeSsoConfig = createAppAsyncThunk(`${sliceName$4}/changeSsoConfig`, ({ config, contentType }, { dispatch }) => Api.put(`${ssoIdpApiUrlv1}/${config.id}`, config.config, { headers: {
1879
+ "Content-Type": contentType,
1880
+ Accept: "application/json"
1881
+ } }).catch((err) => dispatch(ssoConfigActionErrorHandler(err, "edit"))).then(() => Promise.all([dispatch(ssoConfigActionSuccessHandler("edit")), dispatch(getSsoConfigs())])));
1882
+ const deleteSsoConfig = createAppAsyncThunk(`${sliceName$4}/deleteSsoConfig`, ({ id }, { dispatch, getState }) => Api.delete(`${ssoIdpApiUrlv1}/${id}`).catch((err) => dispatch(ssoConfigActionErrorHandler(err, "remove"))).then(() => {
1883
+ const configs = getState().organization.ssoConfigs.filter((item) => id !== item.id);
1884
+ return Promise.all([dispatch(ssoConfigActionSuccessHandler("remove")), dispatch(actions$4.receiveSsoConfigs(configs))]);
1885
+ }));
1886
+ const getSsoConfigById = createAppAsyncThunk(`${sliceName$4}/getSsoConfigById`, (config, { dispatch }) => Api.get(`${ssoIdpApiUrlv1}/${config.id}`).catch((err) => dispatch(ssoConfigActionErrorHandler(err, "read"))).then(({ data, headers }) => {
1887
+ const sso = Object.values(SSO_TYPES).find(({ contentType }) => contentType === headers["content-type"]);
1888
+ return sso ? Promise.resolve({
1889
+ ...config,
1890
+ config: data,
1891
+ type: sso.id
1892
+ }) : Promise.reject("Unsupported SSO config content type.");
1893
+ }));
1894
+ const getSsoConfigs = createAppAsyncThunk(`${sliceName$4}/getSsoConfigs`, (_, { dispatch }) => Api.get(ssoIdpApiUrlv1).catch((err) => dispatch(ssoConfigActionErrorHandler(err, "readMultiple"))).then(({ data }) => Promise.all(data.map((config) => dispatch(getSsoConfigById(config)).unwrap())).then((configs) => dispatch(actions$4.receiveSsoConfigs(configs))).catch((err) => commonErrorHandler(err, err, dispatch, ""))));
1895
+ //#endregion
1896
+ //#region src/usersSlice/thunks.ts
1897
+ const cookies = new Cookies();
1898
+ const { setAnnouncement, setSnackbar } = actions_default;
1899
+ const handleLoginError = (err, { token2fa: has2FA, password }, rejectWithValue) => () => {
1900
+ const is2FABackend = extractErrorMessage(err).includes("2fa");
1901
+ if (is2FABackend && !has2FA) return rejectWithValue({ error: "2fa code missing" });
1902
+ if (password === void 0) return Promise.reject();
1903
+ const twoFAError = is2FABackend ? " and verification code" : "";
1904
+ return rejectWithValue({ error: `There was a problem logging in. Please check your email${twoFAError ? "," : " and"} password${twoFAError}. If you still have problems, contact an administrator.` });
1905
+ };
1906
+ const loginUser = createAppAsyncThunk(`${sliceName$5}/loginUser`, ({ stayLoggedIn, ...userData }, { dispatch, rejectWithValue }) => Api$1.postLogin(`${useradmApiUrl}/auth/login`, {
1907
+ ...userData,
1908
+ no_expiry: stayLoggedIn
1909
+ }).catch((err) => {
1910
+ cleanUp();
1911
+ return Promise.reject(dispatch(handleLoginError(err, userData, rejectWithValue)));
1912
+ }).then(({ text: token, contentType }) => {
1913
+ if (contentType?.includes(APPLICATION_JSON_CONTENT_TYPE)) {
1914
+ const { id, kind } = token;
1915
+ const ssoLoginUrl = SSO_TYPES[kind.split("/")[1]].getStartUrl(id);
1916
+ window.location.replace(ssoLoginUrl);
1917
+ return;
1918
+ }
1919
+ if (contentType !== APPLICATION_JWT_CONTENT_TYPE || !token) return;
1920
+ const now = /* @__PURE__ */ new Date();
1921
+ now.setSeconds(now.getSeconds() + maxSessionAge);
1922
+ const expiresAt = stayLoggedIn ? void 0 : now.toISOString();
1923
+ setSessionInfo({
1924
+ token,
1925
+ expiresAt
1926
+ });
1927
+ cookies.remove("JWT", { path: "/" });
1928
+ return dispatch(getUser("me")).unwrap().catch((e) => {
1929
+ cleanUp();
1930
+ return Promise.reject(dispatch(setSnackbar(extractErrorMessage(e))));
1931
+ }).then(() => {
1932
+ window.sessionStorage.removeItem("pendings-redirect");
1933
+ if (window.location.pathname !== "/ui/") window.location.replace("/ui/");
1934
+ return Promise.resolve(dispatch(actions$5.successfullyLoggedIn({
1935
+ expiresAt,
1936
+ token
1937
+ })));
1938
+ });
1939
+ }));
1940
+ const logoutUser = createAppAsyncThunk(`${sliceName$5}/logoutUser`, (_, { dispatch, getState }) => {
1941
+ if (Object.keys(getState().app.uploadsById).length) return Promise.reject();
1942
+ return Api.post(`${useradmApiUrl}/auth/logout`).finally(() => {
1943
+ cleanUp();
1944
+ clearAllRetryTimers(setSnackbar);
1945
+ return Promise.resolve(dispatch({ type: USER_LOGOUT }));
1946
+ });
1947
+ });
1948
+ const switchUserOrganization = createAppAsyncThunk(`${sliceName$5}/switchUserOrganization`, (tenantId, { getState }) => {
1949
+ if (Object.keys(getState().app.uploadsById).length) return Promise.reject();
1950
+ return Api.get(`${useradmApiUrl}/users/tenants/${tenantId}/token`).then(({ data: token }) => {
1951
+ window.sessionStorage.setItem("tenantChanged", "true");
1952
+ setSessionInfo({
1953
+ ...getSessionInfo(),
1954
+ token
1955
+ });
1956
+ window.location.reload();
1957
+ });
1958
+ });
1959
+ const passwordResetStart = createAppAsyncThunk(`${sliceName$5}/passwordResetStart`, (email, { dispatch }) => Api.post(`${useradmApiUrl}/auth/password-reset/start`, { email }).catch((err) => commonErrorHandler(err, `The password reset request cannot be processed:`, dispatch, void 0, true)));
1960
+ const passwordResetComplete = createAppAsyncThunk(`${sliceName$5}/passwordResetComplete`, ({ secretHash, newPassword }, { dispatch }) => Api.post(`${useradmApiUrl}/auth/password-reset/complete`, {
1961
+ secret_hash: secretHash,
1962
+ password: newPassword
1963
+ }).catch((err = {}) => {
1964
+ const { error, response = {} } = err;
1965
+ let errorMsg = "";
1966
+ if (response.status == 400) errorMsg = "the link you are using expired or the request is not valid, please try again.";
1967
+ else errorMsg = error;
1968
+ dispatch(setSnackbar("The password reset request cannot be processed: " + errorMsg));
1969
+ return Promise.reject(err);
1970
+ }));
1971
+ const verifyEmailStart = createAppAsyncThunk(`${sliceName$5}/verifyEmailStart`, (_, { dispatch, getState }) => Api.post(`${useradmApiUrl}/auth/verify-email/start`, { email: getCurrentUser(getState()).email }).catch((err) => commonErrorHandler(err, "An error occured starting the email verification process:", dispatch)).finally(() => Promise.resolve(dispatch(getUser("me")))));
1972
+ const verifyEmailComplete = createAppAsyncThunk(`${sliceName$5}/verifyEmailComplete`, (secret_hash, { dispatch, rejectWithValue }) => Api.post(`${useradmApiUrl}/auth/verify-email/complete`, { secret_hash }).catch((err) => rejectWithValue({
1973
+ status: err.response?.status,
1974
+ data: err.response?.data
1975
+ })).finally(() => Promise.resolve(dispatch(getUser("me")))));
1976
+ const verify2FA = createAppAsyncThunk(`${sliceName$5}/verify2FA`, (tfaData, { dispatch }) => Api$1.putVerifyTFA(`${useradmApiUrl}/2faverify`, tfaData).then(() => Promise.resolve(dispatch(getUser("me")))).catch((err) => commonErrorHandler(err, "An error occured validating the verification code: failed to verify token, please try again.", dispatch, void 0, true)));
1977
+ const getUserList = createAppAsyncThunk(`${sliceName$5}/getUserList`, (_, { dispatch, getState }) => Api.get(`${useradmApiUrl}/users`).then((res) => {
1978
+ const currentUsersById = getUsersById(getState());
1979
+ const users = res.data.reduce((accu, item) => {
1980
+ accu[item.id] = {
1981
+ ...accu[item.id],
1982
+ ...item
1983
+ };
1984
+ return accu;
1985
+ }, { ...currentUsersById });
1986
+ return dispatch(actions$5.receivedUserList(users));
1987
+ }).catch((err) => commonErrorHandler(err, `Users couldn't be loaded.`, dispatch, commonErrorFallback)));
1988
+ const getUser = createAppAsyncThunk(`${sliceName$5}/getUser`, (id, { dispatch, rejectWithValue }) => Api.get(`${useradmApiUrl}/users/${id}`).then(({ data: user }) => Promise.all([
1989
+ dispatch(actions$5.receivedUser(user)),
1990
+ dispatch(setHideAnnouncement({
1991
+ shouldHide: false,
1992
+ userId: user.id
1993
+ })),
1994
+ dispatch(updateUserColumnSettings({ currentUserId: user.id })),
1995
+ user
1996
+ ])).catch((e) => rejectWithValue(e)));
1997
+ const initializeSelf = createAppAsyncThunk(`${sliceName$5}/initializeSelf`, (_, { dispatch }) => dispatch(getUser("me")));
1998
+ const updateUserColumnSettings = createAppAsyncThunk(`${sliceName$5}/updateUserColumnSettings`, ({ columns, currentUserId }, { dispatch, getState }) => {
1999
+ const storageKey = `${currentUserId ?? getCurrentUser(getState()).id}-column-widths`;
2000
+ let customColumns = [];
2001
+ if (!columns) try {
2002
+ customColumns = JSON.parse(window.localStorage.getItem(storageKey) || "") || customColumns;
2003
+ } catch {}
2004
+ else customColumns = columns;
2005
+ window.localStorage.setItem(storageKey, JSON.stringify(customColumns));
2006
+ return Promise.resolve(dispatch(actions$5.setCustomColumns(customColumns)));
2007
+ });
2008
+ const userActions = {
2009
+ add: {
2010
+ successMessage: "The user was added successfully.",
2011
+ errorMessage: "adding"
2012
+ },
2013
+ create: {
2014
+ successMessage: "The user was created successfully.",
2015
+ errorMessage: "creating"
2016
+ },
2017
+ edit: {
2018
+ successMessage: "The user has been updated.",
2019
+ errorMessage: "editing"
2020
+ },
2021
+ remove: {
2022
+ successMessage: "The user was removed from the system.",
2023
+ errorMessage: "removing"
2024
+ }
2025
+ };
2026
+ const userActionErrorHandler = (err, type, dispatch) => commonErrorHandler(err, `There was an error ${userActions[type].errorMessage} the user.`, dispatch);
2027
+ const createUser = createAppAsyncThunk(`${sliceName$5}/createUser`, ({ shouldResetPassword, ...userData }, { dispatch }) => Api.post(`${useradmApiUrl}/users`, {
2028
+ ...userData,
2029
+ send_reset_password: shouldResetPassword
2030
+ }).then(() => Promise.all([dispatch(getUserList()), dispatch(setSnackbar(userActions.create.successMessage))])).catch((err) => userActionErrorHandler(err, "create", dispatch)));
2031
+ const removeUser = createAppAsyncThunk(`${sliceName$5}/removeUser`, (userId, { dispatch }) => Api.delete(`${useradmApiUrl}/users/${userId}`).then(() => Promise.all([
2032
+ dispatch(actions$5.removedUser(userId)),
2033
+ dispatch(getUserList()),
2034
+ dispatch(setSnackbar(userActions.remove.successMessage))
2035
+ ])).catch((err) => userActionErrorHandler(err, "remove", dispatch)));
2036
+ const editUser = createAppAsyncThunk(`${sliceName$5}/editUser`, ({ id, ...userData }, { dispatch, getState }) => Api.put(`${useradmApiUrl}/users/${id}`, userData).then(() => Promise.all([dispatch(actions$5.updatedUser({
2037
+ ...userData,
2038
+ id: id === "me" ? getCurrentUser(getState()).id : id
2039
+ })), dispatch(setSnackbar(userActions.edit.successMessage))])).catch((err) => userActionErrorHandler(err, "edit", dispatch)));
2040
+ const checkEmailExists = createAppAsyncThunk(`${sliceName$5}/checkEmailExists`, async (email) => {
2041
+ return (await Api.get(`${useradmApiUrl}/users/exists?email=${encodeURIComponent(email)}`)).data.exists;
2042
+ });
2043
+ const addUserToCurrentTenant = createAppAsyncThunk(`${sliceName$5}/addUserToTenant`, (userId, { dispatch, getState }) => {
2044
+ const { id } = getOrganization(getState());
2045
+ return Api.post(`${useradmApiUrl}/users/${userId}/assign`, { tenant_ids: [id] }).catch((err) => commonErrorHandler(err, `There was an error adding the user to your organization:`, dispatch)).then(() => Promise.all([dispatch(setSnackbar(userActions.add.successMessage)), dispatch(getUserList())]));
2046
+ });
2047
+ const enableUser2fa = createAppAsyncThunk(`${sliceName$5}/enableUser2fa`, (userId = "me", { dispatch }) => Api.post(`${useradmApiUrl}/users/${userId}/2fa/enable`).catch((err) => commonErrorHandler(err, `There was an error enabling Two Factor authentication for the user.`, dispatch)).then(() => Promise.resolve(dispatch(getUser(userId)))));
2048
+ const disableUser2fa = createAppAsyncThunk(`${sliceName$5}/disableUser2fa`, (userId = "me", { dispatch }) => Api.post(`${useradmApiUrl}/users/${userId}/2fa/disable`).catch((err) => commonErrorHandler(err, `There was an error disabling Two Factor authentication for the user.`, dispatch)).then(() => Promise.all([dispatch(getUser(userId)), dispatch(actions$5.receivedQrCode(null))])));
2049
+ const mapHttpPermission = (permission) => Object.entries(uiPermissionsByArea).reduce((accu, [area, definition]) => {
2050
+ const endpointMatches = definition.endpoints.filter((endpoint) => endpoint.path.test(permission.value) && (endpoint.types.includes(permission.type) || permission.type === PermissionTypes.Any));
2051
+ if (permission.value === PermissionTypes.Any || permission.value.includes(apiRoot) && endpointMatches.length) {
2052
+ const collector = (endpointMatches.reduce((endpointAccu, endpoint) => [...endpointAccu, ...endpoint.uiPermissions], []) || definition.uiPermissions).reduce((permissionsAccu, uiPermission) => {
2053
+ if (permission.type === PermissionTypes.Any || !endpointMatches.length && uiPermission.verbs.some((verb) => verb === permission.type)) permissionsAccu.push(uiPermission.value);
2054
+ return permissionsAccu;
2055
+ }, []).filter(duplicateFilter);
2056
+ if (Array.isArray(accu[area])) accu[area] = [...accu[area], ...collector].filter(duplicateFilter);
2057
+ else accu[area] = mergePermissions(accu[area], { [scopedPermissionAreas[area].excessiveAccessSelector]: collector });
2058
+ }
2059
+ return accu;
2060
+ }, { ...emptyUiPermissions });
2061
+ const permissionActionTypes = {
2062
+ any: mapHttpPermission,
2063
+ CREATE_DEPLOYMENT: (permission) => permission.type === PermissionTypes.DeviceGroup ? {
2064
+ deployments: [uiPermissionsById.deploy.value],
2065
+ groups: { [permission.value]: [uiPermissionsById.deploy.value] }
2066
+ } : {},
2067
+ http: mapHttpPermission,
2068
+ REMOTE_TERMINAL: (permission) => permission.type === PermissionTypes.DeviceGroup ? { groups: { [permission.value]: [uiPermissionsById.connect.value] } } : {},
2069
+ VIEW_DEVICE: (permission) => permission.type === PermissionTypes.DeviceGroup ? { groups: { [permission.value]: [uiPermissionsById.read.value] } } : {}
2070
+ };
2071
+ const combinePermissions = (existingPermissions, additionalPermissions = {}) => Object.entries(additionalPermissions).reduce((accu, [name, permissions]) => {
2072
+ const maybeExistingPermissions = accu[name] || [];
2073
+ accu[name] = [...permissions, ...maybeExistingPermissions].filter(duplicateFilter);
2074
+ return accu;
2075
+ }, existingPermissions);
2076
+ const tryParseCustomPermission = (permission) => {
2077
+ const uiPermissions = permissionActionTypes[permission.action](permission.object);
2078
+ return {
2079
+ isCustom: true,
2080
+ permission,
2081
+ result: mergePermissions({ ...emptyUiPermissions }, uiPermissions)
2082
+ };
2083
+ };
2084
+ const customPermissionHandler = (accu, permission) => {
2085
+ const processor = tryParseCustomPermission(permission);
2086
+ return {
2087
+ ...accu,
2088
+ isCustom: accu.isCustom || processor.isCustom,
2089
+ uiPermissions: mergePermissions(accu.uiPermissions, processor.result)
2090
+ };
2091
+ };
2092
+ const mapPermissionSet = (permissionSetName, names, scope, existingGroupsPermissions = {}) => {
2093
+ const permission = Object.values(uiPermissionsById).find((permission) => permission.permissionSets[scope] === permissionSetName)?.value;
2094
+ const scopedPermissions = names.reduce((accu, name) => combinePermissions(accu, { [name]: [permission] }), existingGroupsPermissions);
2095
+ return Object.entries(scopedPermissions).reduce((accu, [key, permissions]) => ({
2096
+ ...accu,
2097
+ [key]: deriveImpliedAreaPermissions(scope, permissions)
2098
+ }), {});
2099
+ };
2100
+ const isEmptyPermissionSet = (permissionSet) => !Object.values(permissionSet).reduce((accu, permissions) => {
2101
+ if (Array.isArray(permissions)) return accu || !!permissions.length;
2102
+ return accu || !isEmpty(permissions);
2103
+ }, false);
2104
+ const parseRolePermissions = ({ permission_sets_with_scope = [], permissions = [] }, permissionSets) => {
2105
+ const preliminaryResult = permission_sets_with_scope.reduce((accu, permissionSet) => {
2106
+ if (!permissionSet.name) return accu;
2107
+ const processor = permissionSets[permissionSet.name];
2108
+ if (!processor) return accu;
2109
+ const scope = Object.keys(scopedPermissionAreas).find((scope) => uiPermissionsByArea[scope].scope === permissionSet.scope?.type);
2110
+ if (scope) {
2111
+ const result = mapPermissionSet(permissionSet.name, permissionSet.scope?.value ?? [], scope, accu.uiPermissions[scope]);
2112
+ return {
2113
+ ...accu,
2114
+ uiPermissions: {
2115
+ ...accu.uiPermissions,
2116
+ [scope]: result
2117
+ }
2118
+ };
2119
+ } else if (isEmptyPermissionSet(processor.result)) return processor.permissions?.reduce(customPermissionHandler, accu);
2120
+ return {
2121
+ ...accu,
2122
+ isCustom: accu.isCustom || processor.isCustom,
2123
+ uiPermissions: mergePermissions(accu.uiPermissions, processor.result)
2124
+ };
2125
+ }, {
2126
+ isCustom: false,
2127
+ uiPermissions: {
2128
+ ...emptyUiPermissions,
2129
+ groups: {},
2130
+ releases: {}
2131
+ }
2132
+ });
2133
+ return permissions.reduce(customPermissionHandler, preliminaryResult);
2134
+ };
2135
+ const normalizeRbacRoles = (roles, rolesById$1, permissionSets) => roles.reduce((accu, role) => {
2136
+ let normalizedPermissions;
2137
+ let isCustom = false;
2138
+ if (rolesById$1[role.name]) normalizedPermissions = {
2139
+ ...rolesById$1[role.name].uiPermissions,
2140
+ groups: { ...rolesById$1[role.name].uiPermissions.groups },
2141
+ releases: { ...rolesById$1[role.name].uiPermissions.releases }
2142
+ };
2143
+ else {
2144
+ const result = parseRolePermissions(role, permissionSets);
2145
+ normalizedPermissions = result.uiPermissions;
2146
+ isCustom = result.isCustom;
2147
+ }
2148
+ const roleState = accu[role.name] ?? { ...emptyRole };
2149
+ accu[role.name] = {
2150
+ ...roleState,
2151
+ ...role,
2152
+ description: roleState.description ? roleState.description : role.description,
2153
+ editable: !rolesById[role.name] && !isCustom && (typeof roleState.editable !== "undefined" ? roleState.editable : true),
2154
+ isCustom,
2155
+ name: roleState.name ? roleState.name : role.name,
2156
+ uiPermissions: normalizedPermissions
2157
+ };
2158
+ return accu;
2159
+ }, { ...rolesById$1 });
2160
+ const getPermissionSets = createAppAsyncThunk(`${sliceName$5}/getPermissionSets`, (_, { dispatch, getState }) => Api.get(`${useradmApiUrlv2}/permission_sets?per_page=500`).then(({ data }) => {
2161
+ const permissionSets = data.reduce((accu, permissionSet) => {
2162
+ let permissionSetObject = {
2163
+ ...accu[permissionSet.name] ?? {},
2164
+ ...permissionSet
2165
+ };
2166
+ permissionSetObject.result = Object.values(uiPermissionsById).reduce((accu, item) => Object.entries(item.permissionSets).reduce((collector, [area, permissionSet]) => {
2167
+ if (scopedPermissionAreas[area]) return collector;
2168
+ if (permissionSet === permissionSetObject.name) collector[area] = [...collector[area], item.value].filter(duplicateFilter);
2169
+ return collector;
2170
+ }, accu), {
2171
+ ...emptyUiPermissions,
2172
+ ...permissionSetObject.result ?? {}
2173
+ });
2174
+ permissionSetObject = Object.values(scopedPermissionAreas).reduce((accu, { key, scopeType }) => {
2175
+ if (permissionSetObject.supported_scope_types?.includes(key) || permissionSetObject.supported_scope_types?.includes(scopeType)) accu.push(key);
2176
+ return accu;
2177
+ }, []).reduce((accu, scope) => {
2178
+ accu.result = {
2179
+ ...accu.result,
2180
+ [scope]: mapPermissionSet(permissionSetObject.name, [scopedPermissionAreas[scope].excessiveAccessSelector], scope)
2181
+ };
2182
+ return accu;
2183
+ }, permissionSetObject);
2184
+ accu[permissionSet.name] = permissionSetObject;
2185
+ return accu;
2186
+ }, { ...getState().users.permissionSetsById });
2187
+ return Promise.all([Promise.resolve(dispatch(actions$5.receivedPermissionSets(permissionSets))), Promise.resolve(permissionSets)]);
2188
+ }).catch(() => console.log("Permission set retrieval failed - likely accessing a non-RBAC backend")));
2189
+ const getRoles = createAppAsyncThunk(`${sliceName$5}/getRoles`, async (_, { dispatch, getState }) => {
2190
+ try {
2191
+ const [{ data: roles }, permissionSetResult] = await Promise.all([Api.get(`${useradmApiUrlv2}/roles?per_page=500`), dispatch(getPermissionSets())]);
2192
+ const permissionSetTasks = permissionSetResult.payload;
2193
+ const rolesById = normalizeRbacRoles(roles, getRolesById(getState()), permissionSetTasks[permissionSetTasks.length - 1]);
2194
+ return dispatch(actions$5.receivedRoles(rolesById));
2195
+ } catch {
2196
+ console.log("Role retrieval failed - likely accessing a non-RBAC backend");
2197
+ } finally {
2198
+ dispatch(actions$5.finishedRoleInitialization(true));
2199
+ }
2200
+ });
2201
+ const deriveImpliedAreaPermissions = (area, areaPermissions, skipPermissions = []) => {
2202
+ const highestAreaPermissionLevelSelected = areaPermissions.reduce((highest, current) => uiPermissionsById[current].permissionLevel > highest ? uiPermissionsById[current].permissionLevel : highest, 1);
2203
+ return uiPermissionsByArea[area].uiPermissions.reduce((permissions, current) => {
2204
+ if ((current.permissionLevel < highestAreaPermissionLevelSelected || areaPermissions.includes(current.value)) && !skipPermissions.includes(current.value)) permissions.push(current.value);
2205
+ return permissions;
2206
+ }, []);
2207
+ };
2208
+ /**
2209
+ * transforms [{ group: "groupName", uiPermissions: ["read", "manage", "connect"] }, ...] to
2210
+ * [{ name: "ReadDevices", scope: { type: "DeviceGroups", value: ["groupName", ...] } }, ...]
2211
+ */
2212
+ const transformAreaRoleDataToScopedPermissionsSets = (area, areaPermissions, excessiveAccessSelector) => {
2213
+ const permissionSetObject = areaPermissions.reduce((accu, { item, uiPermissions }) => {
2214
+ accu = deriveImpliedAreaPermissions(area, uiPermissions, scopedPermissionAreas.releases.key === area && item !== ALL_RELEASES ? [uiPermissionsById.upload.value] : []).reduce((itemPermissionAccu, impliedPermission) => {
2215
+ const permissionSetState = itemPermissionAccu[uiPermissionsById[impliedPermission].permissionSets[area]] ?? {
2216
+ type: uiPermissionsByArea[area].scope,
2217
+ value: []
2218
+ };
2219
+ itemPermissionAccu[uiPermissionsById[impliedPermission].permissionSets[area]] = {
2220
+ ...permissionSetState,
2221
+ value: [...permissionSetState.value, item]
2222
+ };
2223
+ return itemPermissionAccu;
2224
+ }, accu);
2225
+ return accu;
2226
+ }, {});
2227
+ return Object.entries(permissionSetObject).map(([name, { value, ...scope }]) => {
2228
+ if (value.includes(excessiveAccessSelector)) return { name };
2229
+ return {
2230
+ name,
2231
+ scope: {
2232
+ ...scope,
2233
+ value: value.filter(duplicateFilter)
2234
+ }
2235
+ };
2236
+ });
2237
+ };
2238
+ const transformRoleDataToRole = (roleData, roleState = {}) => {
2239
+ const role = {
2240
+ ...roleState,
2241
+ ...roleData
2242
+ };
2243
+ const { description = "", name, uiPermissions = emptyUiPermissions } = role;
2244
+ const { maybeUiPermissions, remainderKeys } = Object.entries(emptyUiPermissions).reduce((accu, [key, emptyPermissions]) => {
2245
+ if (!scopedPermissionAreas[key]) accu.remainderKeys.push(key);
2246
+ else if (uiPermissions[key]) accu.maybeUiPermissions[key] = uiPermissions[key].reduce(itemUiPermissionsReducer, emptyPermissions);
2247
+ return accu;
2248
+ }, {
2249
+ maybeUiPermissions: {},
2250
+ remainderKeys: []
2251
+ });
2252
+ const { permissionSetsWithScope, roleUiPermissions } = remainderKeys.reduce((accu, area) => {
2253
+ const areaPermissions = role.uiPermissions[area];
2254
+ if (!Array.isArray(areaPermissions)) return accu;
2255
+ const impliedPermissions = deriveImpliedAreaPermissions(area, areaPermissions);
2256
+ accu.roleUiPermissions[area] = impliedPermissions;
2257
+ const mappedPermissions = impliedPermissions.map((uiPermission) => ({ name: uiPermissionsById[uiPermission].permissionSets[area] }));
2258
+ accu.permissionSetsWithScope.push(...mappedPermissions);
2259
+ return accu;
2260
+ }, {
2261
+ permissionSetsWithScope: [{ name: defaultPermissionSets.Basic.name }],
2262
+ roleUiPermissions: {}
2263
+ });
2264
+ const scopedPermissionSets = Object.values(scopedPermissionAreas).reduce((accu, { key, excessiveAccessSelector }) => {
2265
+ if (!uiPermissions[key]) return accu;
2266
+ accu.push(...transformAreaRoleDataToScopedPermissionsSets(key, uiPermissions[key], excessiveAccessSelector));
2267
+ return accu;
2268
+ }, []);
2269
+ return {
2270
+ permissionSetsWithScope: [...permissionSetsWithScope, ...scopedPermissionSets],
2271
+ role: {
2272
+ ...emptyRole,
2273
+ name,
2274
+ description: description ? description : roleState.description || "",
2275
+ uiPermissions: {
2276
+ ...emptyUiPermissions,
2277
+ ...roleUiPermissions,
2278
+ ...maybeUiPermissions
2279
+ }
2280
+ }
2281
+ };
2282
+ };
2283
+ const roleActions = {
2284
+ create: {
2285
+ successMessage: "The role was created successfully.",
2286
+ errorMessage: "creating"
2287
+ },
2288
+ edit: {
2289
+ successMessage: "The role has been updated.",
2290
+ errorMessage: "editing"
2291
+ },
2292
+ remove: {
2293
+ successMessage: "The role was deleted successfully.",
2294
+ errorMessage: "removing"
2295
+ }
2296
+ };
2297
+ const roleActionErrorHandler = (err, type, dispatch, meta) => {
2298
+ let errorContext = `There was an error ${roleActions[type].errorMessage} the role.`;
2299
+ if (meta) {
2300
+ const { permissionSetsCreated, name } = meta;
2301
+ errorContext += ` Tried to ${type} role ${name} with ${permissionSetsCreated} permission sets.`;
2302
+ }
2303
+ return commonErrorHandler(err, errorContext, dispatch);
2304
+ };
2305
+ const createRole = createAppAsyncThunk(`${sliceName$5}/createRole`, (roleData, { dispatch }) => {
2306
+ const { permissionSetsWithScope, role } = transformRoleDataToRole(roleData);
2307
+ return Api.post(`${useradmApiUrlv2}/roles`, {
2308
+ name: role.name,
2309
+ description: role.description,
2310
+ permission_sets_with_scope: permissionSetsWithScope
2311
+ }).then(() => Promise.all([
2312
+ dispatch(actions$5.createdRole(role)),
2313
+ dispatch(getRoles()),
2314
+ dispatch(setSnackbar(roleActions.create.successMessage))
2315
+ ])).catch((err) => roleActionErrorHandler(err, "create", dispatch, {
2316
+ permissionSetsCreated: permissionSetsWithScope.length,
2317
+ name: role.name
2318
+ }));
2319
+ });
2320
+ const editRole = createAppAsyncThunk(`${sliceName$5}/editRole`, (roleData, { dispatch, getState }) => {
2321
+ const { permissionSetsWithScope, role } = transformRoleDataToRole(roleData, getRolesById(getState())[roleData.name]);
2322
+ return Api.put(`${useradmApiUrlv2}/roles/${role.name}`, {
2323
+ description: role.description,
2324
+ name: role.name,
2325
+ permission_sets_with_scope: permissionSetsWithScope
2326
+ }).then(() => Promise.all([
2327
+ dispatch(actions$5.createdRole(role)),
2328
+ dispatch(getRoles()),
2329
+ dispatch(setSnackbar(roleActions.edit.successMessage))
2330
+ ])).catch((err) => roleActionErrorHandler(err, "edit", dispatch, {
2331
+ permissionSetsCreated: permissionSetsWithScope.length,
2332
+ name: role.name
2333
+ }));
2334
+ });
2335
+ const removeRole = createAppAsyncThunk(`${sliceName$5}/removeRole`, (roleId, { dispatch }) => Api.delete(`${useradmApiUrlv2}/roles/${roleId}`).then(() => Promise.all([
2336
+ dispatch(actions$5.removedRole(roleId)),
2337
+ dispatch(getRoles()),
2338
+ dispatch(setSnackbar(roleActions.remove.successMessage))
2339
+ ])).catch((err) => roleActionErrorHandler(err, "remove", dispatch)));
2340
+ const getGlobalSettings = createAppAsyncThunk(`${sliceName$5}/getGlobalSettings`, async (_, { dispatch }) => {
2341
+ const { data: settings, headers: { etag } } = await Api.get(`${useradmApiUrl}/settings`);
2342
+ window.sessionStorage.setItem(settingsKeys.initialized, "true");
2343
+ await Promise.all([dispatch(actions$5.setGlobalSettings(settings)), dispatch(setOfflineThreshold())]);
2344
+ return { etag };
2345
+ });
2346
+ const saveGlobalSettings = createAppAsyncThunk(`${sliceName$5}/saveGlobalSettings`, ({ beOptimistic = false, notify = false, ...settings }, { dispatch, getState }) => {
2347
+ if (!window.sessionStorage.getItem(settingsKeys.initialized) && !beOptimistic) return;
2348
+ return dispatch(getGlobalSettings()).unwrap().then((result) => {
2349
+ const updatedSettings = {
2350
+ ...getState().users.globalSettings,
2351
+ ...settings
2352
+ };
2353
+ if (getCurrentUser(getState()).verified) updatedSettings["2fa"] = twoFAStates.enabled;
2354
+ else delete updatedSettings["2fa"];
2355
+ const tasks = [Promise.resolve(dispatch(actions$5.setGlobalSettings(updatedSettings)))];
2356
+ const headers = result.etag ? { "If-Match": result.etag } : {};
2357
+ return Api.post(`${useradmApiUrl}/settings`, updatedSettings, { headers }).then(() => {
2358
+ if (notify) tasks.push(Promise.resolve(dispatch(setSnackbar("Settings saved successfully"))));
2359
+ return Promise.all(tasks);
2360
+ }).catch((err) => {
2361
+ if (beOptimistic) return Promise.all(tasks);
2362
+ console.log(err);
2363
+ return commonErrorHandler(err, `The settings couldn't be saved.`, dispatch);
2364
+ });
2365
+ });
2366
+ });
2367
+ const getUserSettings = createAppAsyncThunk(`${sliceName$5}/getUserSettings`, async (_, { dispatch }) => {
2368
+ const { data: settings, headers: { etag } } = await Api.get(`${useradmApiUrl}/settings/me`);
2369
+ window.sessionStorage.setItem(settingsKeys.initialized, "true");
2370
+ dispatch(actions$5.setUserSettings(settings));
2371
+ return { etag };
2372
+ });
2373
+ const saveUserSettings = createAppAsyncThunk(`${sliceName$5}/saveUserSettings`, (settings = { onboarding: {} }, { dispatch, getState }) => {
2374
+ if (!getCurrentUser(getState()).id) return Promise.resolve();
2375
+ return dispatch(getUserSettings()).unwrap().then((result) => {
2376
+ const userSettings = getUserSettings$1(getState());
2377
+ const onboardingState = getOnboardingState$1(getState());
2378
+ const tooltipState = getTooltipsState(getState());
2379
+ const updatedSettings = {
2380
+ ...userSettings,
2381
+ ...settings,
2382
+ firstLoginTimestamp: userSettings.firstLoginTimestamp ?? dayjs().format(),
2383
+ onboarding: {
2384
+ ...onboardingState,
2385
+ ...settings.onboarding
2386
+ },
2387
+ tooltips: tooltipState
2388
+ };
2389
+ const headers = result.etag ? { "If-Match": result.etag } : {};
2390
+ return Promise.all([Promise.resolve(dispatch(actions$5.setUserSettings(updatedSettings))), Api.post(`${useradmApiUrl}/settings/me`, updatedSettings, { headers })]).catch(() => dispatch(actions$5.setUserSettings(userSettings)));
2391
+ });
2392
+ });
2393
+ const get2FAQRCode = createAppAsyncThunk(`${sliceName$5}/get2FAQRCode`, (_, { dispatch }) => Api.get(`${useradmApiUrl}/2faqr`).then((res) => dispatch(actions$5.receivedQrCode(res.data.qr))));
2394
+ const setHideAnnouncement = createAppAsyncThunk(`${sliceName$5}/setHideAnnouncement`, ({ shouldHide, userId }, { dispatch, getState }) => {
2395
+ const currentUserId = userId || getCurrentUser(getState()).id;
2396
+ const announcement = getHostedAnnouncement(getState());
2397
+ const hash = announcement ? hashString(announcement) : "";
2398
+ const announceCookie = cookies.get(`${currentUserId}${hash}`);
2399
+ if (shouldHide || hash.length && typeof announceCookie !== "undefined") {
2400
+ cookies.set(`${currentUserId}${hash}`, true, { maxAge: 604800 });
2401
+ dispatch(setAnnouncement(""));
2402
+ }
2403
+ });
2404
+ const getTokens = createAppAsyncThunk(`${sliceName$5}/getTokens`, (_, { dispatch, getState }) => Api.get(`${useradmApiUrl}/settings/tokens`).then(({ data: tokens }) => {
2405
+ const updatedUser = {
2406
+ ...getCurrentUser(getState()),
2407
+ tokens
2408
+ };
2409
+ return Promise.resolve(dispatch(actions$5.updatedUser(updatedUser)));
2410
+ }));
2411
+ const ONE_YEAR = 31536e3;
2412
+ const generateToken = createAppAsyncThunk(`${sliceName$5}/generateToken`, async ({ expiresIn = ONE_YEAR, name }, { dispatch }) => {
2413
+ const { data: token } = await Api.post(`${useradmApiUrl}/settings/tokens`, {
2414
+ name,
2415
+ expires_in: expiresIn
2416
+ }).catch((err) => commonErrorHandler(err, "There was an error creating the token:", dispatch));
2417
+ await dispatch(getTokens());
2418
+ return token;
2419
+ });
2420
+ const revokeToken = createAppAsyncThunk(`${sliceName$5}/revokeToken`, (token, { dispatch }) => Api.delete(`${useradmApiUrl}/settings/tokens/${token.id}`).then(() => Promise.resolve(dispatch(getTokens()))));
2421
+ const setTooltipReadState = createAppAsyncThunk(`${sliceName$5}/setTooltipReadState`, async ({ persist, ...remainder }, { dispatch }) => {
2422
+ dispatch(actions$5.setTooltipState(remainder));
2423
+ if (persist) await dispatch(saveUserSettings());
2424
+ });
2425
+ const setAllTooltipsReadState = createAppAsyncThunk(`${sliceName$5}/toggleHelptips`, ({ readState = READ_STATES.read, tooltipIds }, { dispatch }) => {
2426
+ const updatedTips = tooltipIds.reduce((accu, id) => ({
2427
+ ...accu,
2428
+ [id]: { readState }
2429
+ }), {});
2430
+ return Promise.resolve(dispatch(actions$5.setTooltipsState(updatedTips))).then(() => dispatch(saveUserSettings()));
2431
+ });
2432
+ const submitUserFeedback = createAppAsyncThunk(`${sliceName$5}/submitFeedback`, ({ formId, feedback }, { dispatch }) => Api.post(`${useradmApiUrlv2}/support/feedback/${formId}`, feedback).then(() => {
2433
+ if (formId === "product") {
2434
+ dispatch(saveUserSettings({ feedbackCollectedAt: (/* @__PURE__ */ new Date()).toISOString().split("T")[0] }));
2435
+ setTimeout(() => dispatch(actions$5.setShowFeedbackDialog(false)), TIMEOUTS.threeSeconds);
2436
+ }
2437
+ }));
2438
+ //#endregion
2439
+ export { abortDeployment, addDevicesToGroup, addDynamicGroup, addStaticGroup, addTenant, addUserToCurrentTenant, advanceOnboarding, applyDeviceConfig, cancelFileUpload, cancelRequest, cancelUpgrade, changeIntegration, changeNotificationSetting, changeSsoConfig, checkEmailExists, completeUpgrade, confirmCardUpdate, createArtifact, createBillingProfile, createDeployment, createIntegration, createOrganizationTrial, createRole, createUser, decommissionDevice, deleteAuthset, deleteIntegration, deleteSsoConfig, deriveDeploymentGroup, deviceFileUpload, disableUser2fa, downloadLicenseReport, editArtifact, editBillingProfile, editRole, editTenant, editUser, enableUser2fa, generateDeploymentLogAnalysis, generateToken, get2FAQRCode, getAllDeviceCounts, getAllDevicesByStatus, getAllDynamicGroupDevices, getAllGroupDevices, getArtifactInstallCount, getArtifactUrl, getAuditLogs, getAuditLogsCsvLink, getBillingPreview, getCurrentCard, getCurrentSubscription, getDeltaGenerationJobDetails, getDeltaGenerationJobs, getDeploymentDevices, getDeploymentsByStatus, getDeploymentsConfig, getDeviceAlerts, getDeviceAttributes, getDeviceAuth, getDeviceById, getDeviceConfig, getDeviceConnect, getDeviceDeployments, getDeviceFileDownloadLink, getDeviceInfo, getDeviceLimits, getDeviceLog, getDeviceMonitorConfig, getDeviceTwin, getDevicesByStatus, getDevicesWithAuth, getDynamicGroup, getDynamicGroups, getExistingReleaseTags, getGatewayDevices, getGlobalSettings, getGroupDevices, getGroups, getIntegrations, getIssueCountsByType, getLatestDeviceAlerts, getLatestReleaseInfo, getOnboardingState, getPermissionSets, getProducts, getRelease, getReleases, getReportDataWithoutBackendSupport, getRoles, getSessionDetails, getSingleDeployment, getSsoConfigById, getSsoConfigs, getSystemDevices, getTargetLocation, getTenants, getTokens, getUpdateTypes, getUser, getUserBilling, getUserList, getUserOrganization, getUserSettings, getUserSubscription, getWebhookEvents, initializeSelf, loginUser, logoutUser, normalizeRbacRoles, passwordResetComplete, passwordResetStart, preauthDevice, removeArtifact, removeDevicesFromGroup, removeDynamicGroup, removeRelease, removeReleases, removeReportsByGroupName, removeRole, removeStaticGroup, removeTenant, removeUser, requestPlanChange, requestPlanUpgrade, resetDeviceDeployments, revokeToken, saveDeltaDeploymentsConfig, saveGlobalSettings, saveUserSettings, searchDevices, selectGroup, selectRelease, sendSupportMessage, setAllTooltipsReadState, setAuditlogsState, setDeploymentsState, setDeviceConfig, setDeviceListState, setDeviceTags, setDeviceTwin, setFirstLoginAfterSignup, setHideAnnouncement, setOfflineThreshold, setOnboardingApproach, setOnboardingCanceled, setOnboardingComplete, setOnboardingDeviceType, setReleaseTags, setReleasesListState, setReleasesTags, setSearchState, setSingleReleaseTags, setTenantsListState, setTooltipReadState, startCardUpdate, startUpgrade, storeSsoConfig, submitUserFeedback, switchUserOrganization, tenantDataDivergedMessage, transformProductResponse, triggerDeviceUpdate, updateDeploymentControlMap, updateDeviceAuth, updateDevicesAuth, updateDynamicGroup, updateReleaseInfo, updateReportData, updateUserColumnSettings, uploadArtifact, verify2FA, verifyEmailComplete, verifyEmailStart };
2440
+
387
2441
  //# sourceMappingURL=thunks.js.map