@northern.tech/store 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/.eslintrc.cjs +9 -0
  2. package/.prettierignore +1 -0
  3. package/CHANGELOG.md +12 -0
  4. package/actions.ts +32 -0
  5. package/api/general-api.test.ts +51 -0
  6. package/api/general-api.ts +60 -0
  7. package/api/types/AWSCredentials.ts +16 -0
  8. package/api/types/Actor.ts +35 -0
  9. package/api/types/Addon.ts +17 -0
  10. package/api/types/AddonTenantadm.ts +17 -0
  11. package/api/types/Alert.ts +34 -0
  12. package/api/types/AlertDetails.ts +23 -0
  13. package/api/types/AlertSubject.ts +23 -0
  14. package/api/types/ApiBurst.ts +21 -0
  15. package/api/types/ApiBurstTenantadm.ts +21 -0
  16. package/api/types/ApiLimits.ts +16 -0
  17. package/api/types/ApiLimitsTenantadm.ts +16 -0
  18. package/api/types/ApiQuota.ts +17 -0
  19. package/api/types/ApiQuotaTenantadm.ts +17 -0
  20. package/api/types/Artifact.ts +48 -0
  21. package/api/types/ArtifactDeployments.ts +48 -0
  22. package/api/types/ArtifactInfo.ts +11 -0
  23. package/api/types/ArtifactInfoDeployments.ts +11 -0
  24. package/api/types/ArtifactLink.ts +11 -0
  25. package/api/types/ArtifactTypeInfo.ts +13 -0
  26. package/api/types/ArtifactTypeInfoDeployments.ts +13 -0
  27. package/api/types/ArtifactUpdate.ts +10 -0
  28. package/api/types/ArtifactUploadLink.ts +15 -0
  29. package/api/types/Attribute.ts +36 -0
  30. package/api/types/AttributeInventory.ts +32 -0
  31. package/api/types/AuditLog.ts +26 -0
  32. package/api/types/AuthSet.ts +33 -0
  33. package/api/types/AuthSetDeviceauth.ts +37 -0
  34. package/api/types/AutoAuthRequest.ts +23 -0
  35. package/api/types/AzureSharedAccessSecret.ts +11 -0
  36. package/api/types/BillingInfo.ts +13 -0
  37. package/api/types/BinaryDeltaConfiguration.ts +15 -0
  38. package/api/types/BinaryDeltaConfigurationDeployments.ts +15 -0
  39. package/api/types/BinaryDeltaLimits.ts +15 -0
  40. package/api/types/BinaryDeltaLimitsDeployments.ts +15 -0
  41. package/api/types/BoundingBox.ts +11 -0
  42. package/api/types/CancelRequest.ts +10 -0
  43. package/api/types/CardData.ts +49 -0
  44. package/api/types/CardSetupData.ts +17 -0
  45. package/api/types/CheckoutData.ts +13 -0
  46. package/api/types/Configuration.ts +11 -0
  47. package/api/types/Count.ts +13 -0
  48. package/api/types/Credentials.ts +23 -0
  49. package/api/types/DBusSubsystem.ts +27 -0
  50. package/api/types/DeltaConfiguration.ts +14 -0
  51. package/api/types/DeltaConfigurationDeployments.ts +14 -0
  52. package/api/types/Deployment.ts +95 -0
  53. package/api/types/DeploymentAggregation.ts +18 -0
  54. package/api/types/DeploymentAggregationItem.ts +18 -0
  55. package/api/types/DeploymentAggregationTerm.ts +23 -0
  56. package/api/types/DeploymentAggregationTerms.ts +18 -0
  57. package/api/types/DeploymentAttributeProjection.ts +11 -0
  58. package/api/types/DeploymentAuditlogs.ts +11 -0
  59. package/api/types/DeploymentDeployments.ts +99 -0
  60. package/api/types/DeploymentFilterTerm.ts +37 -0
  61. package/api/types/DeploymentIdentifier.ts +10 -0
  62. package/api/types/DeploymentPhase.ts +23 -0
  63. package/api/types/DeploymentReporting.ts +46 -0
  64. package/api/types/DeploymentSearchTerms.ts +39 -0
  65. package/api/types/DeploymentSortTerm.ts +25 -0
  66. package/api/types/DeploymentStatistics.ts +15 -0
  67. package/api/types/DeploymentStatusStatistics.ts +54 -0
  68. package/api/types/Device.ts +29 -0
  69. package/api/types/DeviceAggregation.ts +18 -0
  70. package/api/types/DeviceAggregationItem.ts +18 -0
  71. package/api/types/DeviceAggregationTerm.ts +27 -0
  72. package/api/types/DeviceAggregationTerms.ts +22 -0
  73. package/api/types/DeviceAttribute.ts +23 -0
  74. package/api/types/DeviceAttributeProjection.ts +15 -0
  75. package/api/types/DeviceAuditlogs.ts +17 -0
  76. package/api/types/DeviceAuthEvent.ts +23 -0
  77. package/api/types/DeviceConfiguration.ts +16 -0
  78. package/api/types/DeviceDeployment.ts +11 -0
  79. package/api/types/DeviceDeployments.ts +31 -0
  80. package/api/types/DeviceDeviceauth.ts +42 -0
  81. package/api/types/DeviceFilterAttribute.ts +22 -0
  82. package/api/types/DeviceFilterTerm.ts +41 -0
  83. package/api/types/DeviceInventory.ts +19 -0
  84. package/api/types/DeviceInventoryInventory.ts +19 -0
  85. package/api/types/DeviceReporting.ts +22 -0
  86. package/api/types/DeviceSearchTerms.ts +39 -0
  87. package/api/types/DeviceSortTerm.ts +29 -0
  88. package/api/types/DeviceState.ts +32 -0
  89. package/api/types/DeviceStateDeviceconnect.ts +33 -0
  90. package/api/types/DeviceStateIot_manager.ts +14 -0
  91. package/api/types/DeviceStatus.ts +19 -0
  92. package/api/types/DeviceWithImage.ts +80 -0
  93. package/api/types/DirectUploadMetadata.ts +18 -0
  94. package/api/types/EmailVerificationCompletion.ts +13 -0
  95. package/api/types/EmailVerificationRequest.ts +13 -0
  96. package/api/types/Error.ts +17 -0
  97. package/api/types/ErrorAuditlogs.ts +13 -0
  98. package/api/types/ErrorDeployments.ts +17 -0
  99. package/api/types/ErrorDeviceauth.ts +13 -0
  100. package/api/types/ErrorDeviceconfig.ts +17 -0
  101. package/api/types/ErrorDeviceconnect.ts +17 -0
  102. package/api/types/ErrorDevicemonitor.ts +17 -0
  103. package/api/types/ErrorExt.ts +18 -0
  104. package/api/types/ErrorInventory.ts +17 -0
  105. package/api/types/ErrorIot_manager.ts +17 -0
  106. package/api/types/ErrorNotFound.ts +17 -0
  107. package/api/types/ErrorReporting.ts +18 -0
  108. package/api/types/ErrorTenantadm.ts +13 -0
  109. package/api/types/ErrorUseradm.ts +17 -0
  110. package/api/types/Event.ts +48 -0
  111. package/api/types/ExternalIdentity.ts +17 -0
  112. package/api/types/Features.ts +17 -0
  113. package/api/types/FileUpload.ts +23 -0
  114. package/api/types/Filter.ts +19 -0
  115. package/api/types/FilterAttribute.ts +21 -0
  116. package/api/types/FilterDefinition.ts +18 -0
  117. package/api/types/FilterDeployments.ts +19 -0
  118. package/api/types/FilterInventory.ts +20 -0
  119. package/api/types/FilterPredicate.ts +78 -0
  120. package/api/types/FilterPredicateDeployments.ts +48 -0
  121. package/api/types/FilterPredicateInventory.ts +76 -0
  122. package/api/types/GeoBoundingBox.ts +10 -0
  123. package/api/types/GeoBoundingBoxFilter.ts +6 -0
  124. package/api/types/GeoDistance.ts +17 -0
  125. package/api/types/GeoDistanceFilter.ts +10 -0
  126. package/api/types/GeoPoint.ts +15 -0
  127. package/api/types/Group.ts +10 -0
  128. package/api/types/HTTP.ts +19 -0
  129. package/api/types/IdentityData.ts +25 -0
  130. package/api/types/InputParameter.ts +8 -0
  131. package/api/types/Integration.ts +24 -0
  132. package/api/types/JobStatus.ts +13 -0
  133. package/api/types/Limit.ts +21 -0
  134. package/api/types/LimitDeployments.ts +21 -0
  135. package/api/types/LimitDeviceauth.ts +10 -0
  136. package/api/types/LimitUseradm.ts +11 -0
  137. package/api/types/Limits.ts +11 -0
  138. package/api/types/LineDescriptor.ts +11 -0
  139. package/api/types/LogSubsystem.ts +23 -0
  140. package/api/types/LoginOptions.ts +18 -0
  141. package/api/types/ManagementAPIConfiguration.ts +5 -0
  142. package/api/types/MenderTypes.ts +183 -0
  143. package/api/types/MonitorConfiguration.ts +22 -0
  144. package/api/types/NewConfigurationDeployment.ts +15 -0
  145. package/api/types/NewConfigurationDeploymentResponse.ts +10 -0
  146. package/api/types/NewDeployment.ts +42 -0
  147. package/api/types/NewDeploymentForGroup.ts +33 -0
  148. package/api/types/NewDeploymentPhase.ts +37 -0
  149. package/api/types/NewDeploymentPhaseDeployments.ts +20 -0
  150. package/api/types/NewDeploymentV2.ts +31 -0
  151. package/api/types/NewTenant.ts +41 -0
  152. package/api/types/Object.ts +35 -0
  153. package/api/types/OwnUserUpdate.ts +21 -0
  154. package/api/types/PasswordResetCompletion.ts +17 -0
  155. package/api/types/PasswordResetRequest.ts +13 -0
  156. package/api/types/Permission.ts +21 -0
  157. package/api/types/PermissionObject.ts +14 -0
  158. package/api/types/PermissionSet.ts +22 -0
  159. package/api/types/PermissionSetWithScope.ts +15 -0
  160. package/api/types/PersonalAccessToken.ts +29 -0
  161. package/api/types/PersonalAccessTokenRequest.ts +18 -0
  162. package/api/types/Plan.ts +19 -0
  163. package/api/types/PlanBindingDetails.ts +13 -0
  164. package/api/types/PlanChangeRequest.ts +14 -0
  165. package/api/types/PlanLimits.ts +12 -0
  166. package/api/types/PreAuthSet.ts +16 -0
  167. package/api/types/Release.ts +32 -0
  168. package/api/types/ReleaseDeployments.ts +32 -0
  169. package/api/types/ReleaseUpdate.ts +13 -0
  170. package/api/types/Releases.ts +9 -0
  171. package/api/types/ReleasesDeleteError.ts +21 -0
  172. package/api/types/ReleasesDeployments.ts +9 -0
  173. package/api/types/Role.ts +19 -0
  174. package/api/types/RolePermission.ts +25 -0
  175. package/api/types/RolePermissionObject.ts +17 -0
  176. package/api/types/RoleUseradm.ts +19 -0
  177. package/api/types/SAMLMetadata.ts +21 -0
  178. package/api/types/Scope.ts +19 -0
  179. package/api/types/SelectAttribute.ts +17 -0
  180. package/api/types/ServiceSubsystem.ts +19 -0
  181. package/api/types/Settings.ts +23 -0
  182. package/api/types/SortCriteria.ts +30 -0
  183. package/api/types/SsoObject.ts +21 -0
  184. package/api/types/Status.ts +17 -0
  185. package/api/types/StatusDeviceauth.ts +18 -0
  186. package/api/types/StatusTenantadm.ts +19 -0
  187. package/api/types/StorageLimit.ts +17 -0
  188. package/api/types/SubscriptionData.ts +8 -0
  189. package/api/types/SupportRequest.ts +17 -0
  190. package/api/types/Tag.ts +27 -0
  191. package/api/types/Tags.ts +10 -0
  192. package/api/types/TaskResult.ts +13 -0
  193. package/api/types/TaskResultCLI.ts +10 -0
  194. package/api/types/TaskResultHTTPRequest.ts +8 -0
  195. package/api/types/TaskResultHTTPResponse.ts +10 -0
  196. package/api/types/Tenant.ts +38 -0
  197. package/api/types/TenantApiLimits.ts +12 -0
  198. package/api/types/TenantApiLimitsTenantadm.ts +12 -0
  199. package/api/types/TenantIdName.ts +14 -0
  200. package/api/types/TenantIdsData.ts +10 -0
  201. package/api/types/TenantInfo.ts +14 -0
  202. package/api/types/TenantShortInfo.ts +21 -0
  203. package/api/types/TenantTenantadm.ts +38 -0
  204. package/api/types/TenantsIdName.ts +6 -0
  205. package/api/types/Update.ts +17 -0
  206. package/api/types/UpdateDeployments.ts +18 -0
  207. package/api/types/UpdateFile.ts +13 -0
  208. package/api/types/UpdateFileDeployments.ts +13 -0
  209. package/api/types/UpdateTypes.ts +8 -0
  210. package/api/types/UpgradeCompleteRequest.ts +23 -0
  211. package/api/types/User.ts +13 -0
  212. package/api/types/UserAuditlogs.ts +13 -0
  213. package/api/types/UserNew.ts +26 -0
  214. package/api/types/UserUpdate.ts +25 -0
  215. package/api/types/UserUseradm.ts +45 -0
  216. package/api/types/UserWithTenantInfo.ts +8 -0
  217. package/api/types/XDeltaArgs.ts +9 -0
  218. package/api/types/XDeltaArgsDeployments.ts +9 -0
  219. package/api/types/XDeltaArgsLimits.ts +10 -0
  220. package/api/types/XDeltaArgsLimitsDeployments.ts +10 -0
  221. package/api/users-api.ts +34 -0
  222. package/appSlice/constants.ts +166 -0
  223. package/appSlice/index.ts +159 -0
  224. package/appSlice/reducer.test.ts +97 -0
  225. package/appSlice/selectors.ts +33 -0
  226. package/appSlice/thunks.test.ts +118 -0
  227. package/appSlice/thunks.ts +148 -0
  228. package/auth.test.ts +36 -0
  229. package/auth.ts +82 -0
  230. package/commonConstants.tsx +252 -0
  231. package/commonSelectors.ts +255 -0
  232. package/constants.ts +22 -0
  233. package/deploymentsSlice/constants.ts +175 -0
  234. package/deploymentsSlice/index.ts +145 -0
  235. package/deploymentsSlice/reducer.test.ts +108 -0
  236. package/deploymentsSlice/selectors.ts +58 -0
  237. package/deploymentsSlice/thunks.test.ts +425 -0
  238. package/deploymentsSlice/thunks.ts +382 -0
  239. package/devicesSlice/constants.ts +56 -0
  240. package/devicesSlice/index.ts +207 -0
  241. package/devicesSlice/reducer.test.ts +194 -0
  242. package/devicesSlice/selectors.ts +127 -0
  243. package/devicesSlice/thunks.test.tsx +1245 -0
  244. package/devicesSlice/thunks.tsx +1098 -0
  245. package/monitorSlice/constants.ts +17 -0
  246. package/monitorSlice/index.ts +65 -0
  247. package/monitorSlice/reducer.test.ts +79 -0
  248. package/monitorSlice/selectors.ts +15 -0
  249. package/monitorSlice/thunks.test.ts +112 -0
  250. package/monitorSlice/thunks.ts +101 -0
  251. package/onboardingSlice/constants.ts +53 -0
  252. package/onboardingSlice/index.ts +60 -0
  253. package/onboardingSlice/reducer.test.ts +45 -0
  254. package/onboardingSlice/selectors.ts +15 -0
  255. package/onboardingSlice/thunks.test.ts +235 -0
  256. package/onboardingSlice/thunks.ts +142 -0
  257. package/organizationSlice/constants.ts +82 -0
  258. package/organizationSlice/index.ts +111 -0
  259. package/organizationSlice/reducer.test.ts +78 -0
  260. package/organizationSlice/selectors.ts +45 -0
  261. package/organizationSlice/thunks.test.ts +619 -0
  262. package/organizationSlice/thunks.ts +383 -0
  263. package/package.json +38 -0
  264. package/releasesSlice/constants.ts +18 -0
  265. package/releasesSlice/index.ts +116 -0
  266. package/releasesSlice/reducer.test.ts +78 -0
  267. package/releasesSlice/selectors.ts +33 -0
  268. package/releasesSlice/thunks.test.ts +389 -0
  269. package/releasesSlice/thunks.ts +379 -0
  270. package/selectors.ts +22 -0
  271. package/store.ts +89 -0
  272. package/storehooks.test.tsx +386 -0
  273. package/storehooks.ts +250 -0
  274. package/thunks.ts +21 -0
  275. package/tsconfig.json +11 -0
  276. package/tsup.config.ts +11 -0
  277. package/usersSlice/constants.ts +374 -0
  278. package/usersSlice/index.ts +151 -0
  279. package/usersSlice/reducer.test.ts +141 -0
  280. package/usersSlice/selectors.ts +60 -0
  281. package/usersSlice/thunks.test.ts +660 -0
  282. package/usersSlice/thunks.ts +773 -0
  283. package/utils.test.ts +187 -0
  284. package/utils.ts +249 -0
