@flightctl/ui-components 0.4.0 → 0.5.0-rc2

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 (384) hide show
  1. package/dist/src/components/DetailsPage/DetailsPageActions.d.ts +11 -4
  2. package/dist/src/components/DetailsPage/DetailsPageActions.d.ts.map +1 -1
  3. package/dist/src/components/DetailsPage/DetailsPageActions.js +15 -4
  4. package/dist/src/components/DetailsPage/DetailsPageActions.js.map +1 -1
  5. package/dist/src/components/DetailsPage/Tables/ApplicationsTable.js +1 -1
  6. package/dist/src/components/DetailsPage/Tables/ApplicationsTable.js.map +1 -1
  7. package/dist/src/components/Device/DeviceDetails/DeviceApplications.d.ts +1 -1
  8. package/dist/src/components/Device/DeviceDetails/DeviceApplications.d.ts.map +1 -1
  9. package/dist/src/components/Device/DeviceDetails/DeviceApplications.js +2 -2
  10. package/dist/src/components/Device/DeviceDetails/DeviceApplications.js.map +1 -1
  11. package/dist/src/components/Device/DeviceDetails/DeviceDetailsPage.d.ts.map +1 -1
  12. package/dist/src/components/Device/DeviceDetails/DeviceDetailsPage.js +22 -15
  13. package/dist/src/components/Device/DeviceDetails/DeviceDetailsPage.js.map +1 -1
  14. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTab.d.ts.map +1 -1
  15. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTab.js +42 -39
  16. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTab.js.map +1 -1
  17. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/StatusContent.d.ts +7 -0
  18. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/StatusContent.d.ts.map +1 -0
  19. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/StatusContent.js +41 -0
  20. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/StatusContent.js.map +1 -0
  21. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/SystemResourcesContent.d.ts +7 -0
  22. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/SystemResourcesContent.d.ts.map +1 -0
  23. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/SystemResourcesContent.js +30 -0
  24. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTabContent/SystemResourcesContent.js.map +1 -0
  25. package/dist/src/components/Device/DeviceDetails/TerminalTab.d.ts.map +1 -1
  26. package/dist/src/components/Device/DeviceDetails/TerminalTab.js +1 -1
  27. package/dist/src/components/Device/DeviceDetails/TerminalTab.js.map +1 -1
  28. package/dist/src/components/Device/DevicesPage/DecommissionedDeviceTableRow.d.ts +16 -0
  29. package/dist/src/components/Device/DevicesPage/DecommissionedDeviceTableRow.d.ts.map +1 -0
  30. package/dist/src/components/Device/DevicesPage/DecommissionedDeviceTableRow.js +57 -0
  31. package/dist/src/components/Device/DevicesPage/DecommissionedDeviceTableRow.js.map +1 -0
  32. package/dist/src/components/Device/DevicesPage/DecommissionedDevicesTable.d.ts +16 -0
  33. package/dist/src/components/Device/DevicesPage/DecommissionedDevicesTable.d.ts.map +1 -0
  34. package/dist/src/components/Device/DevicesPage/DecommissionedDevicesTable.js +73 -0
  35. package/dist/src/components/Device/DevicesPage/DecommissionedDevicesTable.js.map +1 -0
  36. package/dist/src/components/Device/DevicesPage/DeviceNameOnlyToolbarFilter.d.ts +10 -0
  37. package/dist/src/components/Device/DevicesPage/DeviceNameOnlyToolbarFilter.d.ts.map +1 -0
  38. package/dist/src/components/Device/DevicesPage/DeviceNameOnlyToolbarFilter.js +19 -0
  39. package/dist/src/components/Device/DevicesPage/DeviceNameOnlyToolbarFilter.js.map +1 -0
  40. package/dist/src/components/Device/DevicesPage/DevicesEmptyStates.d.ts +8 -0
  41. package/dist/src/components/Device/DevicesPage/DevicesEmptyStates.d.ts.map +1 -0
  42. package/dist/src/components/Device/DevicesPage/DevicesEmptyStates.js +34 -0
  43. package/dist/src/components/Device/DevicesPage/DevicesEmptyStates.js.map +1 -0
  44. package/dist/src/components/Device/DevicesPage/DevicesPage.d.ts +0 -22
  45. package/dist/src/components/Device/DevicesPage/DevicesPage.d.ts.map +1 -1
  46. package/dist/src/components/Device/DevicesPage/DevicesPage.js +9 -92
  47. package/dist/src/components/Device/DevicesPage/DevicesPage.js.map +1 -1
  48. package/dist/src/components/Device/DevicesPage/EnrolledDeviceTableRow.d.ts +16 -0
  49. package/dist/src/components/Device/DevicesPage/EnrolledDeviceTableRow.d.ts.map +1 -0
  50. package/dist/src/components/Device/DevicesPage/{DeviceTableRow.js → EnrolledDeviceTableRow.js} +9 -13
  51. package/dist/src/components/Device/DevicesPage/EnrolledDeviceTableRow.js.map +1 -0
  52. package/dist/src/components/Device/DevicesPage/EnrolledDevicesTable.d.ts +23 -0
  53. package/dist/src/components/Device/DevicesPage/EnrolledDevicesTable.d.ts.map +1 -0
  54. package/dist/src/components/Device/DevicesPage/EnrolledDevicesTable.js +99 -0
  55. package/dist/src/components/Device/DevicesPage/EnrolledDevicesTable.js.map +1 -0
  56. package/dist/src/components/Device/DevicesPage/useDevices.d.ts +2 -0
  57. package/dist/src/components/Device/DevicesPage/useDevices.d.ts.map +1 -1
  58. package/dist/src/components/Device/DevicesPage/useDevices.js +16 -1
  59. package/dist/src/components/Device/DevicesPage/useDevices.js.map +1 -1
  60. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizard.d.ts.map +1 -1
  61. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizard.js +5 -3
  62. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizard.js.map +1 -1
  63. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizardNav.js +1 -1
  64. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizardNav.js.map +1 -1
  65. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.d.ts.map +1 -1
  66. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js +2 -2
  67. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js.map +1 -1
  68. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.d.ts.map +1 -1
  69. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.js +1 -1
  70. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.js.map +1 -1
  71. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigurationTemplates.d.ts.map +1 -1
  72. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigurationTemplates.js +1 -1
  73. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigurationTemplates.js.map +1 -1
  74. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewDeviceStep.d.ts.map +1 -1
  75. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewDeviceStep.js +7 -7
  76. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewDeviceStep.js.map +1 -1
  77. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewUpdatePolicy.d.ts +9 -0
  78. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewUpdatePolicy.d.ts.map +1 -0
  79. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewUpdatePolicy.js +37 -0
  80. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewUpdatePolicy.js.map +1 -0
  81. package/dist/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.d.ts.map +1 -1
  82. package/dist/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.js +6 -4
  83. package/dist/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.js.map +1 -1
  84. package/dist/src/components/Device/EditDeviceWizard/utils.d.ts +1 -1
  85. package/dist/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.d.ts.map +1 -1
  86. package/dist/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.js +4 -13
  87. package/dist/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.js.map +1 -1
  88. package/dist/src/components/EnrollmentRequest/EnrollmentRequestList.js +2 -2
  89. package/dist/src/components/EnrollmentRequest/EnrollmentRequestList.js.map +1 -1
  90. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableRow.d.ts +2 -2
  91. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableRow.d.ts.map +1 -1
  92. package/dist/src/components/EnrollmentRequest/useEnrollmentRequests.d.ts +2 -2
  93. package/dist/src/components/EnrollmentRequest/useEnrollmentRequests.d.ts.map +1 -1
  94. package/dist/src/components/EnrollmentRequest/useEnrollmentRequests.js.map +1 -1
  95. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizard.d.ts.map +1 -1
  96. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizard.js +32 -3
  97. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizard.js.map +1 -1
  98. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizardFooter.d.ts.map +1 -1
  99. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizardFooter.js +4 -0
  100. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizardFooter.js.map +1 -1
  101. package/dist/src/components/Fleet/CreateFleet/fleetSpecUtils.d.ts +26 -0
  102. package/dist/src/components/Fleet/CreateFleet/fleetSpecUtils.d.ts.map +1 -0
  103. package/dist/src/components/Fleet/CreateFleet/fleetSpecUtils.js +63 -0
  104. package/dist/src/components/Fleet/CreateFleet/fleetSpecUtils.js.map +1 -0
  105. package/dist/src/components/Fleet/CreateFleet/steps/ReviewStep.d.ts.map +1 -1
  106. package/dist/src/components/Fleet/CreateFleet/steps/ReviewStep.js +19 -10
  107. package/dist/src/components/Fleet/CreateFleet/steps/ReviewStep.js.map +1 -1
  108. package/dist/src/components/Fleet/CreateFleet/steps/UpdateConfirmChangesModal.d.ts +9 -0
  109. package/dist/src/components/Fleet/CreateFleet/steps/UpdateConfirmChangesModal.d.ts.map +1 -0
  110. package/dist/src/components/Fleet/CreateFleet/steps/UpdateConfirmChangesModal.js +52 -0
  111. package/dist/src/components/Fleet/CreateFleet/steps/UpdateConfirmChangesModal.js.map +1 -0
  112. package/dist/src/components/Fleet/CreateFleet/steps/UpdatePolicyStep.d.ts +8 -0
  113. package/dist/src/components/Fleet/CreateFleet/steps/UpdatePolicyStep.d.ts.map +1 -0
  114. package/dist/src/components/Fleet/CreateFleet/steps/UpdatePolicyStep.js +95 -0
  115. package/dist/src/components/Fleet/CreateFleet/steps/UpdatePolicyStep.js.map +1 -0
  116. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepDisruptionBudget.d.ts +4 -0
  117. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepDisruptionBudget.d.ts.map +1 -0
  118. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepDisruptionBudget.js +31 -0
  119. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepDisruptionBudget.js.map +1 -0
  120. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepRolloutPolicy.d.ts +4 -0
  121. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepRolloutPolicy.d.ts.map +1 -0
  122. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepRolloutPolicy.js +78 -0
  123. package/dist/src/components/Fleet/CreateFleet/steps/UpdateStepRolloutPolicy.js.map +1 -0
  124. package/dist/src/components/Fleet/CreateFleet/types.d.ts +21 -0
  125. package/dist/src/components/Fleet/CreateFleet/types.d.ts.map +1 -1
  126. package/dist/src/components/Fleet/CreateFleet/types.js +6 -0
  127. package/dist/src/components/Fleet/CreateFleet/types.js.map +1 -1
  128. package/dist/src/components/Fleet/CreateFleet/utils.d.ts.map +1 -1
  129. package/dist/src/components/Fleet/CreateFleet/utils.js +15 -1
  130. package/dist/src/components/Fleet/CreateFleet/utils.js.map +1 -1
  131. package/dist/src/components/Fleet/FleetDetails/FleetDetailsContent.d.ts.map +1 -1
  132. package/dist/src/components/Fleet/FleetDetails/FleetDetailsContent.js +9 -7
  133. package/dist/src/components/Fleet/FleetDetails/FleetDetailsContent.js.map +1 -1
  134. package/dist/src/components/Fleet/FleetDetails/FleetDevicesCharts.d.ts +9 -0
  135. package/dist/src/components/Fleet/FleetDetails/FleetDevicesCharts.d.ts.map +1 -0
  136. package/dist/src/components/Fleet/FleetDetails/{FleetDevices.js → FleetDevicesCharts.js} +4 -4
  137. package/dist/src/components/Fleet/FleetDetails/FleetDevicesCharts.js.map +1 -0
  138. package/dist/src/components/Fleet/FleetDetails/FleetDevicesCount.d.ts +10 -0
  139. package/dist/src/components/Fleet/FleetDetails/FleetDevicesCount.d.ts.map +1 -0
  140. package/dist/src/components/Fleet/FleetDetails/FleetDevicesCount.js +30 -0
  141. package/dist/src/components/Fleet/FleetDetails/FleetDevicesCount.js.map +1 -0
  142. package/dist/src/components/Fleet/FleetResourceSyncs.js +2 -2
  143. package/dist/src/components/Fleet/FleetResourceSyncs.js.map +1 -1
  144. package/dist/src/components/Fleet/FleetRow.d.ts.map +1 -1
  145. package/dist/src/components/Fleet/FleetRow.js +7 -5
  146. package/dist/src/components/Fleet/FleetRow.js.map +1 -1
  147. package/dist/src/components/Fleet/FleetsPage.js +2 -2
  148. package/dist/src/components/Fleet/FleetsPage.js.map +1 -1
  149. package/dist/src/components/Fleet/useFleets.d.ts +3 -3
  150. package/dist/src/components/Fleet/useFleets.d.ts.map +1 -1
  151. package/dist/src/components/Fleet/useFleets.js +3 -3
  152. package/dist/src/components/Fleet/useFleets.js.map +1 -1
  153. package/dist/src/components/ListPage/ListPage.d.ts.map +1 -1
  154. package/dist/src/components/ListPage/ListPage.js +6 -1
  155. package/dist/src/components/ListPage/ListPage.js.map +1 -1
  156. package/dist/src/components/ListPage/ListPageActions.d.ts +8 -15
  157. package/dist/src/components/ListPage/ListPageActions.d.ts.map +1 -1
  158. package/dist/src/components/ListPage/ListPageActions.js +25 -5
  159. package/dist/src/components/ListPage/ListPageActions.js.map +1 -1
  160. package/dist/src/components/ListPage/types.d.ts +11 -11
  161. package/dist/src/components/ListPage/types.d.ts.map +1 -1
  162. package/dist/src/components/OverviewPage/Cards/Status/DeviceStatusChart.d.ts.map +1 -1
  163. package/dist/src/components/OverviewPage/Cards/Status/DeviceStatusChart.js +0 -1
  164. package/dist/src/components/OverviewPage/Cards/Status/DeviceStatusChart.js.map +1 -1
  165. package/dist/src/components/OverviewPage/OverviewPage.d.ts.map +1 -1
  166. package/dist/src/components/OverviewPage/OverviewPage.js +6 -1
  167. package/dist/src/components/OverviewPage/OverviewPage.js.map +1 -1
  168. package/dist/src/components/Repository/RepositoryDetails/RepositoryResourceSyncsCard.js +1 -1
  169. package/dist/src/components/Repository/RepositoryDetails/RepositoryResourceSyncsCard.js.map +1 -1
  170. package/dist/src/components/Repository/useRepositories.d.ts +2 -2
  171. package/dist/src/components/Repository/useRepositories.d.ts.map +1 -1
  172. package/dist/src/components/Repository/useRepositories.js.map +1 -1
  173. package/dist/src/components/ResourceSync/RepositoryResourceSyncList.js +2 -2
  174. package/dist/src/components/ResourceSync/RepositoryResourceSyncList.js.map +1 -1
  175. package/dist/src/components/Status/DeviceLifecycleStatus.d.ts +7 -0
  176. package/dist/src/components/Status/DeviceLifecycleStatus.d.ts.map +1 -0
  177. package/dist/src/components/Status/DeviceLifecycleStatus.js +25 -0
  178. package/dist/src/components/Status/DeviceLifecycleStatus.js.map +1 -0
  179. package/dist/src/components/Status/StatusDisplay.d.ts +1 -1
  180. package/dist/src/components/Status/StatusDisplay.d.ts.map +1 -1
  181. package/dist/src/components/Status/StatusDisplay.js +3 -3
  182. package/dist/src/components/Status/StatusDisplay.js.map +1 -1
  183. package/dist/src/components/Table/Table.d.ts.map +1 -1
  184. package/dist/src/components/Table/Table.js +2 -2
  185. package/dist/src/components/Table/Table.js.map +1 -1
  186. package/dist/src/components/Table/TablePagination.d.ts +4 -3
  187. package/dist/src/components/Table/TablePagination.d.ts.map +1 -1
  188. package/dist/src/components/Table/TablePagination.js +6 -5
  189. package/dist/src/components/Table/TablePagination.js.map +1 -1
  190. package/dist/src/components/common/EditableLabelControl.d.ts.map +1 -1
  191. package/dist/src/components/common/EditableLabelControl.js +5 -7
  192. package/dist/src/components/common/EditableLabelControl.js.map +1 -1
  193. package/dist/src/components/common/TechPreviewBadge.d.ts +4 -0
  194. package/dist/src/components/common/TechPreviewBadge.d.ts.map +1 -0
  195. package/dist/src/components/common/TechPreviewBadge.js +23 -0
  196. package/dist/src/components/common/TechPreviewBadge.js.map +1 -0
  197. package/dist/src/components/form/LabelsField.d.ts.map +1 -1
  198. package/dist/src/components/form/LabelsField.js +4 -1
  199. package/dist/src/components/form/LabelsField.js.map +1 -1
  200. package/dist/src/components/form/NumberField.d.ts +10 -0
  201. package/dist/src/components/form/NumberField.d.ts.map +1 -0
  202. package/dist/src/components/form/NumberField.js +51 -0
  203. package/dist/src/components/form/NumberField.js.map +1 -0
  204. package/dist/src/components/form/TextListField.d.ts +12 -0
  205. package/dist/src/components/form/TextListField.d.ts.map +1 -0
  206. package/dist/src/components/form/TextListField.js +46 -0
  207. package/dist/src/components/form/TextListField.js.map +1 -0
  208. package/dist/src/components/form/validations.d.ts +34 -6
  209. package/dist/src/components/form/validations.d.ts.map +1 -1
  210. package/dist/src/components/form/validations.js +78 -4
  211. package/dist/src/components/form/validations.js.map +1 -1
  212. package/dist/src/components/modals/DecommissionModal/DecommissionModal.d.ts +9 -0
  213. package/dist/src/components/modals/DecommissionModal/DecommissionModal.d.ts.map +1 -0
  214. package/dist/src/components/modals/DecommissionModal/DecommissionModal.js +51 -0
  215. package/dist/src/components/modals/DecommissionModal/DecommissionModal.js.map +1 -0
  216. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.d.ts +4 -2
  217. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.d.ts.map +1 -1
  218. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.js +11 -4
  219. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.js.map +1 -1
  220. package/dist/src/components/modals/massModals/MassDecommissionDeviceModal/MassDecommissionDeviceModal.d.ts +10 -0
  221. package/dist/src/components/modals/massModals/MassDecommissionDeviceModal/MassDecommissionDeviceModal.d.ts.map +1 -0
  222. package/dist/src/components/modals/massModals/MassDecommissionDeviceModal/MassDecommissionDeviceModal.js +67 -0
  223. package/dist/src/components/modals/massModals/MassDecommissionDeviceModal/MassDecommissionDeviceModal.js.map +1 -0
  224. package/dist/src/constants.d.ts +1 -1
  225. package/dist/src/constants.d.ts.map +1 -1
  226. package/dist/src/constants.js +1 -1
  227. package/dist/src/constants.js.map +1 -1
  228. package/dist/src/hooks/useAppContext.d.ts +1 -1
  229. package/dist/src/hooks/useAppContext.d.ts.map +1 -1
  230. package/dist/src/hooks/useFetch.d.ts +1 -1
  231. package/dist/src/hooks/useFetchPeriodically.js +10 -10
  232. package/dist/src/hooks/useFetchPeriodically.js.map +1 -1
  233. package/dist/src/hooks/useTablePagination.d.ts +5 -3
  234. package/dist/src/hooks/useTablePagination.d.ts.map +1 -1
  235. package/dist/src/hooks/useTablePagination.js +9 -5
  236. package/dist/src/hooks/useTablePagination.js.map +1 -1
  237. package/dist/src/hooks/useWebSocket.d.ts +1 -1
  238. package/dist/src/hooks/useWebSocket.js +4 -4
  239. package/dist/src/hooks/useWebSocket.js.map +1 -1
  240. package/dist/src/links.d.ts +1 -0
  241. package/dist/src/links.d.ts.map +1 -1
  242. package/dist/src/links.js +2 -1
  243. package/dist/src/links.js.map +1 -1
  244. package/dist/src/types/rbac.d.ts +3 -1
  245. package/dist/src/types/rbac.d.ts.map +1 -1
  246. package/dist/src/types/rbac.js +2 -0
  247. package/dist/src/types/rbac.js.map +1 -1
  248. package/dist/src/utils/api.d.ts +3 -6
  249. package/dist/src/utils/api.d.ts.map +1 -1
  250. package/dist/src/utils/api.js.map +1 -1
  251. package/dist/src/utils/apiCalls.d.ts +2 -0
  252. package/dist/src/utils/apiCalls.d.ts.map +1 -0
  253. package/dist/src/utils/apiCalls.js +23 -0
  254. package/dist/src/utils/apiCalls.js.map +1 -0
  255. package/dist/src/utils/devices.d.ts +6 -3
  256. package/dist/src/utils/devices.d.ts.map +1 -1
  257. package/dist/src/utils/devices.js +20 -1
  258. package/dist/src/utils/devices.js.map +1 -1
  259. package/dist/src/utils/patch.d.ts +4 -1
  260. package/dist/src/utils/patch.d.ts.map +1 -1
  261. package/dist/src/utils/patch.js +166 -9
  262. package/dist/src/utils/patch.js.map +1 -1
  263. package/dist/src/utils/status/common.js +13 -12
  264. package/dist/src/utils/status/common.js.map +1 -1
  265. package/dist/src/utils/status/devices.d.ts +3 -3
  266. package/dist/src/utils/status/devices.d.ts.map +1 -1
  267. package/dist/src/utils/status/devices.js +40 -5
  268. package/dist/src/utils/status/devices.js.map +1 -1
  269. package/dist/src/utils/status/fleet.d.ts +4 -4
  270. package/dist/src/utils/status/fleet.d.ts.map +1 -1
  271. package/dist/src/utils/status/fleet.js +15 -2
  272. package/dist/src/utils/status/fleet.js.map +1 -1
  273. package/dist/src/utils/tooltip.d.ts +7 -0
  274. package/dist/src/utils/tooltip.d.ts.map +1 -0
  275. package/dist/src/utils/tooltip.js +6 -0
  276. package/dist/src/utils/tooltip.js.map +1 -0
  277. package/package.json +1 -1
  278. package/src/components/DetailsPage/DetailsPageActions.tsx +34 -6
  279. package/src/components/DetailsPage/Tables/ApplicationsTable.tsx +1 -1
  280. package/src/components/Device/DeviceDetails/DeviceApplications.tsx +3 -3
  281. package/src/components/Device/DeviceDetails/DeviceDetailsPage.tsx +53 -34
  282. package/src/components/Device/DeviceDetails/DeviceDetailsTab.tsx +71 -54
  283. package/src/components/Device/DeviceDetails/DeviceDetailsTabContent/StatusContent.tsx +75 -0
  284. package/src/components/Device/DeviceDetails/DeviceDetailsTabContent/SystemResourcesContent.tsx +47 -0
  285. package/src/components/Device/DeviceDetails/TerminalTab.tsx +1 -4
  286. package/src/components/Device/DevicesPage/DecommissionedDeviceTableRow.tsx +89 -0
  287. package/src/components/Device/DevicesPage/DecommissionedDevicesTable.tsx +156 -0
  288. package/src/components/Device/DevicesPage/DeviceNameOnlyToolbarFilter.tsx +30 -0
  289. package/src/components/Device/DevicesPage/DevicesEmptyStates.tsx +46 -0
  290. package/src/components/Device/DevicesPage/DevicesPage.tsx +45 -215
  291. package/src/components/Device/DevicesPage/{DeviceTableRow.tsx → EnrolledDeviceTableRow.tsx} +16 -20
  292. package/src/components/Device/DevicesPage/EnrolledDevicesTable.tsx +208 -0
  293. package/src/components/Device/DevicesPage/useDevices.ts +21 -1
  294. package/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsx +6 -3
  295. package/src/components/Device/EditDeviceWizard/EditDeviceWizardNav.tsx +1 -1
  296. package/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.tsx +2 -0
  297. package/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.tsx +1 -0
  298. package/src/components/Device/EditDeviceWizard/steps/ConfigurationTemplates.tsx +1 -0
  299. package/src/components/Device/EditDeviceWizard/steps/ReviewDeviceStep.tsx +27 -19
  300. package/src/components/Device/EditDeviceWizard/steps/ReviewUpdatePolicy.tsx +55 -0
  301. package/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.tsx +9 -7
  302. package/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.tsx +10 -36
  303. package/src/components/EnrollmentRequest/EnrollmentRequestList.tsx +2 -2
  304. package/src/components/EnrollmentRequest/EnrollmentRequestTableRow.tsx +2 -2
  305. package/src/components/EnrollmentRequest/useEnrollmentRequests.ts +3 -2
  306. package/src/components/Fleet/CreateFleet/CreateFleetWizard.tsx +46 -5
  307. package/src/components/Fleet/CreateFleet/CreateFleetWizardFooter.tsx +4 -0
  308. package/src/components/Fleet/CreateFleet/fleetSpecUtils.ts +62 -0
  309. package/src/components/Fleet/CreateFleet/steps/ReviewStep.tsx +65 -30
  310. package/src/components/Fleet/CreateFleet/steps/UpdateConfirmChangesModal.tsx +87 -0
  311. package/src/components/Fleet/CreateFleet/steps/UpdatePolicyStep.tsx +155 -0
  312. package/src/components/Fleet/CreateFleet/steps/UpdateStepDisruptionBudget.tsx +87 -0
  313. package/src/components/Fleet/CreateFleet/steps/UpdateStepRolloutPolicy.tsx +190 -0
  314. package/src/components/Fleet/CreateFleet/types.ts +25 -0
  315. package/src/components/Fleet/CreateFleet/utils.ts +20 -1
  316. package/src/components/Fleet/FleetDetails/FleetDetailsContent.tsx +10 -7
  317. package/src/components/Fleet/FleetDetails/{FleetDevices.tsx → FleetDevicesCharts.tsx} +4 -4
  318. package/src/components/Fleet/FleetDetails/FleetDevicesCount.tsx +53 -0
  319. package/src/components/Fleet/FleetResourceSyncs.tsx +2 -2
  320. package/src/components/Fleet/FleetRow.tsx +12 -4
  321. package/src/components/Fleet/FleetsPage.tsx +2 -2
  322. package/src/components/Fleet/useFleets.ts +7 -7
  323. package/src/components/ListPage/ListPage.tsx +12 -4
  324. package/src/components/ListPage/ListPageActions.tsx +50 -16
  325. package/src/components/ListPage/types.ts +8 -8
  326. package/src/components/OverviewPage/Cards/Status/DeviceStatusChart.tsx +0 -1
  327. package/src/components/OverviewPage/OverviewPage.tsx +12 -4
  328. package/src/components/Repository/RepositoryDetails/RepositoryResourceSyncsCard.tsx +1 -1
  329. package/src/components/Repository/useRepositories.ts +2 -2
  330. package/src/components/ResourceSync/RepositoryResourceSyncList.tsx +2 -2
  331. package/src/components/Status/DeviceLifecycleStatus.tsx +33 -0
  332. package/src/components/Status/StatusDisplay.tsx +4 -4
  333. package/src/components/Table/Table.tsx +2 -1
  334. package/src/components/Table/TablePagination.tsx +9 -7
  335. package/src/components/common/EditableLabelControl.tsx +7 -6
  336. package/src/components/common/TechPreviewBadge.tsx +43 -0
  337. package/src/components/form/LabelsField.tsx +4 -1
  338. package/src/components/form/NumberField.tsx +78 -0
  339. package/src/components/form/TextListField.tsx +82 -0
  340. package/src/components/form/validations.ts +103 -10
  341. package/src/components/modals/DecommissionModal/DecommissionModal.tsx +95 -0
  342. package/src/components/modals/EditLabelsModal/EditLabelsForm.tsx +9 -8
  343. package/src/components/modals/massModals/MassDecommissionDeviceModal/MassDecommissionDeviceModal.tsx +130 -0
  344. package/src/constants.ts +1 -1
  345. package/src/hooks/useAppContext.tsx +1 -1
  346. package/src/hooks/useFetchPeriodically.ts +11 -11
  347. package/src/hooks/{useTablePagination.tsx → useTablePagination.ts} +13 -7
  348. package/src/hooks/useWebSocket.ts +4 -4
  349. package/src/links.ts +2 -0
  350. package/src/types/rbac.ts +2 -0
  351. package/src/utils/api.ts +13 -6
  352. package/src/utils/apiCalls.ts +15 -0
  353. package/src/utils/devices.ts +21 -3
  354. package/src/utils/patch.ts +182 -8
  355. package/src/utils/status/common.ts +8 -8
  356. package/src/utils/status/devices.ts +39 -8
  357. package/src/utils/status/fleet.ts +21 -6
  358. package/src/utils/tooltip.ts +2 -0
  359. package/dist/src/components/DetailsPage/Tables/IntegrityDetails.d.ts +0 -8
  360. package/dist/src/components/DetailsPage/Tables/IntegrityDetails.d.ts.map +0 -1
  361. package/dist/src/components/DetailsPage/Tables/IntegrityDetails.js +0 -23
  362. package/dist/src/components/DetailsPage/Tables/IntegrityDetails.js.map +0 -1
  363. package/dist/src/components/Device/DevicesPage/DeviceTableRow.d.ts +0 -16
  364. package/dist/src/components/Device/DevicesPage/DeviceTableRow.d.ts.map +0 -1
  365. package/dist/src/components/Device/DevicesPage/DeviceTableRow.js.map +0 -1
  366. package/dist/src/components/Fleet/FleetDetails/FleetDevices.d.ts +0 -9
  367. package/dist/src/components/Fleet/FleetDetails/FleetDevices.d.ts.map +0 -1
  368. package/dist/src/components/Fleet/FleetDetails/FleetDevices.js.map +0 -1
  369. package/dist/src/components/Fleet/FleetDetails/FleetDevicesLink.d.ts +0 -7
  370. package/dist/src/components/Fleet/FleetDetails/FleetDevicesLink.d.ts.map +0 -1
  371. package/dist/src/components/Fleet/FleetDetails/FleetDevicesLink.js +0 -13
  372. package/dist/src/components/Fleet/FleetDetails/FleetDevicesLink.js.map +0 -1
  373. package/dist/src/components/Status/IntegrityStatus.d.ts +0 -7
  374. package/dist/src/components/Status/IntegrityStatus.d.ts.map +0 -1
  375. package/dist/src/components/Status/IntegrityStatus.js +0 -17
  376. package/dist/src/components/Status/IntegrityStatus.js.map +0 -1
  377. package/dist/src/utils/status/integrity.d.ts +0 -5
  378. package/dist/src/utils/status/integrity.d.ts.map +0 -1
  379. package/dist/src/utils/status/integrity.js +0 -28
  380. package/dist/src/utils/status/integrity.js.map +0 -1
  381. package/src/components/DetailsPage/Tables/IntegrityDetails.tsx +0 -44
  382. package/src/components/Fleet/FleetDetails/FleetDevicesLink.tsx +0 -16
  383. package/src/components/Status/IntegrityStatus.tsx +0 -19
  384. package/src/utils/status/integrity.ts +0 -26
