@northern.tech/store 0.30.0 → 0.30.2

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