@flightctl/ui-components 0.0.5 → 0.4.0-rc1

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 (506) hide show
  1. package/dist/src/components/DetailsPage/Tables/ApplicationsTable.css +7 -0
  2. package/dist/src/components/DetailsPage/Tables/ApplicationsTable.d.ts +8 -1
  3. package/dist/src/components/DetailsPage/Tables/ApplicationsTable.d.ts.map +1 -1
  4. package/dist/src/components/DetailsPage/Tables/ApplicationsTable.js +91 -9
  5. package/dist/src/components/DetailsPage/Tables/ApplicationsTable.js.map +1 -1
  6. package/dist/src/components/Device/AddDeviceModal/AddDeviceModal.d.ts.map +1 -1
  7. package/dist/src/components/Device/AddDeviceModal/AddDeviceModal.js +15 -51
  8. package/dist/src/components/Device/AddDeviceModal/AddDeviceModal.js.map +1 -1
  9. package/dist/src/components/Device/DeviceDetails/DeviceApplications.d.ts +10 -0
  10. package/dist/src/components/Device/DeviceDetails/DeviceApplications.d.ts.map +1 -0
  11. package/dist/src/components/Device/DeviceDetails/DeviceApplications.js +65 -0
  12. package/dist/src/components/Device/DeviceDetails/DeviceApplications.js.map +1 -0
  13. package/dist/src/components/Device/DeviceDetails/DeviceDetailsPage.d.ts +5 -2
  14. package/dist/src/components/Device/DeviceDetails/DeviceDetailsPage.d.ts.map +1 -1
  15. package/dist/src/components/Device/DeviceDetails/DeviceDetailsPage.js +19 -10
  16. package/dist/src/components/Device/DeviceDetails/DeviceDetailsPage.js.map +1 -1
  17. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTab.d.ts +3 -4
  18. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTab.d.ts.map +1 -1
  19. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTab.js +6 -18
  20. package/dist/src/components/Device/DeviceDetails/DeviceDetailsTab.js.map +1 -1
  21. package/dist/src/components/Device/DeviceDetails/TerminalTab.d.ts +4 -3
  22. package/dist/src/components/Device/DeviceDetails/TerminalTab.d.ts.map +1 -1
  23. package/dist/src/components/Device/DeviceDetails/TerminalTab.js +13 -4
  24. package/dist/src/components/Device/DeviceDetails/TerminalTab.js.map +1 -1
  25. package/dist/src/components/Device/DevicesPage/DeviceFilterSelect.d.ts.map +1 -1
  26. package/dist/src/components/Device/DevicesPage/DeviceFilterSelect.js +4 -14
  27. package/dist/src/components/Device/DevicesPage/DeviceFilterSelect.js.map +1 -1
  28. package/dist/src/components/Device/DevicesPage/DeviceTableRow.d.ts +2 -0
  29. package/dist/src/components/Device/DevicesPage/DeviceTableRow.d.ts.map +1 -1
  30. package/dist/src/components/Device/DevicesPage/DeviceTableRow.js +14 -6
  31. package/dist/src/components/Device/DevicesPage/DeviceTableRow.js.map +1 -1
  32. package/dist/src/components/Device/DevicesPage/DeviceTableToolbar.d.ts +2 -5
  33. package/dist/src/components/Device/DevicesPage/DeviceTableToolbar.d.ts.map +1 -1
  34. package/dist/src/components/Device/DevicesPage/DeviceTableToolbar.js +8 -8
  35. package/dist/src/components/Device/DevicesPage/DeviceTableToolbar.js.map +1 -1
  36. package/dist/src/components/Device/DevicesPage/DeviceToolbarFilters.d.ts +3 -6
  37. package/dist/src/components/Device/DevicesPage/DeviceToolbarFilters.d.ts.map +1 -1
  38. package/dist/src/components/Device/DevicesPage/DeviceToolbarFilters.js +91 -17
  39. package/dist/src/components/Device/DevicesPage/DeviceToolbarFilters.js.map +1 -1
  40. package/dist/src/components/Device/DevicesPage/DevicesPage.d.ts +10 -6
  41. package/dist/src/components/Device/DevicesPage/DevicesPage.d.ts.map +1 -1
  42. package/dist/src/components/Device/DevicesPage/DevicesPage.js +46 -42
  43. package/dist/src/components/Device/DevicesPage/DevicesPage.js.map +1 -1
  44. package/dist/src/components/Device/DevicesPage/types.d.ts +1 -10
  45. package/dist/src/components/Device/DevicesPage/types.d.ts.map +1 -1
  46. package/dist/src/components/Device/DevicesPage/types.js.map +1 -1
  47. package/dist/src/components/Device/DevicesPage/useDeviceBackendFilters.d.ts +2 -0
  48. package/dist/src/components/Device/DevicesPage/useDeviceBackendFilters.d.ts.map +1 -1
  49. package/dist/src/components/Device/DevicesPage/useDeviceBackendFilters.js +10 -3
  50. package/dist/src/components/Device/DevicesPage/useDeviceBackendFilters.js.map +1 -1
  51. package/dist/src/components/Device/DevicesPage/useDevices.d.ts +8 -3
  52. package/dist/src/components/Device/DevicesPage/useDevices.d.ts.map +1 -1
  53. package/dist/src/components/Device/DevicesPage/useDevices.js +26 -47
  54. package/dist/src/components/Device/DevicesPage/useDevices.js.map +1 -1
  55. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizard.d.ts +2 -2
  56. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizard.d.ts.map +1 -1
  57. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizard.js +19 -4
  58. package/dist/src/components/Device/EditDeviceWizard/EditDeviceWizard.js.map +1 -1
  59. package/dist/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts +7 -2
  60. package/dist/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts.map +1 -1
  61. package/dist/src/components/Device/EditDeviceWizard/deviceSpecUtils.js +99 -7
  62. package/dist/src/components/Device/EditDeviceWizard/deviceSpecUtils.js.map +1 -1
  63. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.d.ts +5 -0
  64. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.d.ts.map +1 -0
  65. package/dist/src/components/Device/EditDeviceWizard/steps/{ApplicationsForm.js → ApplicationTemplates.js} +31 -24
  66. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js.map +1 -0
  67. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.d.ts.map +1 -1
  68. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.js +9 -10
  69. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.js.map +1 -1
  70. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.d.ts +2 -1
  71. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.d.ts.map +1 -1
  72. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.js +5 -6
  73. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.js.map +1 -1
  74. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigurationTemplates.d.ts +4 -0
  75. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigurationTemplates.d.ts.map +1 -0
  76. package/dist/src/components/Device/EditDeviceWizard/steps/{ConfigTemplateForm.js → ConfigurationTemplates.js} +42 -28
  77. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigurationTemplates.js.map +1 -0
  78. package/dist/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.d.ts.map +1 -1
  79. package/dist/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.js +53 -12
  80. package/dist/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.js.map +1 -1
  81. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewTrackedSystemdServices.d.ts +7 -0
  82. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewTrackedSystemdServices.d.ts.map +1 -0
  83. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewTrackedSystemdServices.js +13 -0
  84. package/dist/src/components/Device/EditDeviceWizard/steps/ReviewTrackedSystemdServices.js.map +1 -0
  85. package/dist/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.d.ts +4 -0
  86. package/dist/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.d.ts.map +1 -0
  87. package/dist/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.js +38 -0
  88. package/dist/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.js.map +1 -0
  89. package/dist/src/components/Device/EditDeviceWizard/types.d.ts +3 -0
  90. package/dist/src/components/Device/EditDeviceWizard/types.d.ts.map +1 -1
  91. package/dist/src/components/Device/EditDeviceWizard/utils.d.ts +1 -0
  92. package/dist/src/components/Device/EditDeviceWizard/utils.d.ts.map +1 -1
  93. package/dist/src/components/Device/EditDeviceWizard/utils.js +5 -2
  94. package/dist/src/components/Device/EditDeviceWizard/utils.js.map +1 -1
  95. package/dist/src/components/Device/{MatchPatternsModal/MatchPatternsModal.d.ts → SystemdUnitsModal/SystemdUnitsModal.d.ts} +6 -6
  96. package/dist/src/components/Device/SystemdUnitsModal/SystemdUnitsModal.d.ts.map +1 -0
  97. package/dist/src/components/Device/{MatchPatternsModal/MatchPatternsModal.js → SystemdUnitsModal/SystemdUnitsModal.js} +28 -15
  98. package/dist/src/components/Device/SystemdUnitsModal/SystemdUnitsModal.js.map +1 -0
  99. package/dist/src/components/Device/SystemdUnitsModal/TrackSystemdUnitsForm.d.ts +15 -0
  100. package/dist/src/components/Device/SystemdUnitsModal/TrackSystemdUnitsForm.d.ts.map +1 -0
  101. package/dist/src/components/Device/SystemdUnitsModal/TrackSystemdUnitsForm.js +57 -0
  102. package/dist/src/components/Device/SystemdUnitsModal/TrackSystemdUnitsForm.js.map +1 -0
  103. package/dist/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.d.ts +2 -2
  104. package/dist/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.d.ts.map +1 -1
  105. package/dist/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.js +14 -4
  106. package/dist/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.js.map +1 -1
  107. package/dist/src/components/EnrollmentRequest/EnrollmentRequestList.d.ts +9 -0
  108. package/dist/src/components/EnrollmentRequest/EnrollmentRequestList.d.ts.map +1 -0
  109. package/dist/src/components/EnrollmentRequest/EnrollmentRequestList.js +97 -0
  110. package/dist/src/components/EnrollmentRequest/EnrollmentRequestList.js.map +1 -0
  111. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableRow.d.ts +2 -0
  112. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableRow.d.ts.map +1 -1
  113. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableRow.js +15 -11
  114. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableRow.js.map +1 -1
  115. package/dist/src/components/{Device/DevicesPage → EnrollmentRequest}/EnrollmentRequestTableToolbar.d.ts +1 -1
  116. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableToolbar.d.ts.map +1 -0
  117. package/dist/src/components/{Device/DevicesPage → EnrollmentRequest}/EnrollmentRequestTableToolbar.js +2 -2
  118. package/dist/src/components/EnrollmentRequest/EnrollmentRequestTableToolbar.js.map +1 -0
  119. package/dist/src/components/EnrollmentRequest/PendingEnrollmentRequestsBadge.css +10 -0
  120. package/dist/src/components/EnrollmentRequest/PendingEnrollmentRequestsBadge.d.ts +5 -0
  121. package/dist/src/components/EnrollmentRequest/PendingEnrollmentRequestsBadge.d.ts.map +1 -0
  122. package/dist/src/components/EnrollmentRequest/PendingEnrollmentRequestsBadge.js +22 -0
  123. package/dist/src/components/EnrollmentRequest/PendingEnrollmentRequestsBadge.js.map +1 -0
  124. package/dist/src/components/EnrollmentRequest/useEnrollmentRequests.d.ts +9 -0
  125. package/dist/src/components/EnrollmentRequest/useEnrollmentRequests.d.ts.map +1 -0
  126. package/dist/src/components/EnrollmentRequest/useEnrollmentRequests.js +42 -0
  127. package/dist/src/components/EnrollmentRequest/useEnrollmentRequests.js.map +1 -0
  128. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizard.d.ts +2 -2
  129. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizard.d.ts.map +1 -1
  130. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizard.js +19 -2
  131. package/dist/src/components/Fleet/CreateFleet/CreateFleetWizard.js.map +1 -1
  132. package/dist/src/components/Fleet/CreateFleet/steps/DeviceLabelSelector.d.ts.map +1 -1
  133. package/dist/src/components/Fleet/CreateFleet/steps/DeviceLabelSelector.js +2 -4
  134. package/dist/src/components/Fleet/CreateFleet/steps/DeviceLabelSelector.js.map +1 -1
  135. package/dist/src/components/Fleet/CreateFleet/steps/ReviewStep.d.ts.map +1 -1
  136. package/dist/src/components/Fleet/CreateFleet/steps/ReviewStep.js +6 -1
  137. package/dist/src/components/Fleet/CreateFleet/steps/ReviewStep.js.map +1 -1
  138. package/dist/src/components/Fleet/CreateFleet/utils.d.ts.map +1 -1
  139. package/dist/src/components/Fleet/CreateFleet/utils.js +61 -35
  140. package/dist/src/components/Fleet/CreateFleet/utils.js.map +1 -1
  141. package/dist/src/components/Fleet/FleetDetails/FleetDetails.d.ts +2 -2
  142. package/dist/src/components/Fleet/FleetDetails/FleetDetails.d.ts.map +1 -1
  143. package/dist/src/components/Fleet/FleetDetails/FleetDetails.js +16 -6
  144. package/dist/src/components/Fleet/FleetDetails/FleetDetails.js.map +1 -1
  145. package/dist/src/components/Fleet/FleetDetails/FleetDevices.d.ts.map +1 -1
  146. package/dist/src/components/Fleet/FleetDetails/FleetDevices.js +7 -7
  147. package/dist/src/components/Fleet/FleetDetails/FleetDevices.js.map +1 -1
  148. package/dist/src/components/Fleet/FleetResourceSyncs.d.ts +2 -5
  149. package/dist/src/components/Fleet/FleetResourceSyncs.d.ts.map +1 -1
  150. package/dist/src/components/Fleet/FleetResourceSyncs.js +38 -24
  151. package/dist/src/components/Fleet/FleetResourceSyncs.js.map +1 -1
  152. package/dist/src/components/Fleet/FleetRow.d.ts +2 -0
  153. package/dist/src/components/Fleet/FleetRow.d.ts.map +1 -1
  154. package/dist/src/components/Fleet/FleetRow.js +16 -14
  155. package/dist/src/components/Fleet/FleetRow.js.map +1 -1
  156. package/dist/src/components/Fleet/FleetsPage.d.ts +2 -2
  157. package/dist/src/components/Fleet/FleetsPage.d.ts.map +1 -1
  158. package/dist/src/components/Fleet/FleetsPage.js +37 -33
  159. package/dist/src/components/Fleet/FleetsPage.js.map +1 -1
  160. package/dist/src/components/Fleet/ImportFleetWizard/ImportFleetWizard.d.ts +2 -2
  161. package/dist/src/components/Fleet/ImportFleetWizard/ImportFleetWizard.d.ts.map +1 -1
  162. package/dist/src/components/Fleet/ImportFleetWizard/ImportFleetWizard.js +11 -2
  163. package/dist/src/components/Fleet/ImportFleetWizard/ImportFleetWizard.js.map +1 -1
  164. package/dist/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.d.ts.map +1 -1
  165. package/dist/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js +5 -2
  166. package/dist/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js.map +1 -1
  167. package/dist/src/components/Fleet/useFleets.d.ts +26 -0
  168. package/dist/src/components/Fleet/useFleets.d.ts.map +1 -0
  169. package/dist/src/components/Fleet/useFleets.js +71 -0
  170. package/dist/src/components/Fleet/useFleets.js.map +1 -0
  171. package/dist/src/components/OverviewPage/Cards/Status/StatusCard.d.ts.map +1 -1
  172. package/dist/src/components/OverviewPage/Cards/Status/StatusCard.js +6 -14
  173. package/dist/src/components/OverviewPage/Cards/Status/StatusCard.js.map +1 -1
  174. package/dist/src/components/OverviewPage/Cards/Status/StatusCardFilters.d.ts +0 -3
  175. package/dist/src/components/OverviewPage/Cards/Status/StatusCardFilters.d.ts.map +1 -1
  176. package/dist/src/components/OverviewPage/Cards/Status/StatusCardFilters.js +2 -2
  177. package/dist/src/components/OverviewPage/Cards/Status/StatusCardFilters.js.map +1 -1
  178. package/dist/src/components/OverviewPage/Cards/ToDo/ToDoCard.d.ts.map +1 -1
  179. package/dist/src/components/OverviewPage/Cards/ToDo/ToDoCard.js +5 -9
  180. package/dist/src/components/OverviewPage/Cards/ToDo/ToDoCard.js.map +1 -1
  181. package/dist/src/components/OverviewPage/Overview.d.ts.map +1 -1
  182. package/dist/src/components/OverviewPage/Overview.js +11 -5
  183. package/dist/src/components/OverviewPage/Overview.js.map +1 -1
  184. package/dist/src/components/Repository/CreateRepository/CreateRepository.d.ts +2 -2
  185. package/dist/src/components/Repository/CreateRepository/CreateRepository.d.ts.map +1 -1
  186. package/dist/src/components/Repository/CreateRepository/CreateRepository.js +15 -6
  187. package/dist/src/components/Repository/CreateRepository/CreateRepository.js.map +1 -1
  188. package/dist/src/components/Repository/CreateRepository/CreateRepositoryForm.d.ts.map +1 -1
  189. package/dist/src/components/Repository/CreateRepository/CreateRepositoryForm.js +4 -1
  190. package/dist/src/components/Repository/CreateRepository/CreateRepositoryForm.js.map +1 -1
  191. package/dist/src/components/Repository/CreateRepository/utils.d.ts.map +1 -1
  192. package/dist/src/components/Repository/CreateRepository/utils.js +22 -6
  193. package/dist/src/components/Repository/CreateRepository/utils.js.map +1 -1
  194. package/dist/src/components/Repository/RepositoryDetails/DeleteRepositoryModal.d.ts.map +1 -1
  195. package/dist/src/components/Repository/RepositoryDetails/DeleteRepositoryModal.js +3 -2
  196. package/dist/src/components/Repository/RepositoryDetails/DeleteRepositoryModal.js.map +1 -1
  197. package/dist/src/components/Repository/RepositoryDetails/RepositoryDetails.d.ts +2 -2
  198. package/dist/src/components/Repository/RepositoryDetails/RepositoryDetails.d.ts.map +1 -1
  199. package/dist/src/components/Repository/RepositoryDetails/RepositoryDetails.js +16 -5
  200. package/dist/src/components/Repository/RepositoryDetails/RepositoryDetails.js.map +1 -1
  201. package/dist/src/components/Repository/RepositoryList.d.ts +0 -1
  202. package/dist/src/components/Repository/RepositoryList.d.ts.map +1 -1
  203. package/dist/src/components/Repository/RepositoryList.js +55 -46
  204. package/dist/src/components/Repository/RepositoryList.js.map +1 -1
  205. package/dist/src/components/Repository/useRepositories.d.ts +16 -0
  206. package/dist/src/components/Repository/useRepositories.d.ts.map +1 -0
  207. package/dist/src/components/Repository/useRepositories.js +40 -0
  208. package/dist/src/components/Repository/useRepositories.js.map +1 -0
  209. package/dist/src/components/ResourceSync/RepositoryResourceSyncList.d.ts.map +1 -1
  210. package/dist/src/components/ResourceSync/RepositoryResourceSyncList.js +21 -23
  211. package/dist/src/components/ResourceSync/RepositoryResourceSyncList.js.map +1 -1
  212. package/dist/src/components/Table/Table.d.ts +12 -3
  213. package/dist/src/components/Table/Table.d.ts.map +1 -1
  214. package/dist/src/components/Table/Table.js +4 -4
  215. package/dist/src/components/Table/Table.js.map +1 -1
  216. package/dist/src/components/Table/TablePagination.d.ts +8 -0
  217. package/dist/src/components/Table/TablePagination.d.ts.map +1 -0
  218. package/dist/src/components/Table/TablePagination.js +38 -0
  219. package/dist/src/components/Table/TablePagination.js.map +1 -0
  220. package/dist/src/components/Terminal/Terminal.d.ts.map +1 -1
  221. package/dist/src/components/Terminal/Terminal.js +1 -0
  222. package/dist/src/components/Terminal/Terminal.js.map +1 -1
  223. package/dist/src/components/charts/DonutChart.css +5 -0
  224. package/dist/src/components/charts/DonutChart.js +1 -1
  225. package/dist/src/components/charts/DonutChart.js.map +1 -1
  226. package/dist/src/components/common/AccessDenied.d.ts +4 -0
  227. package/dist/src/components/common/AccessDenied.d.ts.map +1 -0
  228. package/dist/src/components/common/AccessDenied.js +15 -0
  229. package/dist/src/components/common/AccessDenied.js.map +1 -0
  230. package/dist/src/components/common/ButtonWithPermissions.d.ts +8 -0
  231. package/dist/src/components/common/ButtonWithPermissions.d.ts.map +1 -0
  232. package/dist/src/components/common/ButtonWithPermissions.js +12 -0
  233. package/dist/src/components/common/ButtonWithPermissions.js.map +1 -0
  234. package/dist/src/components/common/LearnMoreLink.d.ts +7 -0
  235. package/dist/src/components/common/LearnMoreLink.d.ts.map +1 -0
  236. package/dist/src/components/common/LearnMoreLink.js +13 -0
  237. package/dist/src/components/common/LearnMoreLink.js.map +1 -0
  238. package/dist/src/components/common/LeaveFormConfirmation.js +1 -1
  239. package/dist/src/components/common/LeaveFormConfirmation.js.map +1 -1
  240. package/dist/src/components/common/PageWithPermissions.d.ts +7 -0
  241. package/dist/src/components/common/PageWithPermissions.d.ts.map +1 -0
  242. package/dist/src/components/common/PageWithPermissions.js +17 -0
  243. package/dist/src/components/common/PageWithPermissions.js.map +1 -0
  244. package/dist/src/components/form/FilterSelect.d.ts +2 -4
  245. package/dist/src/components/form/FilterSelect.d.ts.map +1 -1
  246. package/dist/src/components/form/FilterSelect.js.map +1 -1
  247. package/dist/src/components/form/FlightCtlForm.css +3 -0
  248. package/dist/src/components/form/FlightCtlForm.d.ts +1 -0
  249. package/dist/src/components/form/FlightCtlForm.d.ts.map +1 -1
  250. package/dist/src/components/form/FlightCtlForm.js +2 -1
  251. package/dist/src/components/form/FlightCtlForm.js.map +1 -1
  252. package/dist/src/components/form/FormSelect.d.ts +1 -0
  253. package/dist/src/components/form/FormSelect.d.ts.map +1 -1
  254. package/dist/src/components/form/FormSelect.js +14 -2
  255. package/dist/src/components/form/FormSelect.js.map +1 -1
  256. package/dist/src/components/form/LabelsField.d.ts +2 -1
  257. package/dist/src/components/form/LabelsField.d.ts.map +1 -1
  258. package/dist/src/components/form/LabelsField.js +6 -6
  259. package/dist/src/components/form/LabelsField.js.map +1 -1
  260. package/dist/src/components/form/validations.d.ts +13 -2
  261. package/dist/src/components/form/validations.d.ts.map +1 -1
  262. package/dist/src/components/form/validations.js +39 -24
  263. package/dist/src/components/form/validations.js.map +1 -1
  264. package/dist/src/components/modals/ApproveDeviceModal/ApproveDeviceModal.d.ts.map +1 -1
  265. package/dist/src/components/modals/ApproveDeviceModal/ApproveDeviceModal.js +2 -5
  266. package/dist/src/components/modals/ApproveDeviceModal/ApproveDeviceModal.js.map +1 -1
  267. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.d.ts +2 -1
  268. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.d.ts.map +1 -1
  269. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.js +4 -4
  270. package/dist/src/components/modals/EditLabelsModal/EditLabelsForm.js.map +1 -1
  271. package/dist/src/components/modals/massModals/MassApproveDeviceModal/MassApproveDeviceModal.d.ts.map +1 -1
  272. package/dist/src/components/modals/massModals/MassApproveDeviceModal/MassApproveDeviceModal.js +2 -3
  273. package/dist/src/components/modals/massModals/MassApproveDeviceModal/MassApproveDeviceModal.js.map +1 -1
  274. package/dist/src/components/modals/massModals/MassDeleteRepositoryModal/MassDeleteRepositoryModal.d.ts +1 -1
  275. package/dist/src/components/modals/massModals/MassDeleteRepositoryModal/MassDeleteRepositoryModal.d.ts.map +1 -1
  276. package/dist/src/components/modals/massModals/MassDeleteRepositoryModal/MassDeleteRepositoryModal.js +6 -5
  277. package/dist/src/components/modals/massModals/MassDeleteRepositoryModal/MassDeleteRepositoryModal.js.map +1 -1
  278. package/dist/src/constants.d.ts +2 -1
  279. package/dist/src/constants.d.ts.map +1 -1
  280. package/dist/src/constants.js +3 -1
  281. package/dist/src/constants.js.map +1 -1
  282. package/dist/src/hooks/useAccessReview.d.ts +4 -0
  283. package/dist/src/hooks/useAccessReview.d.ts.map +1 -0
  284. package/dist/src/hooks/useAccessReview.js +33 -0
  285. package/dist/src/hooks/useAccessReview.js.map +1 -0
  286. package/dist/src/hooks/useAppContext.d.ts +8 -7
  287. package/dist/src/hooks/useAppContext.d.ts.map +1 -1
  288. package/dist/src/hooks/useAppContext.js +2 -2
  289. package/dist/src/hooks/useAppContext.js.map +1 -1
  290. package/dist/src/hooks/useFetch.d.ts +4 -2
  291. package/dist/src/hooks/useFetch.d.ts.map +1 -1
  292. package/dist/src/hooks/useFetchPeriodically.d.ts +1 -1
  293. package/dist/src/hooks/useFetchPeriodically.d.ts.map +1 -1
  294. package/dist/src/hooks/useFetchPeriodically.js +4 -1
  295. package/dist/src/hooks/useFetchPeriodically.js.map +1 -1
  296. package/dist/src/hooks/useFleetImportAccessReview.d.ts +3 -0
  297. package/dist/src/hooks/useFleetImportAccessReview.d.ts.map +1 -0
  298. package/dist/src/hooks/useFleetImportAccessReview.js +12 -0
  299. package/dist/src/hooks/useFleetImportAccessReview.js.map +1 -0
  300. package/dist/src/hooks/useNavigate.d.ts +3 -3
  301. package/dist/src/hooks/useNavigate.d.ts.map +1 -1
  302. package/dist/src/hooks/useNavigate.js +3 -3
  303. package/dist/src/hooks/useNavigate.js.map +1 -1
  304. package/dist/src/hooks/usePendingEnrollmentRequestsCount.d.ts +2 -0
  305. package/dist/src/hooks/usePendingEnrollmentRequestsCount.d.ts.map +1 -0
  306. package/dist/src/hooks/usePendingEnrollmentRequestsCount.js +13 -0
  307. package/dist/src/hooks/usePendingEnrollmentRequestsCount.js.map +1 -0
  308. package/dist/src/hooks/useTablePagination.d.ts +10 -0
  309. package/dist/src/hooks/useTablePagination.d.ts.map +1 -0
  310. package/dist/src/hooks/useTablePagination.js +33 -0
  311. package/dist/src/hooks/useTablePagination.js.map +1 -0
  312. package/dist/src/hooks/useWebSocket.d.ts +2 -2
  313. package/dist/src/hooks/useWebSocket.d.ts.map +1 -1
  314. package/dist/src/hooks/useWebSocket.js.map +1 -1
  315. package/dist/src/links.d.ts +3 -0
  316. package/dist/src/links.d.ts.map +1 -0
  317. package/dist/src/links.js +6 -0
  318. package/dist/src/links.js.map +1 -0
  319. package/dist/src/types/rbac.d.ts +18 -0
  320. package/dist/src/types/rbac.d.ts.map +1 -0
  321. package/dist/src/types/rbac.js +23 -0
  322. package/dist/src/types/rbac.js.map +1 -0
  323. package/dist/src/utils/api.d.ts +3 -3
  324. package/dist/src/utils/api.d.ts.map +1 -1
  325. package/dist/src/utils/api.js.map +1 -1
  326. package/dist/src/utils/labels.d.ts +1 -1
  327. package/dist/src/utils/labels.d.ts.map +1 -1
  328. package/dist/src/utils/labels.js +4 -8
  329. package/dist/src/utils/labels.js.map +1 -1
  330. package/dist/src/utils/query.d.ts +15 -0
  331. package/dist/src/utils/query.d.ts.map +1 -0
  332. package/dist/src/utils/query.js +64 -0
  333. package/dist/src/utils/query.js.map +1 -0
  334. package/dist/src/utils/search.d.ts +1 -0
  335. package/dist/src/utils/search.d.ts.map +1 -1
  336. package/dist/src/utils/search.js +7 -7
  337. package/dist/src/utils/search.js.map +1 -1
  338. package/dist/src/utils/status/devices.d.ts +2 -1
  339. package/dist/src/utils/status/devices.d.ts.map +1 -1
  340. package/dist/src/utils/status/devices.js +1 -0
  341. package/dist/src/utils/status/devices.js.map +1 -1
  342. package/package.json +10 -10
  343. package/src/components/DetailsPage/Tables/ApplicationsTable.css +7 -0
  344. package/src/components/DetailsPage/Tables/ApplicationsTable.tsx +150 -13
  345. package/src/components/Device/AddDeviceModal/AddDeviceModal.tsx +31 -132
  346. package/src/components/Device/DeviceDetails/DeviceApplications.tsx +102 -0
  347. package/src/components/Device/DeviceDetails/DeviceDetailsPage.tsx +33 -16
  348. package/src/components/Device/DeviceDetails/DeviceDetailsTab.tsx +8 -38
  349. package/src/components/Device/DeviceDetails/TerminalTab.tsx +21 -4
  350. package/src/components/Device/DevicesPage/DeviceFilterSelect.tsx +13 -34
  351. package/src/components/Device/DevicesPage/DeviceTableRow.tsx +21 -9
  352. package/src/components/Device/DevicesPage/DeviceTableToolbar.tsx +13 -20
  353. package/src/components/Device/DevicesPage/DeviceToolbarFilters.tsx +128 -48
  354. package/src/components/Device/DevicesPage/DevicesPage.tsx +86 -66
  355. package/src/components/Device/DevicesPage/types.ts +1 -13
  356. package/src/components/Device/DevicesPage/useDeviceBackendFilters.ts +14 -3
  357. package/src/components/Device/DevicesPage/useDevices.ts +49 -57
  358. package/src/components/Device/EditDeviceWizard/EditDeviceWizard.tsx +24 -4
  359. package/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts +156 -47
  360. package/src/components/Device/EditDeviceWizard/steps/{ApplicationsForm.tsx → ApplicationTemplates.tsx} +89 -53
  361. package/src/components/Device/EditDeviceWizard/steps/ConfigInlineTemplateForm.tsx +22 -26
  362. package/src/components/Device/EditDeviceWizard/steps/ConfigWithRepositoryTemplateForm.tsx +17 -12
  363. package/src/components/Device/EditDeviceWizard/steps/{ConfigTemplateForm.tsx → ConfigurationTemplates.tsx} +110 -52
  364. package/src/components/Device/EditDeviceWizard/steps/DeviceTemplateStep.tsx +108 -11
  365. package/src/components/Device/EditDeviceWizard/steps/ReviewTrackedSystemdServices.tsx +19 -0
  366. package/src/components/Device/EditDeviceWizard/steps/SystemdUnitsForm.tsx +75 -0
  367. package/src/components/Device/EditDeviceWizard/types.ts +3 -0
  368. package/src/components/Device/EditDeviceWizard/utils.ts +14 -4
  369. package/src/components/Device/{MatchPatternsModal/MatchPatternsModal.tsx → SystemdUnitsModal/SystemdUnitsModal.tsx} +36 -19
  370. package/src/components/Device/SystemdUnitsModal/TrackSystemdUnitsForm.tsx +114 -0
  371. package/src/components/EnrollmentRequest/EnrollmentRequestDetails/EnrollmentRequestDetails.tsx +28 -9
  372. package/src/components/EnrollmentRequest/EnrollmentRequestList.tsx +167 -0
  373. package/src/components/EnrollmentRequest/EnrollmentRequestTableRow.tsx +28 -17
  374. package/src/components/{Device/DevicesPage → EnrollmentRequest}/EnrollmentRequestTableToolbar.tsx +3 -2
  375. package/src/components/EnrollmentRequest/PendingEnrollmentRequestsBadge.css +10 -0
  376. package/src/components/EnrollmentRequest/PendingEnrollmentRequestsBadge.tsx +27 -0
  377. package/src/components/EnrollmentRequest/useEnrollmentRequests.ts +63 -0
  378. package/src/components/Fleet/CreateFleet/CreateFleetWizard.tsx +28 -2
  379. package/src/components/Fleet/CreateFleet/steps/DeviceLabelSelector.tsx +2 -5
  380. package/src/components/Fleet/CreateFleet/steps/ReviewStep.tsx +7 -0
  381. package/src/components/Fleet/CreateFleet/utils.ts +101 -49
  382. package/src/components/Fleet/FleetDetails/FleetDetails.tsx +57 -36
  383. package/src/components/Fleet/FleetDetails/FleetDevices.tsx +12 -18
  384. package/src/components/Fleet/FleetResourceSyncs.tsx +53 -41
  385. package/src/components/Fleet/FleetRow.tsx +28 -16
  386. package/src/components/Fleet/FleetsPage.tsx +70 -49
  387. package/src/components/Fleet/ImportFleetWizard/ImportFleetWizard.tsx +16 -3
  388. package/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.tsx +25 -19
  389. package/src/components/Fleet/useFleets.ts +104 -0
  390. package/src/components/OverviewPage/Cards/Status/StatusCard.tsx +6 -18
  391. package/src/components/OverviewPage/Cards/Status/StatusCardFilters.tsx +0 -7
  392. package/src/components/OverviewPage/Cards/ToDo/ToDoCard.tsx +6 -10
  393. package/src/components/OverviewPage/Overview.tsx +20 -8
  394. package/src/components/Repository/CreateRepository/CreateRepository.tsx +25 -9
  395. package/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx +5 -2
  396. package/src/components/Repository/CreateRepository/utils.ts +23 -7
  397. package/src/components/Repository/RepositoryDetails/DeleteRepositoryModal.tsx +5 -3
  398. package/src/components/Repository/RepositoryDetails/RepositoryDetails.tsx +32 -10
  399. package/src/components/Repository/RepositoryList.tsx +113 -70
  400. package/src/components/Repository/useRepositories.ts +59 -0
  401. package/src/components/ResourceSync/RepositoryResourceSyncList.tsx +42 -40
  402. package/src/components/Table/Table.tsx +22 -9
  403. package/src/components/Table/TablePagination.tsx +74 -0
  404. package/src/components/Terminal/Terminal.tsx +1 -0
  405. package/src/components/charts/DonutChart.css +5 -0
  406. package/src/components/charts/DonutChart.tsx +1 -1
  407. package/src/components/common/AccessDenied.tsx +17 -0
  408. package/src/components/common/ButtonWithPermissions.tsx +14 -0
  409. package/src/components/common/LearnMoreLink.tsx +26 -0
  410. package/src/components/common/PageWithPermissions.tsx +19 -0
  411. package/src/components/form/FilterSelect.tsx +2 -4
  412. package/src/components/form/FlightCtlForm.css +3 -0
  413. package/src/components/form/FlightCtlForm.tsx +3 -1
  414. package/src/components/form/FormSelect.tsx +22 -2
  415. package/src/components/form/LabelsField.tsx +17 -13
  416. package/src/components/form/validations.ts +53 -25
  417. package/src/components/modals/ApproveDeviceModal/ApproveDeviceModal.tsx +2 -5
  418. package/src/components/modals/EditLabelsModal/EditLabelsForm.tsx +9 -4
  419. package/src/components/modals/massModals/MassApproveDeviceModal/MassApproveDeviceModal.tsx +2 -4
  420. package/src/components/modals/massModals/MassDeleteRepositoryModal/MassDeleteRepositoryModal.tsx +10 -5
  421. package/src/constants.ts +2 -1
  422. package/src/hooks/useAccessReview.ts +33 -0
  423. package/src/hooks/useAppContext.tsx +6 -5
  424. package/src/hooks/useFetchPeriodically.ts +4 -0
  425. package/src/hooks/useFleetImportAccessReview.ts +8 -0
  426. package/src/hooks/useNavigate.tsx +3 -3
  427. package/src/hooks/usePendingEnrollmentRequestsCount.ts +12 -0
  428. package/src/hooks/useTablePagination.tsx +44 -0
  429. package/src/hooks/useWebSocket.ts +4 -4
  430. package/src/links.ts +5 -0
  431. package/src/types/rbac.ts +18 -0
  432. package/src/utils/api.ts +3 -3
  433. package/src/utils/labels.ts +3 -7
  434. package/src/utils/query.ts +70 -0
  435. package/src/utils/search.ts +1 -1
  436. package/src/utils/status/devices.ts +1 -0
  437. package/dist/src/components/DetailsPage/Tables/SystemdDetailsTable.d.ts +0 -12
  438. package/dist/src/components/DetailsPage/Tables/SystemdDetailsTable.d.ts.map +0 -1
  439. package/dist/src/components/DetailsPage/Tables/SystemdDetailsTable.js +0 -40
  440. package/dist/src/components/DetailsPage/Tables/SystemdDetailsTable.js.map +0 -1
  441. package/dist/src/components/Device/DeviceDetails/SystemdTable.d.ts +0 -10
  442. package/dist/src/components/Device/DeviceDetails/SystemdTable.d.ts.map +0 -1
  443. package/dist/src/components/Device/DeviceDetails/SystemdTable.js +0 -38
  444. package/dist/src/components/Device/DeviceDetails/SystemdTable.js.map +0 -1
  445. package/dist/src/components/Device/DevicesPage/EnrollmentRequestList.d.ts +0 -13
  446. package/dist/src/components/Device/DevicesPage/EnrollmentRequestList.d.ts.map +0 -1
  447. package/dist/src/components/Device/DevicesPage/EnrollmentRequestList.js +0 -104
  448. package/dist/src/components/Device/DevicesPage/EnrollmentRequestList.js.map +0 -1
  449. package/dist/src/components/Device/DevicesPage/EnrollmentRequestTableToolbar.d.ts.map +0 -1
  450. package/dist/src/components/Device/DevicesPage/EnrollmentRequestTableToolbar.js.map +0 -1
  451. package/dist/src/components/Device/DevicesPage/useDeviceFilters.d.ts +0 -8
  452. package/dist/src/components/Device/DevicesPage/useDeviceFilters.d.ts.map +0 -1
  453. package/dist/src/components/Device/DevicesPage/useDeviceFilters.js +0 -16
  454. package/dist/src/components/Device/DevicesPage/useDeviceFilters.js.map +0 -1
  455. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationsForm.d.ts +0 -5
  456. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationsForm.d.ts.map +0 -1
  457. package/dist/src/components/Device/EditDeviceWizard/steps/ApplicationsForm.js.map +0 -1
  458. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigTemplateForm.d.ts +0 -4
  459. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigTemplateForm.d.ts.map +0 -1
  460. package/dist/src/components/Device/EditDeviceWizard/steps/ConfigTemplateForm.js.map +0 -1
  461. package/dist/src/components/Device/MatchPatternsModal/MatchPatternsForm.d.ts +0 -11
  462. package/dist/src/components/Device/MatchPatternsModal/MatchPatternsForm.d.ts.map +0 -1
  463. package/dist/src/components/Device/MatchPatternsModal/MatchPatternsForm.js +0 -39
  464. package/dist/src/components/Device/MatchPatternsModal/MatchPatternsForm.js.map +0 -1
  465. package/dist/src/components/Device/MatchPatternsModal/MatchPatternsModal.d.ts.map +0 -1
  466. package/dist/src/components/Device/MatchPatternsModal/MatchPatternsModal.js.map +0 -1
  467. package/dist/src/components/common/HelperTextItems.d.ts +0 -3
  468. package/dist/src/components/common/HelperTextItems.d.ts.map +0 -1
  469. package/dist/src/components/common/HelperTextItems.js +0 -17
  470. package/dist/src/components/common/HelperTextItems.js.map +0 -1
  471. package/dist/src/hooks/useTableSort.d.ts +0 -7
  472. package/dist/src/hooks/useTableSort.d.ts.map +0 -1
  473. package/dist/src/hooks/useTableSort.js +0 -38
  474. package/dist/src/hooks/useTableSort.js.map +0 -1
  475. package/dist/src/utils/sort/device.d.ts +0 -4
  476. package/dist/src/utils/sort/device.d.ts.map +0 -1
  477. package/dist/src/utils/sort/device.js +0 -49
  478. package/dist/src/utils/sort/device.js.map +0 -1
  479. package/dist/src/utils/sort/fleet.d.ts +0 -4
  480. package/dist/src/utils/sort/fleet.d.ts.map +0 -1
  481. package/dist/src/utils/sort/fleet.js +0 -18
  482. package/dist/src/utils/sort/fleet.js.map +0 -1
  483. package/dist/src/utils/sort/generic.d.ts +0 -8
  484. package/dist/src/utils/sort/generic.d.ts.map +0 -1
  485. package/dist/src/utils/sort/generic.js +0 -37
  486. package/dist/src/utils/sort/generic.js.map +0 -1
  487. package/dist/src/utils/sort/repository.d.ts +0 -6
  488. package/dist/src/utils/sort/repository.d.ts.map +0 -1
  489. package/dist/src/utils/sort/repository.js +0 -28
  490. package/dist/src/utils/sort/repository.js.map +0 -1
  491. package/dist/src/utils/sort/resourceSync.d.ts +0 -6
  492. package/dist/src/utils/sort/resourceSync.d.ts.map +0 -1
  493. package/dist/src/utils/sort/resourceSync.js +0 -29
  494. package/dist/src/utils/sort/resourceSync.js.map +0 -1
  495. package/src/components/DetailsPage/Tables/SystemdDetailsTable.tsx +0 -63
  496. package/src/components/Device/DeviceDetails/SystemdTable.tsx +0 -65
  497. package/src/components/Device/DevicesPage/EnrollmentRequestList.tsx +0 -183
  498. package/src/components/Device/DevicesPage/useDeviceFilters.ts +0 -15
  499. package/src/components/Device/MatchPatternsModal/MatchPatternsForm.tsx +0 -92
  500. package/src/components/common/HelperTextItems.tsx +0 -25
  501. package/src/hooks/useTableSort.ts +0 -42
  502. package/src/utils/sort/device.ts +0 -60
  503. package/src/utils/sort/fleet.ts +0 -16
  504. package/src/utils/sort/generic.ts +0 -37
  505. package/src/utils/sort/repository.ts +0 -28
  506. package/src/utils/sort/resourceSync.ts +0 -30