@@ -0,0 +1,255 @@
1
+ // Copyright 2024 Northern.tech AS
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ // @ts-nocheck
15
+ import { attributeDuplicateFilter, getDemoDeviceAddress as getDemoDeviceAddressHelper } from '@northern.tech/utils/helpers';
16
+ import { createSelector } from '@reduxjs/toolkit';
17
+
18
+ import { PLANS, defaultReports } from './appSlice/constants';
19
+ import { getFeatures, getSearchedDevices } from './appSlice/selectors';
20
+ import { ALL_DEVICES, ATTRIBUTE_SCOPES, DEVICE_ISSUE_OPTIONS, DEVICE_LIST_MAXIMUM_LENGTH, UNGROUPED_GROUP } from './commonConstants';
21
+ import { getDeploymentsById, getDeploymentsSelectionState, getSelectedDeploymentDeviceIds } from './deploymentsSlice/selectors';
22
+ import { inventoryApiUrlV2, reportingApiUrl } from './devicesSlice/constants';
23
+ import { getDeviceById, getDevicesById, getFilteringAttributes, getGroupsById, getListedDevices } from './devicesSlice/selectors';
24
+ import { getIssueCountsByType } from './monitorSlice/selectors';
25
+ import { onboardingSteps } from './onboardingSlice/constants';
26
+ import { getOnboarding } from './onboardingSlice/selectors';
27
+ import { getAuditLogEntry, getIsServiceProvider, getOrganization } from './organizationSlice/selectors';
28
+ import { getReleasesById } from './releasesSlice/selectors';
29
+ import { rolesByName, uiPermissionsById } from './usersSlice/constants';
30
+ import { getCurrentUser, getGlobalSettings, getRolesById, getUserSettings } from './usersSlice/selectors';
31
+ import { listItemMapper, mapUserRolesToUiPermissions } from './utils';
32
+
33
+ export const getIsEnterprise = createSelector(
34
+ [getOrganization, getFeatures],
35
+ ({ plan = PLANS.os.id }, { isEnterprise, isHosted }) => isEnterprise || (isHosted && plan === PLANS.enterprise.id)
36
+ );
37
+
38
+ export const getAttrsEndpoint = createSelector([getFeatures], ({ hasReporting }) =>
39
+ hasReporting ? `${reportingApiUrl}/devices/search/attributes` : `${inventoryApiUrlV2}/filters/attributes`
40
+ );
41
+ export const getSearchEndpoint = createSelector([getFeatures], ({ hasReporting }) =>
42
+ hasReporting ? `${reportingApiUrl}/devices/search` : `${inventoryApiUrlV2}/filters/search`
43
+ );
44
+
45
+ export const getUserRoles = createSelector(
46
+ [getCurrentUser, getRolesById, getIsEnterprise, getFeatures, getOrganization],
47
+ (currentUser, rolesById, isEnterprise, { isHosted, hasMultitenancy }, { plan = PLANS.os.id }) => {
48
+ const isAdmin = currentUser.roles?.length
49
+ ? currentUser.roles.some(role => role === rolesByName.admin)
50
+ : !(hasMultitenancy || isEnterprise || (isHosted && plan !== PLANS.os.id));
51
+ const uiPermissions = isAdmin
52
+ ? mapUserRolesToUiPermissions([rolesByName.admin], rolesById)
53
+ : mapUserRolesToUiPermissions(currentUser.roles || [], rolesById);
54
+ return { isAdmin, uiPermissions };
55
+ }
56
+ );
57
+
58
+ const hasPermission = (thing, permission) => Object.values(thing).some(permissions => permissions.includes(permission));
59
+
60
+ export const getUserCapabilities = createSelector([getUserRoles, getIsServiceProvider], ({ uiPermissions }, isServiceProvider) => {
61
+ const canManageReleases = hasPermission(uiPermissions.releases, uiPermissionsById.manage.value);
62
+ const canReadReleases = canManageReleases || hasPermission(uiPermissions.releases, uiPermissionsById.read.value);
63
+ const canUploadReleases = canManageReleases || hasPermission(uiPermissions.releases, uiPermissionsById.upload.value);
64
+
65
+ const canAuditlog = uiPermissions.auditlog.includes(uiPermissionsById.read.value);
66
+
67
+ const canReadUsers = uiPermissions.userManagement.includes(uiPermissionsById.read.value);
68
+ const canManageUsers = uiPermissions.userManagement.includes(uiPermissionsById.manage.value);
69
+
70
+ const canReadDevices = hasPermission(uiPermissions.groups, uiPermissionsById.read.value);
71
+ const canWriteDevices = Object.values(uiPermissions.groups).some(
72
+ groupPermissions => groupPermissions.includes(uiPermissionsById.read.value) && groupPermissions.length > 1
73
+ );
74
+ const canTroubleshoot = hasPermission(uiPermissions.groups, uiPermissionsById.connect.value);
75
+ const canManageDevices = hasPermission(uiPermissions.groups, uiPermissionsById.manage.value);
76
+ const canConfigure = hasPermission(uiPermissions.groups, uiPermissionsById.configure.value);
77
+
78
+ const canDeploy = uiPermissions.deployments.includes(uiPermissionsById.deploy.value) || hasPermission(uiPermissions.groups, uiPermissionsById.deploy.value);
79
+ const canReadDeployments = uiPermissions.deployments.includes(uiPermissionsById.read.value);
80
+
81
+ return {
82
+ canAuditlog,
83
+ canConfigure,
84
+ canDeploy,
85
+ canManageDevices,
86
+ canManageReleases,
87
+ canManageUsers,
88
+ canReadDeployments,
89
+ canReadDevices,
90
+ canReadReleases,
91
+ canReadUsers,
92
+ canTroubleshoot,
93
+ canUploadReleases,
94
+ canWriteDevices,
95
+ groupsPermissions: uiPermissions.groups,
96
+ releasesPermissions: uiPermissions.releases,
97
+ SPTenant: isServiceProvider
98
+ };
99
+ });
100
+
101
+ export const getTenantCapabilities = createSelector(
102
+ [getFeatures, getOrganization, getIsEnterprise],
103
+ (
104
+ { hasAuditlogs: isAuditlogEnabled, hasDeviceConfig: isDeviceConfigEnabled, hasDeviceConnect: isDeviceConnectEnabled, hasMonitor: isMonitorEnabled },
105
+ { addons = [], plan = PLANS.os.id },
106
+ isEnterprise
107
+ ) => {
108
+ const canDelta = isEnterprise || plan === PLANS.professional.id;
109
+ const hasAuditlogs = isAuditlogEnabled && isEnterprise;
110
+ const hasDeviceConfig = isDeviceConfigEnabled && addons.some(addon => addon.name === 'configure' && Boolean(addon.enabled));
111
+ const hasDeviceConnect = isDeviceConnectEnabled && (!isEnterprise || addons.some(addon => addon.name === 'troubleshoot' && Boolean(addon.enabled)));
112
+ const hasMonitor = isMonitorEnabled && addons.some(addon => addon.name === 'monitor' && Boolean(addon.enabled));
113
+ return {
114
+ canDelta,
115
+ canRetry: canDelta,
116
+ canSchedule: canDelta,
117
+ hasAuditlogs,
118
+ hasDeviceConfig,
119
+ hasDeviceConnect,
120
+ hasFullFiltering: canDelta,
121
+ hasMonitor,
122
+ isEnterprise,
123
+ plan
124
+ };
125
+ }
126
+ );
127
+
128
+ export const getFilterAttributes = createSelector(
129
+ [getGlobalSettings, getFilteringAttributes],
130
+ ({ previousFilters }, { identityAttributes, inventoryAttributes, systemAttributes, tagAttributes }) => {
131
+ const deviceNameAttribute = { key: 'name', value: 'Name', scope: ATTRIBUTE_SCOPES.tags, category: ATTRIBUTE_SCOPES.tags, priority: 1 };
132
+ const deviceIdAttribute = { key: 'id', value: 'Device ID', scope: ATTRIBUTE_SCOPES.identity, category: ATTRIBUTE_SCOPES.identity, priority: 1 };
133
+ const checkInAttribute = { key: 'check_in_time', value: 'Latest activity', scope: ATTRIBUTE_SCOPES.system, category: ATTRIBUTE_SCOPES.system, priority: 4 };
134
+ const updateAttribute = { ...checkInAttribute, key: 'updated_ts', value: 'Last inventory update' };
135
+ const firstRequestAttribute = { key: 'created_ts', value: 'First request', scope: ATTRIBUTE_SCOPES.system, category: ATTRIBUTE_SCOPES.system, priority: 4 };
136
+ const attributes = [
137
+ ...previousFilters.map(item => ({
138
+ ...item,
139
+ value: deviceIdAttribute.key === item.key ? deviceIdAttribute.value : item.key,
140
+ category: 'recently used',
141
+ priority: 0
142
+ })),
143
+ deviceNameAttribute,
144
+ deviceIdAttribute,
145
+ ...identityAttributes.map(item => ({ key: item, value: item, scope: ATTRIBUTE_SCOPES.identity, category: ATTRIBUTE_SCOPES.identity, priority: 1 })),
146
+ ...inventoryAttributes.map(item => ({ key: item, value: item, scope: ATTRIBUTE_SCOPES.inventory, category: ATTRIBUTE_SCOPES.inventory, priority: 2 })),
147
+ ...tagAttributes.map(item => ({ key: item, value: item, scope: ATTRIBUTE_SCOPES.tags, category: ATTRIBUTE_SCOPES.tags, priority: 3 })),
148
+ checkInAttribute,
149
+ updateAttribute,
150
+ firstRequestAttribute,
151
+ ...systemAttributes.map(item => ({ key: item, value: item, scope: ATTRIBUTE_SCOPES.system, category: ATTRIBUTE_SCOPES.system, priority: 4 }))
152
+ ];
153
+ return attributeDuplicateFilter(attributes, 'key');
154
+ }
155
+ );
156
+
157
+ export const getOnboardingState = createSelector([getOnboarding, getUserSettings], ({ complete, progress, showTips, ...remainder }, { onboarding = {} }) => ({
158
+ ...remainder,
159
+ ...onboarding,
160
+ complete: onboarding.complete || complete,
161
+ progress:
162
+ Object.keys(onboardingSteps).findIndex(step => step === progress) > Object.keys(onboardingSteps).findIndex(step => step === onboarding.progress)
163
+ ? progress
164
+ : onboarding.progress,
165
+ showTips: !onboarding.showTips ? onboarding.showTips : showTips
166
+ }));
167
+
168
+ export const getDemoDeviceAddress = createSelector([getDevicesById, getOnboarding], (devicesById, { approach, demoArtifactPort }) => {
169
+ const demoDeviceAddress = `http://${getDemoDeviceAddressHelper(Object.values(devicesById), approach)}`;
170
+ return demoArtifactPort ? `${demoDeviceAddress}:${demoArtifactPort}` : demoDeviceAddress;
171
+ });
172
+
173
+ export const getDeviceConfigDeployment = createSelector([getDeviceById, getDeploymentsById], (device, deploymentsById) => {
174
+ const { config = {} } = device;
175
+ const { deployment_id: configDeploymentId } = config;
176
+ const deviceConfigDeployment = deploymentsById[configDeploymentId] || {};
177
+ return { device, deviceConfigDeployment };
178
+ });
179
+
180
+ export const getDeploymentRelease = createSelector(
181
+ [getDeploymentsById, getDeploymentsSelectionState, getReleasesById],
182
+ (deploymentsById, { selectedId }, releasesById) => {
183
+ const deployment = deploymentsById[selectedId] || {};
184
+ return deployment.artifact_name && releasesById[deployment.artifact_name] ? releasesById[deployment.artifact_name] : { device_types_compatible: [] };
185
+ }
186
+ );
187
+
188
+ export const getSelectedDeploymentData = createSelector(
189
+ [getDeploymentsById, getDeploymentsSelectionState, getDevicesById, getSelectedDeploymentDeviceIds],
190
+ (deploymentsById, { selectedId }, devicesById, selectedDeviceIds) => {
191
+ const deployment = deploymentsById[selectedId] ?? {};
192
+ const { devices = {} } = deployment;
193
+ return {
194
+ deployment,
195
+ selectedDevices: selectedDeviceIds.map(deviceId => ({ ...devicesById[deviceId], ...devices[deviceId] }))
196
+ };
197
+ }
198
+ );
199
+
200
+ export const getAvailableIssueOptionsByType = createSelector(
201
+ [getFeatures, getTenantCapabilities, getIssueCountsByType],
202
+ ({ hasReporting }, { hasFullFiltering, hasMonitor }, issueCounts) =>
203
+ Object.values(DEVICE_ISSUE_OPTIONS).reduce((accu, { isCategory, key, needsFullFiltering, needsMonitor, needsReporting, title }) => {
204
+ if (isCategory || (needsReporting && !hasReporting) || (needsFullFiltering && !hasFullFiltering) || (needsMonitor && !hasMonitor)) {
205
+ return accu;
206
+ }
207
+ accu[key] = { count: issueCounts[key].filtered, key, title };
208
+ return accu;
209
+ }, {})
210
+ );
211
+
212
+ export const getGroupNames = createSelector([getGroupsById, getUserRoles, (_, options = {}) => options], (groupsById, { uiPermissions }, { staticOnly }) => {
213
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
214
+ const { [UNGROUPED_GROUP.id]: ungrouped, ...groups } = groupsById;
215
+ if (staticOnly) {
216
+ return Object.keys(uiPermissions.groups).sort();
217
+ }
218
+ return Object.keys(
219
+ Object.entries(groups).reduce((accu, [groupName, group]) => {
220
+ if (group.filterId || uiPermissions.groups[ALL_DEVICES]) {
221
+ accu[groupName] = group;
222
+ }
223
+ return accu;
224
+ }, uiPermissions.groups)
225
+ ).sort();
226
+ });
227
+
228
+ export const getDeviceReportsForUser = createSelector(
229
+ [getUserSettings, getCurrentUser, getGlobalSettings, getDevicesById],
230
+ ({ reports }, { id: currentUserId }, globalSettings, devicesById) => {
231
+ return reports || globalSettings[`${currentUserId}-reports`] || (Object.keys(devicesById).length ? defaultReports : []);
232
+ }
233
+ );
234
+
235
+ const listTypeDeviceIdMap = {
236
+ deviceList: getListedDevices,
237
+ search: getSearchedDevices
238
+ };
239
+ const deviceMapDefault = { defaultObject: { auth_sets: [] }, cutOffSize: DEVICE_LIST_MAXIMUM_LENGTH };
240
+ const getDeviceMappingDefaults = () => deviceMapDefault;
241
+
242
+ export const getMappedDevicesList = createSelector(
243
+ [getDevicesById, (state, listType) => listTypeDeviceIdMap[listType](state), getDeviceMappingDefaults],
244
+ listItemMapper
245
+ );
246
+
247
+ export const getAuditlogDevice = createSelector([getAuditLogEntry, getDevicesById], (auditlogEvent, devicesById) => {
248
+ let auditlogDevice = {};
249
+ if (auditlogEvent) {
250
+ const { object = {} } = auditlogEvent;
251
+ const { device = {}, id, type } = object;
252
+ auditlogDevice = type === 'device' ? { id, ...device } : auditlogDevice;
253
+ }
254
+ return { ...auditlogDevice, ...devicesById[auditlogDevice.id] };
255
+ });
package/constants.ts ADDED
@@ -0,0 +1,22 @@
1
+ // Copyright 2024 Northern.tech AS
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ export * from './appSlice/constants';
15
+ export * from './commonConstants';
16
+ export * from './deploymentsSlice/constants';
17
+ export * from './devicesSlice/constants';
18
+ export * from './monitorSlice/constants';
19
+ export * from './onboardingSlice/constants';
20
+ export * from './organizationSlice/constants';
21
+ export * from './releasesSlice/constants';
22
+ export * from './usersSlice/constants';
@@ -0,0 +1,175 @@
1
+ // Copyright 2019 Northern.tech AS
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ import { DEVICE_LIST_DEFAULTS, SORTING_OPTIONS, apiUrl } from '@northern.tech/store/constants';
15
+
16
+ const alreadyInstalled = 'already-installed';
17
+
18
+ export const deploymentsApiUrl = `${apiUrl.v1}/deployments`;
19
+ export const deploymentsApiUrlV2 = `${apiUrl.v2}/deployments`;
20
+
21
+ export const deploymentSubstates = {
22
+ aborted: 'aborted',
23
+ alreadyInstalled,
24
+ decommissioned: 'decommissioned',
25
+ downloading: 'downloading',
26
+ failure: 'failure',
27
+ installing: 'installing',
28
+ noartifact: 'noartifact',
29
+ pause_before_committing: 'pause_before_committing',
30
+ pause_before_installing: 'pause_before_installing',
31
+ pause_before_rebooting: 'pause_before_rebooting',
32
+ pending: 'pending',
33
+ rebooting: 'rebooting',
34
+ success: 'success'
35
+ };
36
+
37
+ export const deploymentStatesToSubstates = {
38
+ failures: [deploymentSubstates.failure, deploymentSubstates.aborted, deploymentSubstates.decommissioned],
39
+ inprogress: [deploymentSubstates.downloading, deploymentSubstates.installing, deploymentSubstates.rebooting],
40
+ paused: [deploymentSubstates.pause_before_installing, deploymentSubstates.pause_before_rebooting, deploymentSubstates.pause_before_committing],
41
+ pending: [deploymentSubstates.pending],
42
+ successes: [deploymentSubstates.success, deploymentSubstates.alreadyInstalled, deploymentSubstates.noartifact]
43
+ };
44
+
45
+ export const deploymentStatesToSubstatesWithSkipped = {
46
+ ...deploymentStatesToSubstates,
47
+ failures: [deploymentSubstates.failure],
48
+ skipped: [deploymentSubstates.aborted, deploymentSubstates.noartifact, deploymentSubstates.alreadyInstalled, deploymentSubstates.decommissioned],
49
+ successes: [deploymentSubstates.success]
50
+ };
51
+ export const installationSubstatesMap = {
52
+ download: {
53
+ title: 'download',
54
+ done: 'downloaded',
55
+ successIndicators: [deploymentSubstates.installing, deploymentSubstates.rebooting, ...deploymentStatesToSubstates.paused, deploymentSubstates.success],
56
+ failureIndicators: deploymentStatesToSubstates.failures,
57
+ pauseConfigurationIndicator: 'ArtifactInstall_Enter'
58
+ },
59
+ install: {
60
+ title: 'install',
61
+ done: 'installed',
62
+ successIndicators: [
63
+ deploymentSubstates.rebooting,
64
+ deploymentSubstates.pause_before_rebooting,
65
+ deploymentSubstates.pause_before_committing,
66
+ deploymentSubstates.success
67
+ ],
68
+ failureIndicators: deploymentStatesToSubstates.failures,
69
+ pauseConfigurationIndicator: 'ArtifactReboot_Enter'
70
+ },
71
+ reboot: {
72
+ title: 'reboot',
73
+ done: 'rebooted',
74
+ successIndicators: [deploymentSubstates.pause_before_committing, deploymentSubstates.success],
75
+ failureIndicators: deploymentStatesToSubstates.failures,
76
+ pauseConfigurationIndicator: 'ArtifactCommit_Enter'
77
+ },
78
+ commit: {
79
+ title: 'commit',
80
+ done: 'committed',
81
+ successIndicators: deploymentStatesToSubstates.successes,
82
+ failureIndicators: deploymentStatesToSubstates.failures,
83
+ pauseConfigurationIndicator: undefined
84
+ }
85
+ };
86
+
87
+ export const DEPLOYMENT_STATES = {
88
+ finished: 'finished',
89
+ inprogress: 'inprogress',
90
+ pending: 'pending',
91
+ scheduled: 'scheduled'
92
+ };
93
+
94
+ export const listDefaultsByState = {
95
+ [DEPLOYMENT_STATES.inprogress]: { page: 1, perPage: 10 },
96
+ [DEPLOYMENT_STATES.pending]: { page: 1, perPage: 10 },
97
+ [DEPLOYMENT_STATES.scheduled]: { ...DEVICE_LIST_DEFAULTS },
98
+ [DEPLOYMENT_STATES.finished]: { ...DEVICE_LIST_DEFAULTS },
99
+ sort: { direction: SORTING_OPTIONS.desc }
100
+ };
101
+
102
+ export const DEFAULT_PENDING_INPROGRESS_COUNT = 10;
103
+ export const DEPLOYMENT_ROUTES = {
104
+ active: {
105
+ key: 'active',
106
+ route: '/deployments/active',
107
+ states: [DEPLOYMENT_STATES.pending, DEPLOYMENT_STATES.inprogress],
108
+ title: 'Active'
109
+ },
110
+ finished: {
111
+ key: 'finished',
112
+ route: '/deployments/finished',
113
+ states: [DEPLOYMENT_STATES.finished],
114
+ title: 'Finished'
115
+ },
116
+ scheduled: {
117
+ key: 'scheduled',
118
+ route: '/deployments/scheduled',
119
+ states: [DEPLOYMENT_STATES.scheduled],
120
+ title: 'Scheduled'
121
+ }
122
+ };
123
+ export const DEPLOYMENT_TYPES = {
124
+ software: 'software',
125
+ configuration: 'configuration'
126
+ };
127
+ export const defaultStats = {
128
+ [deploymentSubstates.aborted]: 0,
129
+ [deploymentSubstates.alreadyInstalled]: 0,
130
+ [deploymentSubstates.decommissioned]: 0,
131
+ [deploymentSubstates.downloading]: 0,
132
+ [deploymentSubstates.failure]: 0,
133
+ [deploymentSubstates.installing]: 0,
134
+ [deploymentSubstates.noartifact]: 0,
135
+ [deploymentSubstates.pause_before_committing]: 0,
136
+ [deploymentSubstates.pause_before_installing]: 0,
137
+ [deploymentSubstates.pause_before_rebooting]: 0,
138
+ [deploymentSubstates.pending]: 0,
139
+ [deploymentSubstates.rebooting]: 0,
140
+ [deploymentSubstates.success]: 0
141
+ };
142
+ export const deploymentDisplayStates = {
143
+ finished: 'Finished',
144
+ scheduled: 'Scheduled',
145
+ skipped: 'Skipped',
146
+ paused: 'Paused',
147
+ pending: 'Pending',
148
+ inprogress: 'In Progress',
149
+ success: 'Success',
150
+ successes: 'Success',
151
+ failure: 'Fail',
152
+ failures: 'Fail'
153
+ };
154
+
155
+ export const deploymentPrototype = {
156
+ devices: {},
157
+ name: undefined,
158
+ statistics: { status: {} }
159
+ };
160
+
161
+ export const pauseMap = {
162
+ [deploymentSubstates.pause_before_installing]: {
163
+ title: installationSubstatesMap.download.done,
164
+ followUp: installationSubstatesMap.download.pauseConfigurationIndicator
165
+ },
166
+ [deploymentSubstates.pause_before_rebooting]: {
167
+ title: installationSubstatesMap.install.done,
168
+ followUp: installationSubstatesMap.install.pauseConfigurationIndicator
169
+ },
170
+ [deploymentSubstates.pause_before_committing]: {
171
+ title: installationSubstatesMap.reboot.done,
172
+ followUp: installationSubstatesMap.reboot.pauseConfigurationIndicator
173
+ }
174
+ };
175
+ export const limitDefault = { min: 5, max: 100, default: 10 };
@@ -0,0 +1,145 @@
1
+ // Copyright 2023 Northern.tech AS
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+ // @ts-nocheck
15
+ import { DEVICE_LIST_DEFAULTS } from '@northern.tech/store/constants';
16
+ import { createSlice } from '@reduxjs/toolkit';
17
+
18
+ import { DEFAULT_PENDING_INPROGRESS_COUNT, DEPLOYMENT_ROUTES, DEPLOYMENT_STATES, deploymentPrototype, limitDefault } from './constants';
19
+
20
+ export const sliceName = 'deployments';
21
+
22
+ export const initialState = {
23
+ byId: {
24
+ // [id]: { statistics: { status: {}, total_size }, devices: { [deploymentId]: { id, log } }, totalDeviceCount }
25
+ },
26
+ byStatus: {
27
+ finished: { deploymentIds: [], total: 0 },
28
+ inprogress: { deploymentIds: [], total: 0 },
29
+ pending: { deploymentIds: [], total: 0 },
30
+ scheduled: { deploymentIds: [], total: 0 }
31
+ },
32
+ config: {
33
+ binaryDelta: {
34
+ timeout: -1,
35
+ duplicatesWindow: -1,
36
+ compressionLevel: -1,
37
+ disableChecksum: false,
38
+ disableDecompression: false,
39
+ inputWindow: -1,
40
+ instructionBuffer: -1,
41
+ sourceWindow: -1
42
+ },
43
+ binaryDeltaLimits: {
44
+ timeout: { ...limitDefault, default: 60, max: 3600, min: 60 },
45
+ sourceWindow: limitDefault,
46
+ inputWindow: limitDefault,
47
+ duplicatesWindow: limitDefault,
48
+ instructionBuffer: limitDefault
49
+ }
50
+ },
51
+ deploymentDeviceLimit: 5000,
52
+ selectedDeviceIds: [],
53
+ selectionState: {
54
+ finished: { ...DEVICE_LIST_DEFAULTS, endDate: undefined, search: '', selection: [], startDate: undefined, total: 0, type: '' },
55
+ inprogress: { ...DEVICE_LIST_DEFAULTS, perPage: DEFAULT_PENDING_INPROGRESS_COUNT, selection: [] },
56
+ pending: { ...DEVICE_LIST_DEFAULTS, perPage: DEFAULT_PENDING_INPROGRESS_COUNT, selection: [] },
57
+ scheduled: { ...DEVICE_LIST_DEFAULTS, selection: [] },
58
+ general: {
59
+ state: DEPLOYMENT_ROUTES.active.key,
60
+ showCreationDialog: false,
61
+ showReportDialog: false,
62
+ reportType: null // DeploymentConstants.DEPLOYMENT_TYPES.configuration|DeploymentConstants.DEPLOYMENT_TYPES.software
63
+ },
64
+ selectedId: undefined
65
+ }
66
+ };
67
+
68
+ export const deploymentsSlice = createSlice({
69
+ name: sliceName,
70
+ initialState,
71
+ reducers: {
72
+ createdDeployment: (state, action) => {
73
+ state.byId[action.payload.id] = {
74
+ ...deploymentPrototype,
75
+ ...action.payload
76
+ };
77
+ state.byStatus[DEPLOYMENT_STATES.pending].total = state.byStatus[DEPLOYMENT_STATES.pending].total + 1;
78
+ state.byStatus[DEPLOYMENT_STATES.pending].deploymentIds = [...state.byStatus.pending.deploymentIds, action.payload.id];
79
+ (state.selectionState[DEPLOYMENT_STATES.pending].selection = [action.payload.id, ...state.selectionState[DEPLOYMENT_STATES.pending].selection]),
80
+ (state.selectionState[DEPLOYMENT_STATES.pending].total = state.selectionState[DEPLOYMENT_STATES.pending].total + 1);
81
+ },
82
+ removedDeployment: (state, action) => {
83
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
84
+ const { [action.payload]: removedDeployment, ...remainder } = state.byId;
85
+ state.byId = remainder;
86
+ },
87
+ receivedDeployment: (state, action) => {
88
+ state.byId[action.payload.id] = {
89
+ ...(state.byId[action.payload.id] || {}),
90
+ ...action.payload
91
+ };
92
+ },
93
+ receivedDeploymentDeviceLog: (state, action) => {
94
+ const { id, deviceId, log } = action.payload;
95
+ const deployment = {
96
+ ...deploymentPrototype,
97
+ ...state.byId[id]
98
+ };
99
+ state.byId[id] = {
100
+ ...deployment,
101
+ devices: {
102
+ ...deployment.devices,
103
+ [deviceId]: {
104
+ ...deployment.devices[deviceId],
105
+ log
106
+ }
107
+ }
108
+ };
109
+ },
110
+ receivedDeploymentDevices: (state, action) => {
111
+ const { id, devices, selectedDeviceIds, totalDeviceCount } = action.payload;
112
+ state.byId[id] = {
113
+ ...state.byId[id],
114
+ devices,
115
+ totalDeviceCount
116
+ };
117
+ state.selectedDeviceIds = selectedDeviceIds;
118
+ },
119
+ receivedDeployments: (state, action) => {
120
+ state.byId = {
121
+ ...state.byId,
122
+ ...action.payload
123
+ };
124
+ },
125
+ receivedDeploymentsForStatus: (state, action) => {
126
+ const { status, deploymentIds, total } = action.payload;
127
+ state.byStatus[status].deploymentIds = deploymentIds;
128
+ state.byStatus[status].total = total;
129
+ },
130
+ selectDeploymentsForStatus: (state, action) => {
131
+ const { status, deploymentIds, total } = action.payload;
132
+ state.selectionState[status].selection = deploymentIds;
133
+ state.selectionState[status].total = total;
134
+ },
135
+ setDeploymentsState: (state, action) => {
136
+ state.selectionState = action.payload;
137
+ },
138
+ setDeploymentsConfig: (state, action) => {
139
+ state.config = action.payload;
140
+ }
141
+ }
142
+ });
143
+
144
+ export const actions = deploymentsSlice.actions;
145
+ export default deploymentsSlice.reducer;