@@ -1,217 +1,28 @@
1
1
  import * as React from 'react';
2
- import { Button, EmptyStateActions, EmptyStateBody, EmptyStateFooter, ToolbarItem } from '@patternfly/react-core';
3
- import { Tbody } from '@patternfly/react-table';
4
- import { MicrochipIcon } from '@patternfly/react-icons/dist/js/icons/microchip-icon';
5
- import { Trans } from 'react-i18next';
6
- import { TFunction } from 'i18next';
7
2
 
8
- import { useFetch } from '../../../hooks/useFetch';
9
- import { Device } from '@flightctl/types';
3
+ import { DeviceList } from '@flightctl/types';
10
4
 
11
5
  import ListPage from '../../ListPage/ListPage';
12
6
  import ListPageBody from '../../ListPage/ListPageBody';
13
- import { useDeleteListAction } from '../../ListPage/ListPageActions';
14
- import TablePagination from '../../Table/TablePagination';
15
- import AddDeviceModal from '../AddDeviceModal/AddDeviceModal';
16
- import Table, { ApiSortTableColumn } from '../../Table/Table';
17
- import DeviceTableToolbar from './DeviceTableToolbar';
18
- import DeviceTableRow from './DeviceTableRow';
19
- import { FlightCtlLabel } from '../../../types/extraTypes';
20
- import MassDeleteDeviceModal from '../../modals/massModals/MassDeleteDeviceModal/MassDeleteDeviceModal';
21
- import ResourceListEmptyState from '../../common/ResourceListEmptyState';
22
- import { useTableSelect } from '../../../hooks/useTableSelect';
23
7
  import { useTranslation } from '../../../hooks/useTranslation';