@@ -16,6 +16,7 @@ import {
16
16
  } from '../../types/deviceSpec';
17
17
  import { labelToString } from '../../utils/labels';
18
18
  import { ApplicationFormSpec } from '../Device/EditDeviceWizard/types';
19
+ import { SystemdUnitFormValue } from '../Device/SystemdUnitsModal/TrackSystemdUnitsForm';
19
20
 
20
21
  type UnvalidatedLabel = Partial<FlightCtlLabel>;
21
22
 
@@ -32,6 +33,10 @@ const K8S_DNS_SUBDOMAIN_START_END = /^[a-z0-9](.*[a-z0-9])?$/;
32
33
  const K8S_DNS_SUBDOMAIN_ALLOWED_CHARACTERS = /^[a-z0-9.-]*$/;
33
34
  const K8S_DNS_SUBDOMAIN_VALUE_MAX_LENGTH = 253;
34
35
 
36
+ // https://issues.redhat.com/browse/MGMT-18349 to make the validation more robust
37
+ const BASIC_DEVICE_OS_IMAGE_REGEXP = /^[a-zA-Z0-9.\-\/:@_+]*$/;
38
+ const BASIC_FLEET_OS_IMAGE_REGEXP = /^[a-zA-Z0-9.\-\/:@_+{}\s]*$/;
39
+
35
40
  const absolutePathRegex = /^\/.*$/;
36
41
  export const MAX_TARGET_REVISION_LENGTH = 244;
37
42
 
@@ -185,6 +190,14 @@ export const validKubernetesLabelValue = (
185
190
  export const maxLengthString = (t: TFunction, props: { maxLength: number; fieldName: string }) =>
186
191
  Yup.string().max(props.maxLength, t('{{ fieldName }} must not exceed {{ maxLength }} characters', props));
187
192
 
193
+ export const validOsImage = (t: TFunction, { isFleet }: { isFleet: boolean }) =>
194
+ maxLengthString(t, { fieldName: t('System image'), maxLength: 2048 }).matches(
195
+ isFleet ? BASIC_FLEET_OS_IMAGE_REGEXP : BASIC_DEVICE_OS_IMAGE_REGEXP,
196
+ isFleet
197
+ ? t('System image contains invalid characters')
198
+ : t('System image contains invalid characters. Template variables are not allowed.'),
199
+ );
200
+
188
201
  export const validLabelsSchema = (t: TFunction) =>
189
202
  Yup.array()
190
203
  .of(
@@ -302,6 +315,7 @@ export const validConfigTemplatesSchema = (t: TFunction) =>
302
315
  } else if (isHttpConfigTemplate(value)) {
303
316
  return Yup.object<HttpConfigTemplate>().shape({
304
317
  type: Yup.string().required(t('Source type is required.')),
318
+ repository: Yup.string().required(t('Repository is required.')),
305
319
  name: validKubernetesDnsSubdomain(t, { isRequired: true }),
306
320
  filePath: Yup.string()
307
321
  .required(t('File path is required.'))
@@ -332,7 +346,7 @@ export const validConfigTemplatesSchema = (t: TFunction) =>
332
346
  t('File path must be unique.'),
333
347
  (path) => !path || value.files.filter((file) => file.path === path).length == 1,
334
348
  ),
335
- content: Yup.string().required(t('File content is required.')),
349
+ content: Yup.string(),
336
350
  }),
337
351
  ),