24
- import { Link, ROUTE } from '../../../hooks/useNavigate';
25
- import { PaginationDetails, useTablePagination } from '../../../hooks/useTablePagination';
8
+ import { useTablePagination } from '../../../hooks/useTablePagination';
9
+ import { isDeviceEnrolled } from '../../../utils/devices';
26
10
  import { useDevices } from './useDevices';
27
11
  import { useDeviceBackendFilters } from './useDeviceBackendFilters';
28
- import {
29
- getApplicationStatusHelperText,
30
- getDeviceStatusHelperText,
31
- getUpdateStatusHelperText,
32
- } from '../../Status/utils';
12
+
33
13
  import EnrollmentRequestList from '../../EnrollmentRequest/EnrollmentRequestList';
34
- import { FilterStatusMap } from './types';
35
14
  import PageWithPermissions from '../../common/PageWithPermissions';
36
15
  import { RESOURCE, VERB } from '../../../types/rbac';
37
16
  import { useAccessReview } from '../../../hooks/useAccessReview';
17
+ import EnrolledDevicesTable from './EnrolledDevicesTable';
18
+ import DecommissionedDevicesTable from './DecommissionedDevicesTable';
38
19
 
39
- type DeviceEmptyStateProps = {
40
- onAddDevice: VoidFunction;
41
- };
42
-
43
- const DeviceEmptyState: React.FC<DeviceEmptyStateProps> = ({ onAddDevice }) => {
44
- const { t } = useTranslation();
45
- const [canCreateFleet] = useAccessReview(RESOURCE.FLEET, VERB.CREATE);
46
- return (
47
- <ResourceListEmptyState icon={MicrochipIcon} titleText={t('No devices here!')}>
48
- <EmptyStateBody>
49
- {canCreateFleet ? (
50
- <Trans t={t}>
51
- You can add devices and label them to match fleets, or you can{' '}
52
- <Link to={ROUTE.FLEET_CREATE}>start with a fleet</Link> and add devices into it.
53
- </Trans>
54
- ) : (
55
- t('You can add devices and label them to match fleets')
56
- )}
57
- </EmptyStateBody>
58
- <EmptyStateFooter>
59
- <EmptyStateActions>
60
- <Button onClick={onAddDevice}>{t('Add devices')}</Button>
61
- </EmptyStateActions>
62
- </EmptyStateFooter>
63
- </ResourceListEmptyState>
64
- );
65
- };
66
-
67
- const getDeviceColumns = (t: TFunction): ApiSortTableColumn[] => [
68
- {
69
- name: t('Alias'),
70
- },
71
- {
72
- name: t('Name'),
73
- },
74
- {
75
- name: t('Fleet'),
76
- },
77
- {
78
- name: t('Application status'),
79
- helperText: getApplicationStatusHelperText(t),
80
- },
81
- {
82
- name: t('Device status'),
83
- helperText: getDeviceStatusHelperText(t),
84
- },
85
- {
86
- name: t('Update status'),
87
- helperText: getUpdateStatusHelperText(t),
88
- },
89
- {
90
- name: t('Last seen'),
91
- },
92
- ];
93
-
94
- interface DeviceTableProps {
95
- devices: Array<Device>;
96
- refetch: VoidFunction;
97
- ownerFleets: string[];
98
- activeStatuses: FilterStatusMap;
99
- hasFiltersEnabled: boolean;
100
- nameOrAlias: string | undefined;
101
- setNameOrAlias: (text: string) => void;
102
- setOwnerFleets: (ownerFleets: string[]) => void;
103
- setActiveStatuses: (activeStatuses: FilterStatusMap) => void;
104
- selectedLabels: FlightCtlLabel[];
105
- setSelectedLabels: (labels: FlightCtlLabel[]) => void;
106
- isFilterUpdating: boolean;
107
- deviceColumns: ApiSortTableColumn[];
108
- pagination: Pick<PaginationDetails, 'currentPage' | 'setCurrentPage' | 'itemCount'>;
109
- // getSortParams: (columnIndex: number) => ThProps['sort'];
110
- }
111
-
112
- export const DeviceTable = ({
113
- devices,
114
- refetch,
115
- nameOrAlias,
116
- setNameOrAlias,
117
- ownerFleets,
118
- setOwnerFleets,
119
- activeStatuses,
120
- setActiveStatuses,
121
- selectedLabels,
122
- setSelectedLabels,
123
- hasFiltersEnabled,
124
- isFilterUpdating,
125
- deviceColumns,
126
- pagination,
127
- }: DeviceTableProps) => {
128
- const { t } = useTranslation();
129
- const [addDeviceModal, setAddDeviceModal] = React.useState(false);
130
- const [isMassDeleteModalOpen, setIsMassDeleteModalOpen] = React.useState(false);
131
- const { remove } = useFetch();
132
-
133
- const { onRowSelect, hasSelectedRows, isAllSelected, isRowSelected, setAllSelected } = useTableSelect();
134
-
135
- const { deleteAction: deleteDeviceAction, deleteModal: deleteDeviceModal } = useDeleteListAction({
136
- resourceType: 'Device',
137
- onDelete: async (resourceId: string) => {
138
- await remove(`devices/${resourceId}`);
139
- refetch();
140
- },
141
- });
142
-
143
- const [canDelete] = useAccessReview(RESOURCE.DEVICE, VERB.DELETE);
144
- const [canEdit] = useAccessReview(RESOURCE.DEVICE, VERB.PATCH);
145
-
146
- return (
147
- <>
148
- <DeviceTableToolbar
149
- nameOrAlias={nameOrAlias}
150
- setNameOrAlias={setNameOrAlias}
151
- ownerFleets={ownerFleets}
152
- setOwnerFleets={setOwnerFleets}
153
- activeStatuses={activeStatuses}
154
- setActiveStatuses={setActiveStatuses}
155
- selectedLabels={selectedLabels}
156
- setSelectedLabels={setSelectedLabels}
157
- isFilterUpdating={isFilterUpdating}
158
- >
159
- <ToolbarItem>
160
- <Button onClick={() => setAddDeviceModal(true)}>{t('Add devices')}</Button>
161
- </ToolbarItem>
162
- {canDelete && (
163
- <ToolbarItem>
164
- <Button isDisabled={!hasSelectedRows} onClick={() => setIsMassDeleteModalOpen(true)} variant="secondary">
165
- {t('Delete devices')}
166
- </Button>
167
- </ToolbarItem>
168
- )}
169
- </DeviceTableToolbar>
170
- <Table
171
- aria-label={t('Devices table')}
172
- loading={isFilterUpdating}
173
- columns={deviceColumns}
174
- emptyFilters={!hasFiltersEnabled}
175
- emptyData={devices.length === 0}
176
- isAllSelected={isAllSelected}
177
- onSelectAll={setAllSelected}
178
- >
179
- <Tbody>
180
- {devices.map((device, index) => (
181
- <DeviceTableRow
182
- key={device.metadata.name || ''}
183
- device={device}
184
- deleteAction={deleteDeviceAction}
185
- onRowSelect={onRowSelect}
186
- isRowSelected={isRowSelected}
187
- rowIndex={index}
188
- canDelete={canDelete}
189
- canEdit={canEdit}
190
- />
191
- ))}
192
- </Tbody>
193
- </Table>
194
- <TablePagination isUpdating={isFilterUpdating} pagination={pagination} />
195
- {!hasFiltersEnabled && devices.length === 0 && <DeviceEmptyState onAddDevice={() => setAddDeviceModal(true)} />}
196
- {deleteDeviceModal}
197
- {addDeviceModal && <AddDeviceModal onClose={() => setAddDeviceModal(false)} />}
198
- {isMassDeleteModalOpen && (
199
- <MassDeleteDeviceModal
200
- onClose={() => setIsMassDeleteModalOpen(false)}
201
- resources={devices.filter(isRowSelected)}
202
- onDeleteSuccess={() => {
203
- setIsMassDeleteModalOpen(false);
204
- refetch();
205
- }}
206
- />
207
- )}
208
- </>
209
- );
20
+ const removeDecommissionedDevices = (data: DeviceList) => {
21
+ data.items = data.items.filter(isDeviceEnrolled);
210
22
  };
211
23
 
212
24
  const DevicesPage = ({ canListER }: { canListER: boolean }) => {
213
25
  const { t } = useTranslation();
214
- const deviceColumns = React.useMemo(() => getDeviceColumns(t), [t]);
215
26
 
216
27
  const {
217
28
  nameOrAlias,
@@ -224,10 +35,16 @@ const DevicesPage = ({ canListER }: { canListER: boolean }) => {
224
35
  selectedLabels,
225
36
  setSelectedLabels,
226
37
  } = useDeviceBackendFilters();
227
- const { currentPage, setCurrentPage, onPageFetched, nextContinue, itemCount } = useTablePagination();
38
+ const [onlyDecommissioned, setOnlyDecommissioned] = React.useState<boolean>(false);
39
+
40
+ const { currentPage, setCurrentPage, onPageFetched, nextContinue, itemCount } = useTablePagination<DeviceList>(
41
+ onlyDecommissioned ? undefined : removeDecommissionedDevices,
42
+ );
43
+
228
44
  const [data, loading, error, updating, refetch] = useDevices({
229
45
  nameOrAlias,
230
46
  ownerFleets,
47
+ onlyDecommissioned,
231
48
  activeStatuses,
232
49
  labels: selectedLabels,
233
50
  nextContinue,
@@ -248,23 +65,36 @@ const DevicesPage = ({ canListER }: { canListER: boolean }) => {
248
65
  {canListER && <EnrollmentRequestList refetchDevices={refetch} />}
249
66
 
250
67
  <ListPage title={t('Devices')}>
251
- <ListPageBody error={error} loading={loading}>
252
- <DeviceTable
253
- devices={data}
254
- refetch={refetch}
255
- nameOrAlias={nameOrAlias}
256
- setNameOrAlias={setNameOrAlias}
257
- hasFiltersEnabled={hasFiltersEnabled || updating}
258
- ownerFleets={ownerFleets}
259
- activeStatuses={activeStatuses}
260
- setOwnerFleets={setOwnerFleets}
261
- setActiveStatuses={setActiveStatuses}
262
- selectedLabels={selectedLabels}
263
- setSelectedLabels={setSelectedLabels}
264
- isFilterUpdating={updating}
265
- deviceColumns={deviceColumns}
266
- pagination={pagination}
267
- />
68
+ {/* When searching for decommissioned devices we want to avoid showing the enrolled devices */}
69
+ <ListPageBody error={error} loading={loading || (onlyDecommissioned && updating && !hasFiltersEnabled)}>
70
+ {onlyDecommissioned ? (
71
+ <DecommissionedDevicesTable
72
+ devices={data}
73
+ refetch={refetch}
74
+ nameOrAlias={nameOrAlias}
75
+ setNameOrAlias={setNameOrAlias}
76
+ hasFiltersEnabled={hasFiltersEnabled || updating}
77
+ setOnlyDecommissioned={setOnlyDecommissioned}
78
+ isFilterUpdating={updating}
79
+ pagination={pagination}
80
+ />
81
+ ) : (
82
+ <EnrolledDevicesTable
83
+ devices={data}
84
+ nameOrAlias={nameOrAlias}
85
+ setNameOrAlias={setNameOrAlias}
86
+ hasFiltersEnabled={hasFiltersEnabled || updating}
87
+ ownerFleets={ownerFleets}
88
+ setOnlyDecommissioned={setOnlyDecommissioned}
89
+ activeStatuses={activeStatuses}
90
+ setOwnerFleets={setOwnerFleets}
91
+ setActiveStatuses={setActiveStatuses}
92
+ selectedLabels={selectedLabels}
93
+ setSelectedLabels={setSelectedLabels}
94
+ isFilterUpdating={updating}
95
+ pagination={pagination}
96
+ />
97
+ )}
268
98
  </ListPageBody>
269
99
  </ListPage>
270
100
  </>
@@ -4,8 +4,9 @@ import { ActionsColumn, OnSelect, Td, Tr } from '@patternfly/react-table';
4
4
  import { Device } from '@flightctl/types';
5
5
  import DeviceFleet from '../DeviceDetails/DeviceFleet';
6
6
  import { timeSinceText } from '../../../utils/dates';
7
- import { getDeviceFleet } from '../../../utils/devices';
8
- import { DeleteListActionResult } from '../../ListPage/types';
7
+ import { getDecommissionDisabledReason, getEditDisabledReason } from '../../../utils/devices';
8
+ import { getDisabledTooltipProps } from '../../../utils/tooltip';
9
+ import { ListAction } from '../../ListPage/types';
9
10
  import ApplicationSummaryStatus from '../../Status/ApplicationSummaryStatus';
10
11
  import DeviceStatus from '../../Status/DeviceStatus';
11
12
  import SystemUpdateStatus from '../../Status/SystemUpdateStatus';
@@ -13,37 +14,31 @@ import { useTranslation } from '../../../hooks/useTranslation';
13
14
  import { ROUTE, useNavigate } from '../../../hooks/useNavigate';
14
15
  import ResourceLink from '../../common/ResourceLink';
15
16
 
16
- type DeviceTableRowProps = {
17
+ type EnrolledDeviceTableRowProps = {
17
18
  device: Device;
18
- deleteAction: DeleteListActionResult['deleteAction'];
19
19
  rowIndex: number;
20
20
  onRowSelect: (device: Device) => OnSelect;
21
21
  isRowSelected: (device: Device) => boolean;
22
- canDelete: boolean;
23
22
  canEdit: boolean;
23
+ canDecommission: boolean;
24
+ decommissionAction: ListAction;
24
25
  };
25
26
 
26
- const DeviceTableRow: React.FC<DeviceTableRowProps> = ({
27
+ const EnrolledDeviceTableRow = ({
27
28
  device,
28
- deleteAction,
29
29
  rowIndex,
30
30
  onRowSelect,
31
31
  isRowSelected,
32
- canDelete,
33
32
  canEdit,
34
- }) => {
33
+ canDecommission,
34
+ decommissionAction,
35
+ }: EnrolledDeviceTableRowProps) => {
35
36
  const { t } = useTranslation();
36
37
  const navigate = useNavigate();
37
38
  const deviceName = device.metadata.name as string;
38
39
  const deviceAlias = device.metadata.labels?.alias;
39
- const editActionProps = getDeviceFleet(device?.metadata)
40
- ? {
41
- isAriaDisabled: true,
42
- tooltipProps: {
43
- content: t('Device is bound to a fleet. Its configurations cannot be edited'),
44
- },
45
- }
46
- : undefined;
40
+ const editActionProps = getDisabledTooltipProps(getEditDisabledReason(device, t));
41
+ const decommissionDisabledReason = getDecommissionDisabledReason(device, t);
47
42
 
48
43
  return (
49
44
  <Tr>
@@ -89,11 +84,12 @@ const DeviceTableRow: React.FC<DeviceTableRowProps> = ({
89
84
  title: t('View device details'),
90
85
  onClick: () => navigate({ route: ROUTE.DEVICE_DETAILS, postfix: deviceName }),
91
86
  },
92
- ...(canDelete
87
+ ...(canDecommission
93
88
  ? [
94
- deleteAction({
89
+ decommissionAction({
95
90
  resourceId: deviceName,
96
91
  resourceName: deviceAlias,
92
+ disabledReason: decommissionDisabledReason,
97
93
  }),
98
94
  ]
99
95
  : []),
@@ -104,4 +100,4 @@ const DeviceTableRow: React.FC<DeviceTableRowProps> = ({
104
100
  );
105
101
  };
106
102
 
107
- export default DeviceTableRow;
103
+ export default EnrolledDeviceTableRow;
@@ -0,0 +1,208 @@
1
+ import * as React from 'react';
2
+ import { Button, Switch, ToolbarItem } from '@patternfly/react-core';
3
+ import { Tbody } from '@patternfly/react-table';
4
+ import { TFunction } from 'react-i18next';
5
+
6
+ import { Device, DeviceDecommission, DeviceDecommissionTargetType, DeviceList } from '@flightctl/types';
7
+
8
+ import { FilterStatusMap } from './types';
9
+ import { FlightCtlLabel } from '../../../types/extraTypes';
10
+ import { PaginationDetails } from '../../../hooks/useTablePagination';
11
+ import { useTranslation } from '../../../hooks/useTranslation';
12
+ import { useTableSelect } from '../../../hooks/useTableSelect';
13
+ import { useAccessReview } from '../../../hooks/useAccessReview';
14
+ import { useFetch } from '../../../hooks/useFetch';
15
+ import { RESOURCE, VERB } from '../../../types/rbac';
16
+ import {
17
+ getApplicationStatusHelperText,
18
+ getDeviceStatusHelperText,
19
+ getUpdateStatusHelperText,
20
+ } from '../../Status/utils';
21
+
22
+ import Table, { ApiSortTableColumn } from '../../Table/Table';
23
+ import { useDecommissionListAction } from '../../ListPage/ListPageActions';
24
+ import TablePagination from '../../Table/TablePagination';
25
+ import MassDecommissionDeviceModal from '../../modals/massModals/MassDecommissionDeviceModal/MassDecommissionDeviceModal';
26
+ import AddDeviceModal from '../AddDeviceModal/AddDeviceModal';
27
+ import { EnrolledDevicesEmptyState } from './DevicesEmptyStates';
28
+ import DeviceTableToolbar from './DeviceTableToolbar';
29
+ import EnrolledDeviceTableRow from './EnrolledDeviceTableRow';
30
+ import { FilterSearchParams } from '../../../utils/status/devices';
31
+
32
+ interface EnrolledDeviceTableProps {
33
+ devices: Array<Device>;
34
+ ownerFleets: string[];
35
+ activeStatuses: FilterStatusMap;
36
+ hasFiltersEnabled: boolean;
37
+ nameOrAlias: string | undefined;
38
+ setOnlyDecommissioned: (check: boolean) => void;
39
+ setNameOrAlias: (text: string) => void;
40
+ setOwnerFleets: (ownerFleets: string[]) => void;
41
+ setActiveStatuses: (activeStatuses: FilterStatusMap) => void;
42
+ selectedLabels: FlightCtlLabel[];
43
+ setSelectedLabels: (labels: FlightCtlLabel[]) => void;
44
+ isFilterUpdating: boolean;
45
+ pagination: Pick<PaginationDetails<DeviceList>, 'currentPage' | 'setCurrentPage' | 'itemCount'>;
46
+ // getSortParams: (columnIndex: number) => ThProps['sort'];
47
+ }
48
+
49
+ const getDeviceColumns = (t: TFunction): ApiSortTableColumn[] => [
50
+ {
51
+ name: t('Alias'),
52
+ },
53
+ {
54
+ name: t('Name'),
55
+ },
56
+ {
57
+ name: t('Fleet'),
58
+ },
59
+ {
60
+ name: t('Application status'),
61
+ helperText: getApplicationStatusHelperText(t),
62
+ },
63
+ {
64
+ name: t('Device status'),
65
+ helperText: getDeviceStatusHelperText(t),
66
+ },
67
+ {
68
+ name: t('Update status'),
69
+ helperText: getUpdateStatusHelperText(t),
70
+ },
71
+ {
72
+ name: t('Last seen'),
73
+ },
74
+ ];
75
+
76
+ const EnrolledDevicesTable = ({
77
+ devices,
78
+ nameOrAlias,
79
+ setNameOrAlias,
80
+ ownerFleets,
81
+ setOwnerFleets,
82
+ activeStatuses,
83
+ setActiveStatuses,
84
+ setOnlyDecommissioned,
85
+ selectedLabels,
86
+ setSelectedLabels,
87
+ hasFiltersEnabled,
88
+ isFilterUpdating,
89
+ pagination,
90
+ }: EnrolledDeviceTableProps) => {
91
+ const { t } = useTranslation();
92
+ const { put } = useFetch();
93
+
94
+ const [addDeviceModal, setAddDeviceModal] = React.useState(false);
95
+ const [isMassDecommissionModalOpen, setIsMassDecommissionModalOpen] = React.useState(false);
96
+ const deviceColumns = React.useMemo(() => getDeviceColumns(t), [t]);
97
+
98
+ const { onRowSelect, hasSelectedRows, isAllSelected, isRowSelected, setAllSelected } = useTableSelect();
99
+
100
+ const { action: decommissionDeviceAction, modal: decommissionDeviceModal } = useDecommissionListAction({
101
+ resourceType: 'Device',
102
+ onConfirm: async (deviceId: string, params) => {
103
+ await put<DeviceDecommission>(`devices/${deviceId}/decommission`, {
104
+ target: params?.target || DeviceDecommissionTargetType.DeviceDecommissionTargetTypeUnenroll,
105
+ });
106
+ setOnlyDecommissioned(true);
107
+ },
108
+ });
109
+
110
+ const [canEdit] = useAccessReview(RESOURCE.DEVICE, VERB.PATCH);
111
+ const [canDecommission] = useAccessReview(RESOURCE.DEVICE_DECOMMISSION, VERB.UPDATE);
112
+
113
+ return (
114
+ <>
115
+ <DeviceTableToolbar
116
+ nameOrAlias={nameOrAlias}
117
+ setNameOrAlias={setNameOrAlias}
118
+ ownerFleets={ownerFleets}
119
+ setOwnerFleets={setOwnerFleets}
120
+ activeStatuses={activeStatuses}
121
+ setActiveStatuses={setActiveStatuses}
122
+ selectedLabels={selectedLabels}
123
+ setSelectedLabels={setSelectedLabels}
124
+ isFilterUpdating={isFilterUpdating}
125
+ >
126
+ <ToolbarItem>
127
+ <Button aria-label={t('Add devices')} onClick={() => setAddDeviceModal(true)}>
128
+ {t('Add devices')}
129
+ </Button>
130
+ </ToolbarItem>
131
+ {canDecommission && (
132
+ <ToolbarItem>
133
+ <Button
134
+ isDisabled={!hasSelectedRows}
135
+ onClick={() => setIsMassDecommissionModalOpen(true)}
136
+ variant="secondary"
137
+ >
138
+ {t('Decommission devices')}
139
+ </Button>
140
+ </ToolbarItem>
141
+ )}
142
+ <ToolbarItem alignSelf="center">
143
+ <Switch
144
+ id="enrolled-devices-switch"
145
+ label={t('Show only decommissioned devices')}
146
+ isChecked={false}
147
+ onChange={() => {
148
+ if (hasFiltersEnabled) {
149
+ setActiveStatuses({
150
+ [FilterSearchParams.AppStatus]: [],
151
+ [FilterSearchParams.DeviceStatus]: [],
152
+ [FilterSearchParams.UpdatedStatus]: [],
153
+ });
154
+ setOwnerFleets([]);
155
+ setNameOrAlias('');
156
+ setSelectedLabels([]);
157
+ }
158
+ setOnlyDecommissioned(true);
159
+ }}
160
+ ouiaId={t('Show only decommissioned devices')}
161
+ />
162
+ </ToolbarItem>
163
+ </DeviceTableToolbar>
164
+ <Table
165
+ aria-label={t('Enrolled devices table')}
166
+ loading={isFilterUpdating}
167
+ columns={deviceColumns}
168
+ emptyFilters={!hasFiltersEnabled}
169
+ emptyData={devices.length === 0}
170
+ isAllSelected={isAllSelected}
171
+ onSelectAll={setAllSelected}
172
+ >
173
+ <Tbody>
174
+ {devices.map((device, index) => (
175
+ <EnrolledDeviceTableRow
176
+ key={device.metadata.name || ''}
177
+ device={device}
178
+ onRowSelect={onRowSelect}
179
+ isRowSelected={isRowSelected}
180
+ rowIndex={index}
181
+ canEdit={canEdit}
182
+ canDecommission={canDecommission}
183
+ decommissionAction={decommissionDeviceAction}
184
+ />
185
+ ))}
186
+ </Tbody>
187
+ </Table>
188
+ <TablePagination isUpdating={isFilterUpdating} pagination={pagination} />
189
+ {!hasFiltersEnabled && devices.length === 0 && (
190
+ <EnrolledDevicesEmptyState onAddDevice={() => setAddDeviceModal(true)} />
191
+ )}
192
+ {decommissionDeviceModal}
193
+ {addDeviceModal && <AddDeviceModal onClose={() => setAddDeviceModal(false)} />}
194
+ {isMassDecommissionModalOpen && (
195
+ <MassDecommissionDeviceModal
196
+ onClose={() => setIsMassDecommissionModalOpen(false)}
197
+ devices={devices.filter(isRowSelected)}
198
+ onSuccess={() => {
199
+ setIsMassDecommissionModalOpen(false);
200
+ setOnlyDecommissioned(true);
201
+ }}
202
+ />
203
+ )}
204
+ </>
205
+ );
206
+ };
207
+
208
+ export default EnrolledDevicesTable;
@@ -1,6 +1,6 @@
1
1
  import { useDebounce } from 'use-debounce';
2
2
 
3
- import { Device, DeviceList, DevicesSummary } from '@flightctl/types';
3
+ import { Device, DeviceLifecycleStatusType, DeviceList, DevicesSummary } from '@flightctl/types';
4
4
  import { FilterSearchParams } from '../../../utils/status/devices';
5
5
  import * as queryUtils from '../../../utils/query';
6
6
  import { useFetchPeriodically } from '../../../hooks/useFetchPeriodically';
@@ -12,16 +12,28 @@ type DevicesEndpointArgs = {
12
12
  nameOrAlias?: string;
13
13
  ownerFleets?: string[];
14
14
  activeStatuses?: FilterStatusMap;
15
+ onlyDecommissioned?: boolean;
15
16
  labels?: FlightCtlLabel[];
16
17
  summaryOnly?: boolean;
17
18
  nextContinue?: string;
18
19
  };
19
20
 
21
+ const enrolledStatuses = [
22
+ DeviceLifecycleStatusType.DeviceLifecycleStatusEnrolled,
23
+ DeviceLifecycleStatusType.DeviceLifecycleStatusUnknown,
24
+ ];
25
+
26
+ const decommissionedStatuses = [
27
+ DeviceLifecycleStatusType.DeviceLifecycleStatusDecommissioned,
28
+ DeviceLifecycleStatusType.DeviceLifecycleStatusDecommissioning,
29
+ ];
30
+
20
31
  const getDevicesEndpoint = ({
21
32
  nameOrAlias,
22
33
  ownerFleets,
23
34
  activeStatuses,
24
35
  labels,
36
+ onlyDecommissioned,
25
37
  nextContinue,
26
38
  summaryOnly,
27
39
  }: DevicesEndpointArgs) => {
@@ -45,6 +57,12 @@ const getDevicesEndpoint = ({
45
57
  );
46
58
  }
47
59
 
60
+ if (onlyDecommissioned) {
61
+ queryUtils.addQueryConditions(fieldSelectors, 'status.lifecycle.status', decommissionedStatuses);
62
+ } else if (summaryOnly) {
63
+ queryUtils.addQueryConditions(fieldSelectors, 'status.lifecycle.status', enrolledStatuses);
64
+ }
65
+
48
66
  const params = new URLSearchParams();
49
67
  if (fieldSelectors.length > 0) {
50
68
  params.set('fieldSelector', fieldSelectors.join(','));
@@ -65,6 +83,7 @@ const getDevicesEndpoint = ({
65
83
  export const useDevicesEndpoint = (args: DevicesEndpointArgs): [string, boolean] => {
66
84
  const endpoint = getDevicesEndpoint(args);
67
85
  const [devicesEndpointDebounced] = useDebounce(endpoint, 1000);
86
+
68
87
  return [devicesEndpointDebounced, endpoint !== devicesEndpointDebounced];
69
88
  };
70
89
 
@@ -88,6 +107,7 @@ export const useDevices = (args: {
88
107
  ownerFleets?: string[];
89
108
  activeStatuses?: FilterStatusMap;
90
109
  labels?: FlightCtlLabel[];
110
+ onlyDecommissioned: boolean;
91
111
  nextContinue?: string;
92
112
  onPageFetched?: (data: DeviceList) => void;
93
113
  }): [Device[], boolean, unknown, boolean, VoidFunction] => {
@@ -17,6 +17,7 @@ import { Device } from '@flightctl/types';
17
17
  import { EditDeviceFormValues } from './types';
18
18
  import { getErrorMessage } from '../../../utils/error';
19
19
  import { fromAPILabel } from '../../../utils/labels';
20
+ import { getEditDisabledReason } from '../../../utils/devices';
20
21
  import { useTranslation } from '../../../hooks/useTranslation';
21
22
  import { Link, ROUTE, useNavigate } from '../../../hooks/useNavigate';
22
23
  import LeaveFormConfirmation from '../../common/LeaveFormConfirmation';
@@ -47,6 +48,8 @@ const EditDeviceWizard = () => {
47
48
  const deviceAlias = device?.metadata.labels?.alias || '';
48
49
  const displayText = device ? deviceAlias || t('Untitled') : deviceId;
49
50
 
51
+ const editDisabledReason = device ? getEditDisabledReason(device, t) : undefined;
52
+
50
53
  let body: React.ReactNode;
51
54
  if (isLoading) {
52
55
  body = (
@@ -60,10 +63,10 @@ const EditDeviceWizard = () => {
60
63
  {getErrorMessage(loadError)}
61
64
  </Alert>
62
65
  );
63
- } else if (!!device?.metadata.owner) {
66
+ } else if (editDisabledReason) {
64
67
  body = (
65
68
  <Alert isInline variant="info" title={t('Device is non-editable')}>
66
- {t('This device is managed by a fleet and it cannot be edited directly.')}
69
+ {editDisabledReason}
67
70
  </Alert>
68
71
  );
69
72
  } else if (device) {
@@ -120,7 +123,7 @@ const EditDeviceWizard = () => {
120
123
  <WizardStep name={t('Device template')} id={deviceTemplateStepId} isDisabled={isTemplateStepDisabled}>
121
124
  <DeviceTemplateStep isFleet={false} />
122
125
  </WizardStep>
123
- <WizardStep name={t('Review and update')} id={reviewDeviceStepId} isDisabled={!templateStepValid}>
126
+ <WizardStep name={t('Review and save')} id={reviewDeviceStepId} isDisabled={!templateStepValid}>
124
127
  <ReviewDeviceStep error={submitError} />
125
128
  </WizardStep>
126
129
  </Wizard>