338
352
  });
@@ -345,33 +359,47 @@ export const validConfigTemplatesSchema = (t: TFunction) =>
345
359
  }),
346
360
  );
347
361
 
348
- export const deviceSystemdUnitsValidationSchema = (t: TFunction) =>
349
- Yup.object({
350
- matchPatterns: Yup.array()
351
- .max(
352
- SYSTEMD_UNITS_MAX_PATTERNS,
353
- t('The maximum number of systemd units is {{maxSystemUnits}}.', { maxSystemUnits: SYSTEMD_UNITS_MAX_PATTERNS }),
354
- )
355
- .of(Yup.string().required('Unit name is required.'))
356
- .test('invalid patterns', (patterns: string[] | undefined, testContext) => {
357
- // TODO analyze https://github.com/systemd/systemd/blob/9cebda59e818cdb89dc1e53ab5bb51b91b3dc3ff/src/basic/unit-name.c#L42
358
- // and adjust the regular expression and / or the validation to accommodate for it
359
- const invalidPatterns = (patterns || []).filter((pattern) => {
362
+ export const systemdUnitListValidationSchema = (t: TFunction) =>
363
+ Yup.array()
364
+ .max(
365
+ SYSTEMD_UNITS_MAX_PATTERNS,
366
+ t('The maximum number of systemd units is {{maxSystemUnits}}.', { maxSystemUnits: SYSTEMD_UNITS_MAX_PATTERNS }),
367
+ )
368
+ .of(
369
+ Yup.object<SystemdUnitFormValue>().shape({
370
+ pattern: Yup.string().required('Service name is required'),
371
+ exists: Yup.boolean().required(),
372
+ }),
373
+ )
374
+ .test('invalid patterns', (systemdUnits: SystemdUnitFormValue[] | undefined, testContext) => {
375
+ // TODO analyze https://github.com/systemd/systemd/blob/9cebda59e818cdb89dc1e53ab5bb51b91b3dc3ff/src/basic/unit-name.c#L42
376
+ // and adjust the regular expression and / or the validation to accommodate for it
377
+ const invalidSystemdUnits = (systemdUnits || [])
378
+ .map((unit) => unit.pattern)
379
+ .filter((pattern) => {
360
380
  return pattern.length > SYSTEMD_UNITS_MAX_PATTERNS || !SYSTEMD_PATTERNS_REGEXP.test(pattern);
361
381
  });
362
- if (invalidPatterns.length === 0) {
363
- return true;
364
- }
365
- return testContext.createError({
366
- message: t('Invalid systemd unit names: {{invalidPatterns}}', {
367
- invalidPatterns: invalidPatterns.join(', '),
368
- }),
369
- });
370
- })
371
- .test('unique patterns', t('Systemd unit names must be unique'), (patterns: string[] | undefined) => {
372
- const uniqueKeys = new Set(patterns || []);
382
+ if (invalidSystemdUnits.length === 0) {
383
+ return true;
384
+ }
385
+ return testContext.createError({
386
+ message: t('Invalid systemd service names: {{invalidPatterns}}', {
387
+ invalidPatterns: invalidSystemdUnits.join(', '),
388
+ }),
389
+ });
390
+ })
391
+ .test(
392
+ 'unique patterns',
393
+ t('Systemd service names must be unique'),
394
+ (patterns: SystemdUnitFormValue[] | undefined) => {
395
+ const uniqueKeys = new Set(patterns?.map((p) => p.pattern) || []);
373
396
  return uniqueKeys.size === (patterns?.length || 0);
374
- }),
397
+ },
398
+ );
399
+
400
+ export const deviceSystemdUnitsValidationSchema = (t: TFunction) =>
401
+ Yup.object({
402
+ systemdUnits: systemdUnitListValidationSchema(t),
375
403
  });
376
404
 
377
405
  export const deviceApprovalValidationSchema = (t: TFunction, conf: { isSingleDevice: boolean }) =>
@@ -14,15 +14,13 @@ import { useTranslation } from '../../../hooks/useTranslation';
14
14
  import { deviceApprovalValidationSchema } from '../../form/validations';
15
15
 
16
16
  import { fromAPILabel, toAPILabel } from '../../../utils/labels';
17
- import { useAppContext } from '../../../hooks/useAppContext';
18
17
 
19
18
  type DeviceEnrollmentModalProps = Omit<ApproveDeviceFormProps, 'error'>;
20
19
 
21
20
  const DeviceEnrollmentModal: React.FC<DeviceEnrollmentModalProps> = ({ enrollmentRequest, onClose }) => {
22
21
  const { t } = useTranslation();
23
- const { post } = useFetch();
22
+ const { put } = useFetch();
24
23
  const [error, setError] = React.useState<string>();
25
- const { user } = useAppContext();
26
24
  return (
27
25
  <Formik<ApproveDeviceFormValues>
28
26
  initialValues={{
@@ -38,10 +36,9 @@ const DeviceEnrollmentModal: React.FC<DeviceEnrollmentModalProps> = ({ enrollmen
38
36
  }
39
37
 
40
38
  try {
41
- await post<EnrollmentRequestApproval>(`enrollmentrequests/${enrollmentRequest.metadata.name}/approval`, {
39
+ await put<EnrollmentRequestApproval>(`enrollmentrequests/${enrollmentRequest.metadata.name}/approval`, {
42
40
  approved: true,
43
41
  labels: deviceLabels,
44
- approvedBy: user,
45
42
  });
46
43
  onClose(true);
47
44
  } catch (e) {
@@ -23,6 +23,7 @@ type EditLabelsFormValues = {
23
23
  type EditLabelsFormContentProps = {
24
24
  isSubmitting: FormikProps<EditLabelsFormValues>['isSubmitting'];
25
25
  submitForm: (values: EditLabelsFormValues) => Promise<string>;
26
+ canEdit: boolean;
26
27
  };
27
28
 
28
29
  const getValidationSchema = (t: TFunction) => {
@@ -33,7 +34,7 @@ const getValidationSchema = (t: TFunction) => {
33
34
 
34
35
  const delayResponse = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
35
36
 
36
- const EditLabelsFormContent = ({ isSubmitting, submitForm }: EditLabelsFormContentProps) => {
37
+ const EditLabelsFormContent = ({ isSubmitting, submitForm, canEdit }: EditLabelsFormContentProps) => {
37
38
  const { t } = useTranslation();
38
39
  const [submitError, setSubmitError] = React.useState<string>();
39
40
 
@@ -53,8 +54,9 @@ const EditLabelsFormContent = ({ isSubmitting, submitForm }: EditLabelsFormConte
53
54
  <LabelsField
54
55
  name="labels"
55
56
  addButtonText={isSubmitting ? t('Saving...') : undefined}
56
- isFormEditable={!isSubmitting}
57
+ isLoading={isSubmitting}
57
58
  onChangeCallback={debouncedSubmit}
59
+ canEdit={canEdit}
58
60
  />
59
61
  {submitError && <Alert isInline title={submitError} variant="danger" />}
60
62
  </FlightCtlForm>
@@ -64,9 +66,10 @@ const EditLabelsFormContent = ({ isSubmitting, submitForm }: EditLabelsFormConte
64
66
  type EditLabelsFormProps = {
65
67
  device: Device;
66
68
  onDeviceUpdate: () => void;
69
+ canEdit: boolean;
67
70
  };
68
71
 
69
- const EditLabelsForm = ({ device, onDeviceUpdate }: EditLabelsFormProps) => {
72
+ const EditLabelsForm = ({ device, onDeviceUpdate, canEdit }: EditLabelsFormProps) => {
70
73
  const { t } = useTranslation();
71
74
  const { patch } = useFetch();
72
75
 
@@ -93,7 +96,9 @@ const EditLabelsForm = ({ device, onDeviceUpdate }: EditLabelsFormProps) => {
93
96
  }}
94
97
  validationSchema={getValidationSchema(t)}
95
98
  >
96
- {({ isSubmitting, submitForm }) => <EditLabelsFormContent isSubmitting={isSubmitting} submitForm={submitForm} />}
99
+ {({ isSubmitting, submitForm }) => (
100
+ <EditLabelsFormContent canEdit={canEdit} isSubmitting={isSubmitting} submitForm={submitForm} />
101
+ )}
97
102
  </Formik>
98
103
  );
99
104
  };
@@ -49,8 +49,7 @@ const MassApproveDeviceModal: React.FC<MassApproveDeviceModalProps> = ({
49
49
  const [totalProgress, setTotalProgress] = React.useState(0);
50
50
  const [errors, setErrors] = React.useState<string[]>();
51
51
  const {
52
- user,
53
- fetch: { post },
52
+ fetch: { put },
54
53
  } = useAppContext();
55
54
 
56
55
  const approveEnrollments = async (values: MassApproveDeviceFormValues) => {
@@ -63,10 +62,9 @@ const MassApproveDeviceModal: React.FC<MassApproveDeviceModalProps> = ({
63
62
  labels.alias = aliasLabel;
64
63
  }
65
64
 
66
- await post<EnrollmentRequestApproval>(`enrollmentrequests/${r.metadata.name}/approval`, {
65
+ await put<EnrollmentRequestApproval>(`enrollmentrequests/${r.metadata.name}/approval`, {
67
66
  approved: true,
68
67
  labels,
69
- approvedBy: user,
70
68
  });
71
69
  setProgress((p) => p + 1);
72
70
  });
@@ -1,12 +1,15 @@
1
- import { useFetch } from '../../../../hooks/useFetch';
2
- import { getErrorMessage } from '../../../../utils/error';
1
+ import * as React from 'react';
3
2
  import { Alert, Button, Modal, Progress, ProgressMeasureLocation, Stack, StackItem } from '@patternfly/react-core';
4
3
  import { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table';
4
+
5
5
  import { Repository, ResourceSyncList } from '@flightctl/types';
6
- import * as React from 'react';
6
+
7
+ import { useFetch } from '../../../../hooks/useFetch';
8
+ import { getErrorMessage } from '../../../../utils/error';
7
9
  import { useTranslation } from '../../../../hooks/useTranslation';
8
10
  import { isPromiseRejected } from '../../../../types/typeUtils';
9
11
  import { getApiListCount } from '../../../../utils/api';
12
+ import { commonQueries } from '../../../../utils/query';
10
13
 
11
14
  type MassDeleteRepositoryModalProps = {
12
15
  onClose: VoidFunction;
@@ -37,7 +40,9 @@ const MassDeleteRepositoryModal: React.FC<MassDeleteRepositoryModalProps> = ({
37
40
  const rsCount = {};
38
41
  const promises = repositories.map(async (r) => {
39
42
  const repositoryId = r.metadata.name || '';
40
- const resourceSyncs = await get<ResourceSyncList>(`resourcesyncs?repository=${repositoryId}&limit=1`);
43
+ const resourceSyncs = await get<ResourceSyncList>(
44
+ commonQueries.getResourceSyncsByRepo(repositoryId, { limit: 1 }),
45
+ );
41
46
  rsCount[repositoryId] = getApiListCount(resourceSyncs);
42
47
  });
43
48
  await Promise.allSettled(promises);
@@ -51,7 +56,7 @@ const MassDeleteRepositoryModal: React.FC<MassDeleteRepositoryModalProps> = ({
51
56
  setProgress(0);
52
57
  const promises = repositories.map(async (r) => {
53
58
  const repositoryId = r.metadata.name || '';
54
- const resourceSyncs = await get<ResourceSyncList>(`resourcesyncs?repository=${repositoryId}`);
59
+ const resourceSyncs = await get<ResourceSyncList>(commonQueries.getResourceSyncsByRepo(repositoryId));
55
60
  const rsyncPromises = resourceSyncs.items.map((rsync) => remove(`resourcesyncs/${rsync.metadata.name}`));
56
61
  const rsyncResults = await Promise.allSettled(rsyncPromises);
57
62
  const rejectedResults = rsyncResults.filter(isPromiseRejected);
package/src/constants.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  const APP_TITLE = 'Device management service';
2
2
  const API_VERSION = 'v1alpha1';
3
+ const PAGE_SIZE = 15;
3
4
 
4
- export { APP_TITLE, API_VERSION };
5
+ export { APP_TITLE, API_VERSION, PAGE_SIZE };
@@ -0,0 +1,33 @@
1
+ import * as React from 'react';
2
+ import { useAppContext } from './useAppContext';
3
+ import { getErrorMessage } from '../utils/error';
4
+ import { RESOURCE, VERB } from '../types/rbac';
5
+
6
+ export type AccessReviewResult = [boolean, boolean, string | undefined];
7
+
8
+ export const useAccessReview = (kind: RESOURCE, verb: VERB): AccessReviewResult => {
9
+ const [isLoading, setIsLoading] = React.useState(true);
10
+ const [error, setError] = React.useState<string>();
11
+ const [isAllowed, setIsAllowed] = React.useState(false);
12
+
13
+ const {
14
+ fetch: { checkPermissions },
15
+ } = useAppContext();
16
+ React.useEffect(() => {
17
+ const doItAsync = async () => {
18
+ setIsLoading(true);
19
+ try {
20
+ const allowed = await checkPermissions(kind, verb);
21
+ setIsAllowed(allowed);
22
+ } catch (err) {
23
+ setError(getErrorMessage(err));
24
+ setIsAllowed(false);
25
+ } finally {
26
+ setIsLoading(false);
27
+ }
28
+ };
29
+ doItAsync();
30
+ }, [kind, verb, checkPermissions]);
31
+
32
+ return [isAllowed, isLoading, error];
33
+ };
@@ -12,8 +12,9 @@ import {
12
12
  useParams,
13
13
  useSearchParams,
14
14
  } from 'react-router-dom';
15
- import { ROUTE } from './useNavigate';
16
15
  import { PatchRequest } from '@flightctl/types';
16
+ import { ROUTE } from './useNavigate';
17
+ import { RESOURCE, VERB } from '../types/rbac';
17
18
 
18
19
  export const appRoutes = {
19
20
  [ROUTE.ROOT]: '/',
@@ -39,8 +40,6 @@ export type PromptFC = React.FC<{ message: string }>;
39
40
 
40
41
  export type AppContextProps = {
41
42
  appType: 'standalone' | 'ocp' | 'aap';
42
- qcow2ImgUrl: string | undefined;
43
- bootcImgUrl: string | undefined;
44
43
  user?: string; // auth?.user?.profile.preferred_username
45
44
  i18n: {
46
45
  transNamespace?: string;
@@ -63,8 +62,10 @@ export type AppContextProps = {
63
62
  getWsEndpoint: () => { wsEndpoint: string; protocols: string[] };
64
63
  get: <R>(kind: string, abortSignal?: AbortSignal) => Promise<R>;
65
64
  post: <R>(kind: string, data: R, abortSignal?: AbortSignal) => Promise<R>;
65
+ put: <R>(kind: string, data: R, abortSignal?: AbortSignal) => Promise<R>;
66
66
  remove: <R>(kind: string, abortSignal?: AbortSignal) => Promise<R>;
67
67
  patch: <R>(kind: string, patches: PatchRequest, abortSignal?: AbortSignal) => Promise<R>;
68
+ checkPermissions: (resource: RESOURCE, verb: VERB) => Promise<boolean>;
68
69
  };
69
70
  metrics: {
70
71
  get: <R>(query: string, abortSignal?: AbortSignal) => Promise<R>;
@@ -73,8 +74,6 @@ export type AppContextProps = {
73
74
 
74
75
  export const AppContext = React.createContext<AppContextProps>({
75
76
  appType: 'standalone',
76
- qcow2ImgUrl: undefined,
77
- bootcImgUrl: undefined,
78
77
  router: {
79
78
  useNavigate,
80
79
  Link,
@@ -96,8 +95,10 @@ export const AppContext = React.createContext<AppContextProps>({
96
95
  getWsEndpoint: () => ({ wsEndpoint: '', protocols: [''] }),
97
96
  get: async () => ({}) as any,
98
97
  post: async () => ({}) as any,
98
+ put: async () => ({}) as any,
99
99
  remove: async () => ({}) as any,
100
100
  patch: async () => ({}) as any,
101
+ checkPermissions: async () => true,
101
102
  },
102
103
  metrics: {
103
104
  get: async () => ({}) as any,
@@ -8,6 +8,7 @@ const TIMEOUT = 10000;
8
8
 
9
9
  export const useFetchPeriodically = <R>(
10
10
  query: FlightControlQuery,
11
+ onFetchComplete?: (data: R) => void,
11
12
  ): [R | undefined, boolean, unknown, VoidFunction, boolean] => {
12
13
  const [isLoading, setIsLoading] = React.useState(true);
13
14
  const [isUpdating, setIsUpdating] = React.useState(false);
@@ -48,6 +49,9 @@ export const useFetchPeriodically = <R>(
48
49
  // eslint-disable-next-line
49
50
  setData(isAPI ? data : (data as any).data.result);
50
51
  setError(undefined);
52
+ if (isAPI && onFetchComplete) {
53
+ onFetchComplete(data as R);
54
+ }
51
55
  } catch (err) {
52
56
  // aborting fetch trows 'AbortError', we can ignore it
53
57
  if (abortController.signal.aborted) {
@@ -0,0 +1,8 @@
1
+ import { AccessReviewResult, useAccessReview } from './useAccessReview';
2
+ import { RESOURCE, VERB } from '../types/rbac';
3
+
4
+ export const useFleetImportAccessReview = (): AccessReviewResult => {
5
+ const canCreateRs = useAccessReview(RESOURCE.RESOURCE_SYNC, VERB.CREATE);
6
+ const canReadRepo = useAccessReview(RESOURCE.REPOSITORY, VERB.LIST);
7
+ return [canCreateRs[0] && canReadRepo[0], canCreateRs[1] || canReadRepo[1], canCreateRs[2] || canReadRepo[2]];
8
+ };
@@ -12,7 +12,7 @@ export enum ROUTE {
12
12
  FLEETS = 'FLEETS',
13
13
  FLEET_CREATE = 'FLEET_CREATE',
14
14
  FLEET_IMPORT = 'FLEET_IMPORT',
15
- FLEET_DETAILS = ' FLEET_DETAILS',
15
+ FLEET_DETAILS = 'FLEET_DETAILS',
16
16
  FLEET_EDIT = 'FLEET_EDIT',
17
17
  DEVICES = 'DEVICES',
18
18
  DEVICE_DETAILS = 'DEVICE_DETAILS',
@@ -20,8 +20,8 @@ export enum ROUTE {
20
20
  REPOSITORIES = 'REPOSITORIES',
21
21
  REPO_CREATE = 'REPO_CREATE',
22
22
  REPO_EDIT = 'REPO_EDIT',
23
- REPO_DETAILS = ' REPO_DETAILS',
24
- RESOURCE_SYNC_DETAILS = ' RESOURCE_SYNC_DETAILS',
23
+ REPO_DETAILS = 'REPO_DETAILS',
24
+ RESOURCE_SYNC_DETAILS = 'RESOURCE_SYNC_DETAILS',
25
25
  ENROLLMENT_REQUESTS = 'ENROLLMENT_REQUESTS',
26
26
  ENROLLMENT_REQUEST_DETAILS = 'ENROLLMENT_REQUEST_DETAILS',
27
27
  }
@@ -0,0 +1,12 @@
1
+ import { EnrollmentRequestList } from '@flightctl/types';
2
+
3
+ import { useFetchPeriodically } from './useFetchPeriodically';
4
+ import { getApiListCount } from '../utils/api';
5
+
6
+ export const usePendingEnrollmentRequestsCount = (): [number, boolean, unknown] => {
7
+ const [erList, loading, error] = useFetchPeriodically<EnrollmentRequestList>({
8
+ endpoint: 'enrollmentrequests?fieldSelector=!status.approval.approved&limit=1',
9
+ });
10
+
11
+ return [getApiListCount(erList) || 0, loading, error];
12
+ };
@@ -0,0 +1,44 @@
1
+ import * as React from 'react';
2
+
3
+ import { ApiList } from '../utils/api';
4
+ import { PAGE_SIZE } from '../constants';
5
+
6
+ export type PaginationDetails = {
7
+ onPageFetched: (list: ApiList<unknown>) => void;
8
+ currentPage: number;
9
+ setCurrentPage: (page: number) => void;
10
+ nextContinue: string;
11
+ itemCount: number;
12
+ };
13
+
14
+ export const useTablePagination = (): PaginationDetails => {
15
+ const [currentPage, setCurrentPage] = React.useState<number>(1);
16
+ const [continueTokens, setContinueTokens] = React.useState<string[]>([]);
17
+ const [itemCount, setItemCount] = React.useState<number>(0);
18
+
19
+ const nextContinue = currentPage <= 1 ? '' : continueTokens[currentPage - 2];
20
+
21
+ const onPageFetched = React.useCallback(
22
+ (apiList: ApiList<unknown>) => {
23
+ const prevItems = (currentPage - 1) * PAGE_SIZE;
24
+ setItemCount(prevItems + (apiList?.items.length || 0) + (apiList.metadata.remainingItemCount || 0));
25
+
26
+ const nextToken = apiList.metadata?.continue || '';
27
+ if (currentPage === 1) {
28
+ // Always reset the list when at first page
29
+ setContinueTokens([nextToken]);
30
+ } else if (continueTokens.length < currentPage) {
31
+ // Visiting current page for the first time
32
+ setContinueTokens((prevList: string[]) => prevList.concat(nextToken));
33
+ } else {
34
+ // Re-visiting current page, token is updated in case the list of items changed
35
+ setContinueTokens((prevList: string[]) =>
36
+ prevList.map((token, index) => (index === currentPage - 1 ? nextToken : token)),
37
+ );
38
+ }
39
+ },
40
+ [setContinueTokens, continueTokens, setItemCount, currentPage],
41
+ );
42
+
43
+ return { onPageFetched, currentPage, setCurrentPage, nextContinue, itemCount };
44
+ };
@@ -2,11 +2,11 @@ import * as React from 'react';
2
2
  import { useTranslation } from './useTranslation';
3
3
  import { useAppContext } from './useAppContext';
4
4
 
5
- export const useWebSocket = <T extends string>(
5
+ export const useWebSocket = <T>(
6
6
  endpoint: string,
7
- onMsgReceived: (msg: T) => void,
7
+ onMsgReceived: (msg: T) => Promise<void>,
8
8
  ): {
9
- sendMessage: (msg: T) => void;
9
+ sendMessage: (msg: string) => void;
10
10
  isConnecting: boolean;
11
11
  isClosed: boolean;
12
12
  error: unknown;
@@ -22,7 +22,7 @@ export const useWebSocket = <T extends string>(
22
22
  const [error, setError] = React.useState<unknown>();
23
23
  const [reset, setReset] = React.useState<number>(0);
24
24
 
25
- const sendMessage = React.useCallback((data: T) => {
25
+ const sendMessage = React.useCallback((data: string) => {
26
26
  wsRef.current?.send(data);
27
27
  }, []);
28
28
 
package/src/links.ts ADDED
@@ -0,0 +1,5 @@
1
+ export const CREATING_APPLICATIONS_LINK =
2
+ 'https://github.com/flightctl/flightctl/blob/main/docs/user/managing-devices.md#creating-applications';
3
+
4
+ export const USING_TEMPLATE_VARIABLES_LINK =
5
+ 'https://github.com/flightctl/flightctl/blob/main/docs/user/managing-fleets.md#defining-device-templates';
@@ -0,0 +1,18 @@
1
+ export enum VERB {
2
+ CREATE = 'create',
3
+ DELETE = 'delete',
4
+ LIST = 'list',
5
+ GET = 'get',
6
+ PATCH = 'patch',
7
+ POST = 'post',
8
+ }
9
+
10
+ export enum RESOURCE {
11
+ FLEET = 'fleets',
12
+ DEVICE = 'devices',
13
+ DEVICE_CONSOLE = 'devices/console',
14
+ REPOSITORY = 'repositories',
15
+ RESOURCE_SYNC = 'resourcesyncs',
16
+ ENROLLMENT_REQUEST = 'enrollmentrequests',
17
+ ENROLLMENT_REQUEST_APPROVAL = 'enrollmentrequests/approval',
18
+ }
package/src/utils/api.ts CHANGED
@@ -42,12 +42,12 @@ const getRequestQueryString = (queryObj: FlightControlQuery) => {
42
42
  return getMetricsQueryString(queryObj);
43
43
  };
44
44
 
45
- interface ApiList {
46
- items: Array<unknown>;
45
+ export interface ApiList<R> {
46
+ items: Array<R>;
47
47
  metadata: ListMeta;
48
48
  }
49
49
 
50
- const getApiListCount = (listResponse: ApiList | undefined): number | undefined => {
50
+ const getApiListCount = <T>(listResponse: ApiList<T> | undefined): number | undefined => {
51
51
  if (listResponse === undefined) {
52
52
  return undefined;
53
53
  }
@@ -22,6 +22,9 @@ export const toAPILabel = (labels: FlightCtlLabel[]): Record<string, string> =>
22
22
  {} as Record<string, string>,
23
23
  );
24
24
 
25
+ // Used to force the API to perform an exact match check for labels
26
+ export const labelToExactApiMatchString = (label: FlightCtlLabel) => `${label.key}=${label.value || ''}`;
27
+
25
28
  export const labelToString = (label: FlightCtlLabel) => `${label.key}${label.value ? `=${label.value}` : ''}`;
26
29
 
27
30
  export const stringToLabel = (labelStr: string): FlightCtlLabel => {
@@ -31,10 +34,3 @@ export const stringToLabel = (labelStr: string): FlightCtlLabel => {
31
34
  value: labelParts.length > 1 ? labelParts[1] : undefined,
32
35
  };
33
36
  };
34
-
35
- export const filterDevicesLabels = (allLabels: FlightCtlLabel[], selectedLabels: FlightCtlLabel[], filter: string) => {
36
- const filteredLabels = [...new Set(allLabels.concat(selectedLabels).map(labelToString))]
37
- .sort((a, b) => a.localeCompare(b, undefined, { sensitivity: 'base' })) // ignore case
38
- .filter((label) => label.includes(filter));
39
- return filteredLabels;
40
- };
@@ -0,0 +1,70 @@
1
+ import { FlightCtlLabel } from '../types/extraTypes';
2
+ import { labelToExactApiMatchString } from './labels';
3
+
4
+ const addQueryConditions = (fieldSelectors: string[], fieldSelector: string, values?: string[]) => {
5
+ if (values?.length === 1) {
6
+ fieldSelectors.push(`${fieldSelector}=${values[0]}`);
7
+ } else if (values?.length) {
8
+ fieldSelectors.push(`${fieldSelector} in (${values.join(',')})`);
9
+ }
10
+ };
11
+
12
+ const addTextContainsCondition = (fieldSelectors: string[], fieldSelector: string, value: string) => {
13
+ fieldSelectors.push(`${fieldSelector} contains ${value}`); // contains operator
14
+ };
15
+
16
+ const setLabelParams = (params: URLSearchParams, labels?: FlightCtlLabel[]) => {
17
+ if (labels?.length) {
18
+ const labelSelector = labels.reduce((acc, curr) => {
19
+ if (!acc) {
20
+ acc = `${curr.key}=${curr.value || ''}`;
21
+ } else {
22
+ acc += `,${curr.key}=${curr.value || ''}`;
23
+ }
24
+ return acc;
25
+ }, '');
26
+ params.append('labelSelector', labelSelector);
27
+ }
28
+ };
29
+
30
+ type CommonQueryOptions = {
31
+ limit: number | undefined;
32
+ };
33
+
34
+ export const commonQueries = {
35
+ // We can't specify a sorting, as every entity has a default sorting which is always applied implicitly.
36
+ getDevicesWithExactLabelMatching: (labels: FlightCtlLabel[], options?: CommonQueryOptions) => {
37
+ const searchParams = new URLSearchParams();
38
+
39
+ // By default (without the "equal" sign), the API returns a partial match, but only on the label keys
40
+ // To prevent this confusing behaviour, we query for exact matches in all cases (for both keys and values)
41
+ const exactLabelsMatch = labels.map(labelToExactApiMatchString).join(',');
42
+ searchParams.set('labelSelector', exactLabelsMatch);
43
+
44
+ if (options?.limit) {
45
+ searchParams.set('limit', `${options.limit}`);
46
+ }
47
+ return `devices?${searchParams.toString()}`;
48
+ },
49
+ getFleetsWithNameMatching: (matchName: string, options?: CommonQueryOptions) => {
50
+ const searchParams = new URLSearchParams();
51
+ searchParams.set('fieldSelector', `metadata.name contains ${matchName}`);
52
+
53
+ if (options?.limit) {
54
+ searchParams.set('limit', `${options.limit}`);
55
+ }
56
+ return `fleets?${searchParams.toString()}`;
57
+ },
58
+ getResourceSyncsByRepo: (repositoryId: string, options?: CommonQueryOptions) => {
59
+ const searchParams = new URLSearchParams();
60
+ searchParams.set('fieldSelector', `spec.repository=${repositoryId}`);
61
+
62
+ if (options?.limit) {
63
+ searchParams.set('limit', `${options.limit}`);
64
+ }
65
+ return `resourcesyncs?${searchParams.toString()}`;
66
+ },
67
+ getRepositoryById: (repositoryId: string) => `repositories/${repositoryId}`,
68
+ };
69
+
70
+ export { addQueryConditions, addTextContainsCondition, setLabelParams };
@@ -1,7 +1,7 @@
1
1
  import fuzzy from 'fuzzysearch';
2
2
 
3
3
  // Must be an even number for "getSearchResultsCount" to work
4
- const MAX_TOTAL_SEARCH_RESULTS = 10;
4
+ export const MAX_TOTAL_SEARCH_RESULTS = 10;
5
5
 
6
6
  export const fuzzySeach = (filter: string | undefined, value?: string): boolean => {
7
7
  if (!filter) {
@@ -18,6 +18,7 @@ export enum FilterSearchParams {
18
18
  AppStatus = 'appSt',
19
19
  UpdatedStatus = 'updSt',
20
20
  Label = 'label',
21
+ NameOrAlias = 'nameOrAlias',
21
22
  }
22
23
 
23
24
  export type DeviceSummaryStatus =
@@ -1,12 +0,0 @@
1
- import * as React from 'react';
2
- interface DeviceSystemdUnitStatus {
3
- name: string;
4
- status: string;
5
- }
6
- type SystemdDetailsTableProps = {
7
- matchPatterns?: Array<string>;
8
- systemdUnits: DeviceSystemdUnitStatus[] | undefined;
9
- };
10
- declare const SystemdDetailsTable: ({ matchPatterns, systemdUnits }: SystemdDetailsTableProps) => React.JSX.Element;
11
- export default SystemdDetailsTable;
12
- //# sourceMappingURL=SystemdDetailsTable.d.ts.map