katello 5.0.0.rc2 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (297) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/katello/locale/bn/katello.js +63 -15
  3. data/app/assets/javascripts/katello/locale/bn_IN/katello.js +62 -14
  4. data/app/assets/javascripts/katello/locale/ca/katello.js +62 -14
  5. data/app/assets/javascripts/katello/locale/cs/katello.js +63 -15
  6. data/app/assets/javascripts/katello/locale/cs_CZ/katello.js +64 -16
  7. data/app/assets/javascripts/katello/locale/de/katello.js +66 -18
  8. data/app/assets/javascripts/katello/locale/de_AT/katello.js +62 -14
  9. data/app/assets/javascripts/katello/locale/de_DE/katello.js +63 -15
  10. data/app/assets/javascripts/katello/locale/el/katello.js +62 -14
  11. data/app/assets/javascripts/katello/locale/en/katello.js +63 -15
  12. data/app/assets/javascripts/katello/locale/en_GB/katello.js +62 -14
  13. data/app/assets/javascripts/katello/locale/en_US/katello.js +62 -14
  14. data/app/assets/javascripts/katello/locale/es/katello.js +66 -18
  15. data/app/assets/javascripts/katello/locale/et_EE/katello.js +62 -14
  16. data/app/assets/javascripts/katello/locale/fr/katello.js +300 -252
  17. data/app/assets/javascripts/katello/locale/gl/katello.js +62 -14
  18. data/app/assets/javascripts/katello/locale/gu/katello.js +62 -14
  19. data/app/assets/javascripts/katello/locale/he_IL/katello.js +62 -14
  20. data/app/assets/javascripts/katello/locale/hi/katello.js +62 -14
  21. data/app/assets/javascripts/katello/locale/id/katello.js +62 -14
  22. data/app/assets/javascripts/katello/locale/it/katello.js +64 -16
  23. data/app/assets/javascripts/katello/locale/ja/katello.js +378 -330
  24. data/app/assets/javascripts/katello/locale/ka/katello.js +67 -19
  25. data/app/assets/javascripts/katello/locale/kn/katello.js +62 -14
  26. data/app/assets/javascripts/katello/locale/ko/katello.js +297 -249
  27. data/app/assets/javascripts/katello/locale/ml_IN/katello.js +62 -14
  28. data/app/assets/javascripts/katello/locale/mr/katello.js +62 -14
  29. data/app/assets/javascripts/katello/locale/nl_NL/katello.js +62 -14
  30. data/app/assets/javascripts/katello/locale/or/katello.js +62 -14
  31. data/app/assets/javascripts/katello/locale/pa/katello.js +62 -14
  32. data/app/assets/javascripts/katello/locale/pl/katello.js +62 -14
  33. data/app/assets/javascripts/katello/locale/pl_PL/katello.js +62 -14
  34. data/app/assets/javascripts/katello/locale/pt/katello.js +62 -14
  35. data/app/assets/javascripts/katello/locale/pt_BR/katello.js +66 -18
  36. data/app/assets/javascripts/katello/locale/ro/katello.js +62 -14
  37. data/app/assets/javascripts/katello/locale/ro_RO/katello.js +62 -14
  38. data/app/assets/javascripts/katello/locale/ru/katello.js +64 -16
  39. data/app/assets/javascripts/katello/locale/sl/katello.js +62 -14
  40. data/app/assets/javascripts/katello/locale/sv_SE/katello.js +62 -14
  41. data/app/assets/javascripts/katello/locale/ta/katello.js +63 -15
  42. data/app/assets/javascripts/katello/locale/ta_IN/katello.js +62 -14
  43. data/app/assets/javascripts/katello/locale/te/katello.js +62 -14
  44. data/app/assets/javascripts/katello/locale/tr/katello.js +62 -14
  45. data/app/assets/javascripts/katello/locale/vi/katello.js +62 -14
  46. data/app/assets/javascripts/katello/locale/vi_VN/katello.js +62 -14
  47. data/app/assets/javascripts/katello/locale/zh/katello.js +62 -14
  48. data/app/assets/javascripts/katello/locale/zh_CN/katello.js +285 -237
  49. data/app/assets/javascripts/katello/locale/zh_TW/katello.js +64 -16
  50. data/app/controllers/katello/api/registry/registry_proxies_controller.rb +29 -26
  51. data/app/controllers/katello/api/v2/content_view_histories_controller.rb +1 -1
  52. data/app/controllers/katello/concerns/api/v2/hosts_controller_extensions.rb +10 -10
  53. data/app/controllers/katello/concerns/registration_commands_controller_extensions.rb +1 -1
  54. data/app/lib/katello/concerns/base_template_scope_extensions.rb +61 -2
  55. data/app/models/katello/concerns/smart_proxy_extensions.rb +1 -1
  56. data/app/views/katello/api/v2/activation_keys/base.json.rabl +18 -18
  57. data/app/views/katello/api/v2/content_facet/base.json.rabl +19 -19
  58. data/app/views/katello/api/v2/content_view_environments/show.json.rabl +10 -10
  59. data/app/views/katello/api/v2/content_view_versions/base.json.rabl +2 -2
  60. data/db/migrate/20220929204746_add_content_view_environment_content_facet.rb +5 -5
  61. data/db/migrate/20240730163043_add_content_view_environment_activation_key.rb +5 -5
  62. data/db/migrate/20260402151630_add_content_view_environment_to_hostgroup_content_facet.rb +4 -4
  63. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/details/views/activation-key-info.html +1 -1
  64. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/activation-keys/new/views/activation-key-new.html +1 -1
  65. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn.po +0 -12
  66. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/bn_IN.po +0 -12
  67. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ca.po +0 -12
  68. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/cs_CZ.po +0 -12
  69. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de.po +0 -12
  70. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_AT.po +0 -12
  71. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/de_DE.po +0 -12
  72. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/el.po +0 -12
  73. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_GB.po +0 -12
  74. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/en_US.po +0 -12
  75. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/es.po +0 -12
  76. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/et_EE.po +0 -12
  77. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/fr.po +23 -24
  78. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gl.po +0 -12
  79. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/gu.po +0 -12
  80. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/he_IL.po +0 -12
  81. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/hi.po +0 -12
  82. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/id.po +0 -12
  83. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/it.po +0 -12
  84. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ja.po +20 -30
  85. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ka.po +0 -12
  86. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/kn.po +0 -12
  87. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ko.po +31 -39
  88. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ml_IN.po +0 -12
  89. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/mr.po +0 -12
  90. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/nl_NL.po +0 -12
  91. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/or.po +0 -12
  92. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pa.po +0 -12
  93. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl.po +0 -12
  94. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pl_PL.po +0 -12
  95. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt.po +0 -12
  96. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/pt_BR.po +0 -12
  97. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro.po +0 -12
  98. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ro_RO.po +0 -12
  99. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ru.po +0 -12
  100. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sl.po +0 -12
  101. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/sv_SE.po +0 -12
  102. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta.po +0 -12
  103. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/ta_IN.po +0 -12
  104. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/te.po +0 -12
  105. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/tr.po +0 -12
  106. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi.po +0 -12
  107. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/vi_VN.po +0 -12
  108. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh.po +0 -12
  109. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_CN.po +8 -17
  110. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/locale/zh_TW.po +0 -12
  111. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/translations.js +8 -8
  112. data/lib/katello/tasks/upgrades/4.20/clean_cve_with_no_cvv.rake +4 -4
  113. data/lib/katello/version.rb +1 -1
  114. data/lib/rubocop/cop/katello/cve_abbreviation.rb +82 -0
  115. data/locale/bn/LC_MESSAGES/katello.mo +0 -0
  116. data/locale/bn/katello.po +63 -15
  117. data/locale/bn_IN/LC_MESSAGES/katello.mo +0 -0
  118. data/locale/bn_IN/katello.po +62 -14
  119. data/locale/ca/LC_MESSAGES/katello.mo +0 -0
  120. data/locale/ca/katello.po +62 -14
  121. data/locale/cs/LC_MESSAGES/katello.mo +0 -0
  122. data/locale/cs/katello.po +64 -15
  123. data/locale/cs_CZ/LC_MESSAGES/katello.mo +0 -0
  124. data/locale/cs_CZ/katello.po +65 -17
  125. data/locale/de/LC_MESSAGES/katello.mo +0 -0
  126. data/locale/de/katello.po +67 -19
  127. data/locale/de_AT/LC_MESSAGES/katello.mo +0 -0
  128. data/locale/de_AT/katello.po +62 -14
  129. data/locale/de_DE/LC_MESSAGES/katello.mo +0 -0
  130. data/locale/de_DE/katello.po +64 -16
  131. data/locale/el/LC_MESSAGES/katello.mo +0 -0
  132. data/locale/el/katello.po +62 -14
  133. data/locale/en/LC_MESSAGES/katello.mo +0 -0
  134. data/locale/en/katello.po +64 -15
  135. data/locale/en_GB/LC_MESSAGES/katello.mo +0 -0
  136. data/locale/en_GB/katello.po +62 -14
  137. data/locale/en_US/LC_MESSAGES/katello.mo +0 -0
  138. data/locale/en_US/katello.po +62 -14
  139. data/locale/es/LC_MESSAGES/katello.mo +0 -0
  140. data/locale/es/katello.po +68 -21
  141. data/locale/et_EE/LC_MESSAGES/katello.mo +0 -0
  142. data/locale/et_EE/katello.po +62 -14
  143. data/locale/fr/LC_MESSAGES/katello.mo +0 -0
  144. data/locale/fr/katello.po +304 -256
  145. data/locale/gl/LC_MESSAGES/katello.mo +0 -0
  146. data/locale/gl/katello.po +62 -14
  147. data/locale/gu/LC_MESSAGES/katello.mo +0 -0
  148. data/locale/gu/katello.po +62 -14
  149. data/locale/he_IL/LC_MESSAGES/katello.mo +0 -0
  150. data/locale/he_IL/katello.po +62 -14
  151. data/locale/hi/LC_MESSAGES/katello.mo +0 -0
  152. data/locale/hi/katello.po +62 -14
  153. data/locale/id/LC_MESSAGES/katello.mo +0 -0
  154. data/locale/id/katello.po +62 -14
  155. data/locale/it/LC_MESSAGES/katello.mo +0 -0
  156. data/locale/it/katello.po +64 -16
  157. data/locale/ja/LC_MESSAGES/katello.mo +0 -0
  158. data/locale/ja/katello.po +379 -331
  159. data/locale/ka/LC_MESSAGES/katello.mo +0 -0
  160. data/locale/ka/katello.po +67 -19
  161. data/locale/katello.pot +457 -393
  162. data/locale/kn/LC_MESSAGES/katello.mo +0 -0
  163. data/locale/kn/katello.po +62 -14
  164. data/locale/ko/LC_MESSAGES/katello.mo +0 -0
  165. data/locale/ko/katello.po +300 -251
  166. data/locale/ml_IN/LC_MESSAGES/katello.mo +0 -0
  167. data/locale/ml_IN/katello.po +62 -14
  168. data/locale/mr/LC_MESSAGES/katello.mo +0 -0
  169. data/locale/mr/katello.po +62 -14
  170. data/locale/nl_NL/LC_MESSAGES/katello.mo +0 -0
  171. data/locale/nl_NL/katello.po +62 -14
  172. data/locale/or/LC_MESSAGES/katello.mo +0 -0
  173. data/locale/or/katello.po +62 -14
  174. data/locale/pa/LC_MESSAGES/katello.mo +0 -0
  175. data/locale/pa/katello.po +62 -14
  176. data/locale/pl/LC_MESSAGES/katello.mo +0 -0
  177. data/locale/pl/katello.po +62 -14
  178. data/locale/pl_PL/LC_MESSAGES/katello.mo +0 -0
  179. data/locale/pl_PL/katello.po +62 -14
  180. data/locale/pt/LC_MESSAGES/katello.mo +0 -0
  181. data/locale/pt/katello.po +62 -14
  182. data/locale/pt_BR/LC_MESSAGES/katello.mo +0 -0
  183. data/locale/pt_BR/katello.po +68 -20
  184. data/locale/ro/LC_MESSAGES/katello.mo +0 -0
  185. data/locale/ro/katello.po +62 -14
  186. data/locale/ro_RO/LC_MESSAGES/katello.mo +0 -0
  187. data/locale/ro_RO/katello.po +62 -14
  188. data/locale/ru/LC_MESSAGES/katello.mo +0 -0
  189. data/locale/ru/katello.po +64 -16
  190. data/locale/sl/LC_MESSAGES/katello.mo +0 -0
  191. data/locale/sl/katello.po +62 -14
  192. data/locale/sv_SE/LC_MESSAGES/katello.mo +0 -0
  193. data/locale/sv_SE/katello.po +62 -14
  194. data/locale/ta/LC_MESSAGES/katello.mo +0 -0
  195. data/locale/ta/katello.po +63 -15
  196. data/locale/ta_IN/LC_MESSAGES/katello.mo +0 -0
  197. data/locale/ta_IN/katello.po +62 -14
  198. data/locale/te/LC_MESSAGES/katello.mo +0 -0
  199. data/locale/te/katello.po +62 -14
  200. data/locale/tr/LC_MESSAGES/katello.mo +0 -0
  201. data/locale/tr/katello.po +62 -14
  202. data/locale/vi/LC_MESSAGES/katello.mo +0 -0
  203. data/locale/vi/katello.po +62 -14
  204. data/locale/vi_VN/LC_MESSAGES/katello.mo +0 -0
  205. data/locale/vi_VN/katello.po +62 -14
  206. data/locale/zh/LC_MESSAGES/katello.mo +0 -0
  207. data/locale/zh/katello.po +62 -14
  208. data/locale/zh_CN/LC_MESSAGES/katello.mo +0 -0
  209. data/locale/zh_CN/katello.po +286 -238
  210. data/locale/zh_TW/LC_MESSAGES/katello.mo +0 -0
  211. data/locale/zh_TW/katello.po +64 -16
  212. data/package.json +2 -2
  213. data/webpack/ForemanColumnExtensions/index.js +1 -1
  214. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/AssignHostCVModal.js +3 -3
  215. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/ContentViewDetailsCard.js +5 -5
  216. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/OrderableAssignments.js +5 -5
  217. data/webpack/components/extensions/HostDetails/Cards/ContentViewDetailsCard/__tests__/AssignHostCVModal.test.js +17 -17
  218. data/webpack/components/extensions/Hosts/BulkActions/BulkAssignCVEnvsModal/BulkAssignCVEnvsModal.js +4 -8
  219. data/webpack/components/extensions/Hosts/BulkActions/BulkAssignCVEnvsModal/__tests__/BulkAssignCVEnvsModal.test.js +1 -1
  220. data/webpack/components/extensions/Hosts/BulkActions/BulkAssignCVEnvsModal/index.js +2 -1
  221. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/BulkChangeHostCollectionsModal.js +5 -10
  222. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/__tests__/BulkChangeHostCollectionsModal.test.js +6 -24
  223. data/webpack/components/extensions/Hosts/BulkActions/BulkChangeHostCollectionsModal/index.js +2 -1
  224. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/04_ReviewFooter.js +2 -0
  225. data/webpack/components/extensions/Hosts/BulkActions/BulkErrataWizard/BulkErrataWizard.js +2 -1
  226. data/webpack/components/extensions/Hosts/BulkActions/BulkManageTracesModal/BulkManageTracesModal.js +4 -0
  227. data/webpack/components/extensions/Hosts/BulkActions/BulkManageTracesModal/index.js +2 -1
  228. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/04_ReviewFooter.js +2 -0
  229. data/webpack/components/extensions/Hosts/BulkActions/BulkPackagesWizard/BulkPackagesWizard.js +2 -1
  230. data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/03_ReviewFooter.js +2 -0
  231. data/webpack/components/extensions/Hosts/BulkActions/BulkRepositorySetsWizard/BulkRepositorySetsWizard.js +2 -1
  232. data/webpack/components/extensions/Hosts/BulkActions/BulkSystemPurposeModal/BulkSystemPurposeModal.js +5 -0
  233. data/webpack/components/extensions/Hosts/BulkActions/BulkSystemPurposeModal/index.js +2 -1
  234. data/webpack/components/extensions/Hosts/BulkActions/__tests__/bulkSystemPurposeModal.test.js +6 -1
  235. data/webpack/components/extensions/RegistrationCommands/__tests__/ActivationKeys.test.js +6 -6
  236. data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +1 -1
  237. data/webpack/containers/Application/config.js +1 -1
  238. data/webpack/eslint-rules/no-cve-abbreviation.js +121 -0
  239. data/webpack/global_index.js +6 -6
  240. data/webpack/redux/reducers/index.js +0 -2
  241. data/webpack/scenes/ActivationKeys/Details/ActivationKeyDetails.js +2 -2
  242. data/webpack/scenes/ActivationKeys/Details/components/AssignAKCVModal.js +3 -3
  243. data/webpack/scenes/ActivationKeys/Details/components/CreateAKCVModal.js +1 -1
  244. data/webpack/scenes/ActivationKeys/Details/components/{CVEDetailsCard.js → CvEnvDetailsCard.js} +9 -9
  245. data/webpack/scenes/ActivationKeys/Details/components/{CVEDetailsCreateCard.js → CvEnvDetailsCreateCard.js} +10 -10
  246. data/webpack/scenes/ActivationKeys/Details/components/__tests__/{CVEDetailsCreateCard.test.js → CvEnvDetailsCreateCard.test.js} +8 -8
  247. data/webpack/scenes/ContainerImages/Booted/BootedContainerImagesPage.js +2 -2
  248. data/webpack/scenes/ContainerImages/ContainerImagesPage.js +59 -52
  249. data/webpack/scenes/ContainerImages/ContainerImagesPage.scss +27 -4
  250. data/webpack/scenes/ContainerImages/Synced/SyncedContainerImagesPage.js +1 -1
  251. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +1 -11
  252. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionRemoveReview.js +9 -9
  253. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionDetailConfig.js +0 -28
  254. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.test.js +46 -1
  255. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersionContent.test.js +41 -0
  256. data/webpack/scenes/Hosts/ChangeContentSource/actions.js +2 -2
  257. data/webpack/scenes/Subscriptions/Manifest/CdnTabContent.js +44 -0
  258. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +179 -307
  259. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModalConstants.js +5 -0
  260. data/webpack/scenes/Subscriptions/Manifest/ManifestActions.js +64 -70
  261. data/webpack/scenes/Subscriptions/Manifest/ManifestConstants.js +5 -0
  262. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryContent.js +61 -0
  263. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +1 -1
  264. data/webpack/scenes/Subscriptions/Manifest/ManifestTabContent.js +357 -0
  265. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +129 -0
  266. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestActions.test.js +69 -110
  267. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManifestHistoryReducer.test.js +6 -2
  268. data/webpack/scenes/Subscriptions/Manifest/index.js +16 -1
  269. data/webpack/scenes/Subscriptions/SubscriptionActions.js +79 -145
  270. data/webpack/scenes/Subscriptions/SubscriptionConstants.js +4 -35
  271. data/webpack/scenes/Subscriptions/SubscriptionsColumns.js +90 -0
  272. data/webpack/scenes/Subscriptions/SubscriptionsPage.js +297 -217
  273. data/webpack/scenes/Subscriptions/SubscriptionsPage.scss +40 -30
  274. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsActions.js +11 -8
  275. data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsConstants.js +0 -1
  276. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +104 -205
  277. data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +12 -8
  278. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +245 -241
  279. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +61 -27
  280. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Table.js +487 -73
  281. data/webpack/scenes/Subscriptions/components/SubscriptionsToolbar/SubscriptionsToolbar.js +22 -4
  282. data/webpack/utils/contentViewEnvironmentLabel.js +3 -3
  283. data/webpack/utils/helpers.js +2 -2
  284. metadata +22 -20
  285. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.scss +0 -39
  286. data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryTableSchema.js +0 -47
  287. data/webpack/scenes/Subscriptions/SubscriptionReducer.js +0 -223
  288. data/webpack/scenes/Subscriptions/SubscriptionsSelectors.js +0 -31
  289. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsActions.test.js +0 -297
  290. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsReducer.test.js +0 -244
  291. data/webpack/scenes/Subscriptions/__tests__/SubscriptionsSelectors.test.js +0 -47
  292. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionNameFormatter.js +0 -23
  293. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionTypeFormatter.js +0 -32
  294. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +0 -169
  295. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionTypeFormatter.test.js +0 -41
  296. data/webpack/scenes/Subscriptions/components/SubscriptionsTable/index.js +0 -2
  297. data/webpack/scenes/Subscriptions/index.js +0 -57
@@ -1,294 +1,287 @@
1
- import React, { Component } from 'react';
1
+ import React, { useState, useCallback, useMemo, useEffect } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { cloneDeep, findIndex, isEqual } from 'lodash';
4
- import { translate as __ } from 'foremanReact/common/I18n';
5
- import { LoadingState } from '../../../../components/LoadingState';
4
+ import { filterRHSubscriptions } from '../../SubscriptionHelpers';
6
5
  import { recordsValid } from '../../SubscriptionValidations';
7
6
  import { buildTableRows, groupSubscriptionsByProductId } from './SubscriptionsTableHelpers';
8
7
  import Table from './components/Table';
9
8
  import Dialogs from './components/Dialogs';
10
9
 
11
- class SubscriptionsTable extends Component {
12
- constructor(props) {
13
- super(props);
14
-
15
- this.state = {
16
- rows: undefined,
17
- subscriptions: undefined,
18
- groupedSubscriptions: undefined,
19
- updatedQuantity: {},
20
- editing: false,
21
- showUpdateConfirmDialog: false,
22
- showCancelConfirmDialog: false,
23
- showErrorDialog: false,
10
+ const SubscriptionsTable = ({
11
+ emptyState,
12
+ tableColumns,
13
+ columns,
14
+ updateQuantity,
15
+ selectionEnabled,
16
+ customHeader,
17
+ customToolbar,
18
+ searchQuery,
19
+ organizationId,
20
+ availableQuantities,
21
+ selectedRows,
22
+ onSelectedRowsChange,
23
+ toggleDeleteButton,
24
+ subscriptionDeleteModalOpen,
25
+ onDeleteSubscriptions,
26
+ onSubscriptionDeleteModalClose,
27
+ onApiResponse,
28
+ onRefreshReady,
29
+ }) => {
30
+ const [subscriptions, setSubscriptions] = useState({
31
+ results: [],
32
+ loading: false,
33
+ availableQuantities: null,
34
+ itemCount: 0,
35
+ pagination: { page: 1, perPage: 20 },
36
+ searchIsActive: false,
37
+ });
38
+ const [rows, setRows] = useState([]);
39
+ const [groupedSubscriptions, setGroupedSubscriptions] = useState(undefined);
40
+ const [syncedSubscriptions, setSyncedSubscriptions] = useState(undefined);
41
+ const [updatedQuantity, setUpdatedQuantity] = useState({});
42
+ const [editing, setEditing] = useState(false);
43
+ const [showUpdateConfirmDialog, setShowUpdateConfirmDialog] = useState(false);
44
+ const [showCancelConfirmDialog, setShowCancelConfirmDialog] = useState(false);
45
+ const [showErrorDialog, setShowErrorDialog] = useState(false);
46
+
47
+ const handleApiResponse = useCallback((apiData) => {
48
+ const nextSubscriptions = {
49
+ results: apiData.results || [],
50
+ loading: apiData.loading,
51
+ availableQuantities: apiData.availableQuantities,
52
+ itemCount: apiData.itemCount,
53
+ pagination: {
54
+ page: apiData.page,
55
+ perPage: apiData.perPage,
56
+ },
57
+ searchIsActive: apiData.searchIsActive,
58
+ missingPermissions: apiData.missingPermissions,
59
+ activePermissions: apiData.activePermissions,
24
60
  };
25
- }
61
+ setSubscriptions(nextSubscriptions);
62
+ if (onApiResponse) {
63
+ onApiResponse(apiData);
64
+ }
65
+ }, [onApiResponse]);
26
66
 
27
- static getDerivedStateFromProps(nextProps, prevState) {
67
+ // Replaces getDerivedStateFromProps: sync rows when subscriptions change
68
+ useEffect(() => {
28
69
  if (
29
- nextProps.subscriptions !== undefined &&
30
- !isEqual(nextProps.subscriptions, prevState.subscriptions)
70
+ subscriptions !== undefined &&
71
+ !isEqual(subscriptions, syncedSubscriptions)
31
72
  ) {
32
- const groupedSubscriptions = groupSubscriptionsByProductId(
33
- nextProps.subscriptions,
34
- prevState.groupedSubscriptions,
35
- );
36
- const rows = buildTableRows(
73
+ const nextGroupedSubscriptions = groupSubscriptionsByProductId(
74
+ subscriptions,
37
75
  groupedSubscriptions,
38
- nextProps.subscriptions.availableQuantities,
39
- prevState.updatedQuantity,
76
+ );
77
+ const nextRows = buildTableRows(
78
+ nextGroupedSubscriptions,
79
+ subscriptions.availableQuantities,
80
+ updatedQuantity,
40
81
  );
41
82
 
42
- return { rows, groupedSubscriptions, subscriptions: nextProps.subscriptions };
83
+ setSyncedSubscriptions(subscriptions);
84
+ setGroupedSubscriptions(nextGroupedSubscriptions);
85
+ setRows(nextRows);
43
86
  }
87
+ }, [subscriptions, syncedSubscriptions, groupedSubscriptions, updatedQuantity]);
88
+
89
+ const enableEditing = useCallback((editingState) => {
90
+ setUpdatedQuantity({});
91
+ setEditing(editingState);
92
+ }, []);
93
+
94
+ const updateRows = useCallback((nextUpdatedQuantity) => {
95
+ setUpdatedQuantity(nextUpdatedQuantity);
96
+ setRows(buildTableRows(
97
+ groupedSubscriptions,
98
+ subscriptions.availableQuantities,
99
+ nextUpdatedQuantity,
100
+ ));
101
+ }, [groupedSubscriptions, subscriptions.availableQuantities]);
102
+
103
+ const toggleSubscriptionGroup = useCallback((groupId) => {
104
+ setGroupedSubscriptions((prevGrouped) => {
105
+ const nextGrouped = cloneDeep(prevGrouped);
106
+ nextGrouped[groupId].open = !nextGrouped[groupId].open;
107
+
108
+ setRows(buildTableRows(
109
+ nextGrouped,
110
+ subscriptions.availableQuantities,
111
+ updatedQuantity,
112
+ ));
113
+
114
+ return nextGrouped;
115
+ });
116
+ }, [subscriptions.availableQuantities, updatedQuantity]);
117
+
118
+ const showUpdateConfirm = useCallback(show => setShowUpdateConfirmDialog(show), []);
119
+ const showCancelConfirm = useCallback(show => setShowCancelConfirmDialog(show), []);
120
+ const showErrorDialogFn = useCallback(show => setShowErrorDialog(show), []);
121
+
122
+ const cancelEdit = useCallback(() => {
123
+ setShowCancelConfirmDialog(false);
124
+ setUpdatedQuantity({});
125
+ setEditing(false);
126
+ setRows(buildTableRows(
127
+ groupedSubscriptions,
128
+ subscriptions.availableQuantities,
129
+ {},
130
+ ));
131
+ }, [groupedSubscriptions, subscriptions.availableQuantities]);
132
+
133
+ const hasQuantityChanged = useCallback((rowData, editedValue) => {
134
+ if (editedValue !== undefined) {
135
+ const originalRows = subscriptions.results;
136
+ const index = findIndex(originalRows, row => (row.id === rowData.id));
137
+ if (index < 0) {
138
+ return false;
139
+ }
140
+ const currentValue = originalRows[index].quantity;
44
141
 
45
- return null;
46
- }
142
+ return (`${editedValue}` !== `${currentValue}`);
143
+ }
144
+ return false;
145
+ }, [subscriptions.results]);
47
146
 
48
- getInlineEditController = () => ({
147
+ const inlineEditController = useMemo(() => ({
49
148
  isEditing: ({ rowData }) =>
50
- (this.state.editing && rowData.upstream_pool_id && !rowData.expired),
149
+ (editing && rowData.upstream_pool_id && !rowData.expired),
51
150
  hasChanged: ({ rowData }) => {
52
- const editedValue = this.state.updatedQuantity[rowData.id];
53
- return this.hasQuantityChanged(rowData, editedValue);
151
+ const editedValue = updatedQuantity[rowData.id];
152
+ return hasQuantityChanged(rowData, editedValue);
54
153
  },
55
- onActivate: () => this.enableEditing(true),
154
+ onActivate: () => enableEditing(true),
56
155
  onConfirm: () => {
57
- if (recordsValid(this.state.rows)) {
58
- this.showUpdateConfirm(true);
156
+ if (recordsValid(rows)) {
157
+ showUpdateConfirm(true);
59
158
  } else {
60
- this.showErrorDialog(true);
159
+ showErrorDialogFn(true);
61
160
  }
62
161
  },
63
- onCancel: () => {
64
- this.showCancelConfirm(true);
65
- },
162
+ onCancel: () => showCancelConfirm(true),
66
163
  onChange: (value, { rowData }) => {
67
- const updatedQuantity = cloneDeep(this.state.updatedQuantity);
164
+ const nextUpdatedQuantity = cloneDeep(updatedQuantity);
68
165
 
69
- if (this.hasQuantityChanged(rowData, value)) {
70
- updatedQuantity[rowData.id] = value;
166
+ if (hasQuantityChanged(rowData, value)) {
167
+ nextUpdatedQuantity[rowData.id] = value;
71
168
  } else {
72
- delete updatedQuantity[rowData.id];
169
+ delete nextUpdatedQuantity[rowData.id];
73
170
  }
74
171
 
75
- this.updateRows(updatedQuantity);
172
+ updateRows(nextUpdatedQuantity);
76
173
  },
77
- });
78
-
79
- getSelectionController = () => {
80
- const allSubscriptionResults = this.props.subscriptions.results;
174
+ }), [
175
+ editing,
176
+ updatedQuantity,
177
+ rows,
178
+ hasQuantityChanged,
179
+ enableEditing,
180
+ showUpdateConfirm,
181
+ showErrorDialogFn,
182
+ showCancelConfirm,
183
+ updateRows,
184
+ ]);
185
+
186
+ const selectionController = useMemo(() => {
187
+ const allSubscriptionResults = filterRHSubscriptions(subscriptions.results || []);
81
188
 
82
189
  const checkAllRowsSelected = () =>
83
- allSubscriptionResults.length === this.props.selectedRows.length;
190
+ allSubscriptionResults.length > 0 &&
191
+ allSubscriptionResults.length === selectedRows.length;
84
192
 
85
- return ({
193
+ return {
86
194
  allRowsSelected: () => checkAllRowsSelected(),
87
195
  selectAllRows: () => {
88
196
  if (checkAllRowsSelected()) {
89
- this.props.onSelectedRowsChange([]);
90
- this.props.toggleDeleteButton(false);
197
+ onSelectedRowsChange([]);
198
+ toggleDeleteButton(false);
91
199
  } else {
92
- this.props.onSelectedRowsChange(allSubscriptionResults.map(row => row.id));
93
- this.props.toggleDeleteButton(true);
200
+ const selectedIds = allSubscriptionResults.map(row => row.id);
201
+ onSelectedRowsChange(selectedIds);
202
+ toggleDeleteButton(selectedIds.length > 0);
94
203
  }
95
204
  },
96
205
  selectRow: ({ rowData }) => {
97
- let { selectedRows } = this.props;
206
+ let nextSelectedRows = selectedRows;
98
207
  if (selectedRows.includes(rowData.id)) {
99
- selectedRows = selectedRows.filter(e => e !== rowData.id);
208
+ nextSelectedRows = selectedRows.filter(e => e !== rowData.id);
100
209
  } else {
101
- selectedRows = selectedRows.concat(rowData.id);
210
+ nextSelectedRows = selectedRows.concat(rowData.id);
102
211
  }
103
- this.props.onSelectedRowsChange(selectedRows);
104
- this.props.toggleDeleteButton(selectedRows.length > 0);
212
+ onSelectedRowsChange(nextSelectedRows);
213
+ toggleDeleteButton(nextSelectedRows.length > 0);
105
214
  },
106
- isSelected: ({ rowData }) => this.props.selectedRows.includes(rowData.id),
107
- });
108
- };
109
-
110
- getTableProps = () => {
111
- const {
112
- subscriptions,
113
- emptyState,
114
- tableColumns,
115
- loadSubscriptions,
116
- selectionEnabled,
117
- } = this.props;
118
- const { groupedSubscriptions, rows, editing } = this.state;
119
-
120
- return {
121
- emptyState,
122
- editing,
123
- groupedSubscriptions,
124
- loadSubscriptions,
125
- rows,
126
- subscriptions,
127
- selectionEnabled,
128
- tableColumns,
129
- toggleSubscriptionGroup: this.toggleSubscriptionGroup,
130
- inlineEditController: this.getInlineEditController(),
131
- selectionController: this.getSelectionController(),
132
- };
133
- };
134
-
135
- getUpdateDialogProps = () => {
136
- const { showUpdateConfirmDialog: show, updatedQuantity } = this.state;
137
- const {
138
- updateQuantity,
139
- } = this.props;
140
- return {
141
- show,
142
- updatedQuantity,
143
- updateQuantity,
144
- enableEditing: this.enableEditing,
145
- showUpdateConfirm: this.showUpdateConfirm,
146
- };
147
- };
148
-
149
- getUnsavedChangesDialogProps = () => {
150
- const { showCancelConfirmDialog: show } = this.state;
151
- return {
152
- show,
153
- cancelEdit: this.cancelEdit,
154
- showCancelConfirm: this.showCancelConfirm,
155
- };
156
- };
157
-
158
- getInputsErrorsDialogProps = () => {
159
- const { showErrorDialog: show } = this.state;
160
- return {
161
- show,
162
- showErrorDialog: this.showErrorDialog,
215
+ isSelected: ({ rowData }) => selectedRows.includes(rowData.id),
163
216
  };
164
- };
165
-
166
- getDeleteDialogProps = () => {
167
- const {
168
- subscriptionDeleteModalOpen: show,
169
- onDeleteSubscriptions,
170
- onSubscriptionDeleteModalClose,
171
- } = this.props;
172
- const { selectedRows } = this.props;
173
- return {
174
- show,
175
- selectedRows,
176
- onSubscriptionDeleteModalClose,
177
- onDeleteSubscriptions,
178
- };
179
- };
180
-
181
- getLoadingStateProps = () => {
182
- const { subscriptions: { loading } } = this.props;
183
- return {
184
- loading,
185
- loadingText: __('Loading'),
186
- };
187
- };
188
-
189
- getDialogsProps = () => ({
190
- updateDialog: this.getUpdateDialogProps(),
191
- unsavedChangesDialog: this.getUnsavedChangesDialogProps(),
192
- inputsErrorsDialog: this.getInputsErrorsDialogProps(),
193
- deleteDialog: this.getDeleteDialogProps(),
194
- });
195
-
196
-
197
- toggleSubscriptionGroup = (groupId) => {
198
- this.setState((prevState) => {
199
- const { subscriptions } = this.props;
200
- const { groupedSubscriptions, updatedQuantity } = prevState;
201
- const { open } = groupedSubscriptions[groupId];
202
-
203
- groupedSubscriptions[groupId].open = !open;
204
-
205
- const rows = buildTableRows(
206
- groupedSubscriptions,
207
- subscriptions.availableQuantities,
208
- updatedQuantity,
209
- );
210
- return { rows, groupedSubscriptions };
211
- });
212
- };
213
-
214
- enableEditing = (editingState) => {
215
- this.setState({
216
- updatedQuantity: {},
217
- editing: editingState,
218
- });
219
- };
220
-
221
- updateRows = (updatedQuantity) => {
222
- this.setState((prevState) => {
223
- const { groupedSubscriptions } = prevState;
224
- const { subscriptions } = this.props;
225
-
226
- const rows = buildTableRows(
227
- groupedSubscriptions,
228
- subscriptions.availableQuantities,
229
- updatedQuantity,
230
- );
231
- return { rows, updatedQuantity };
232
- });
233
- };
234
-
235
- showUpdateConfirm = (show) => {
236
- this.setState({
237
- showUpdateConfirmDialog: show,
238
- });
239
- };
240
-
241
- showCancelConfirm = (show) => {
242
- this.setState({
243
- showCancelConfirmDialog: show,
244
- });
245
- };
246
-
247
- showErrorDialog = (show) => {
248
- this.setState({
249
- showErrorDialog: show,
250
- });
251
- };
252
-
253
- cancelEdit = () => {
254
- this.showCancelConfirm(false);
255
- this.enableEditing(false);
256
- this.updateRows({});
257
- };
258
-
259
- hasQuantityChanged = (rowData, editedValue) => {
260
- if (editedValue !== undefined) {
261
- const originalRows = this.props.subscriptions.results;
262
- const index = findIndex(originalRows, row => (row.id === rowData.id));
263
- const currentValue = originalRows[index].quantity;
264
-
265
- return (`${editedValue}` !== `${currentValue}`);
266
- }
267
- return false;
268
- };
269
-
270
- render() {
271
- return (
272
- <LoadingState {...this.getLoadingStateProps()}>
273
- <Table ouiaId="subscriptions-table" {...this.getTableProps()} />
274
- <Dialogs {...this.getDialogsProps()} />
275
- </LoadingState>
276
- );
277
- }
278
- }
217
+ }, [
218
+ subscriptions.results,
219
+ selectedRows,
220
+ onSelectedRowsChange,
221
+ toggleDeleteButton,
222
+ ]);
223
+
224
+ return (
225
+ <>
226
+ <Table
227
+ ouiaId="subscriptions-table"
228
+ emptyState={emptyState}
229
+ editing={editing}
230
+ groupedSubscriptions={groupedSubscriptions}
231
+ rows={rows}
232
+ searchQuery={searchQuery}
233
+ organizationId={organizationId}
234
+ availableQuantities={availableQuantities}
235
+ selectionEnabled={selectionEnabled}
236
+ tableColumns={tableColumns}
237
+ columns={columns}
238
+ customHeader={customHeader}
239
+ customToolbar={customToolbar}
240
+ toggleSubscriptionGroup={toggleSubscriptionGroup}
241
+ inlineEditController={inlineEditController}
242
+ selectionController={selectionController}
243
+ onApiResponse={handleApiResponse}
244
+ onRefreshReady={onRefreshReady}
245
+ />
246
+ <Dialogs
247
+ updateDialog={{
248
+ show: showUpdateConfirmDialog,
249
+ updatedQuantity,
250
+ updateQuantity,
251
+ enableEditing,
252
+ showUpdateConfirm,
253
+ }}
254
+ unsavedChangesDialog={{
255
+ show: showCancelConfirmDialog,
256
+ cancelEdit,
257
+ showCancelConfirm,
258
+ }}
259
+ inputsErrorsDialog={{
260
+ show: showErrorDialog,
261
+ showErrorDialog: showErrorDialogFn,
262
+ }}
263
+ deleteDialog={{
264
+ show: subscriptionDeleteModalOpen,
265
+ selectedRows,
266
+ onSubscriptionDeleteModalClose,
267
+ onDeleteSubscriptions,
268
+ }}
269
+ />
270
+ </>
271
+ );
272
+ };
279
273
 
280
274
  SubscriptionsTable.propTypes = {
281
275
  tableColumns: PropTypes.arrayOf(PropTypes.string).isRequired,
282
- loadSubscriptions: PropTypes.func.isRequired,
276
+ columns: PropTypes.objectOf(PropTypes.shape({
277
+ title: PropTypes.node,
278
+ wrapper: PropTypes.func,
279
+ })).isRequired,
283
280
  updateQuantity: PropTypes.func.isRequired,
284
281
  emptyState: PropTypes.shape({}).isRequired,
285
- subscriptions: PropTypes.shape({
286
- loading: PropTypes.bool,
287
- availableQuantities: PropTypes.shape({}),
288
- // Disabling rule as existing code failed due to an eslint-plugin-react update
289
- // eslint-disable-next-line react/forbid-prop-types
290
- results: PropTypes.array,
291
- }).isRequired,
282
+ searchQuery: PropTypes.string,
283
+ organizationId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
284
+ availableQuantities: PropTypes.shape({}),
292
285
  subscriptionDeleteModalOpen: PropTypes.bool.isRequired,
293
286
  onDeleteSubscriptions: PropTypes.func.isRequired,
294
287
  onSubscriptionDeleteModalClose: PropTypes.func.isRequired,
@@ -296,10 +289,21 @@ SubscriptionsTable.propTypes = {
296
289
  selectedRows: PropTypes.instanceOf(Array).isRequired,
297
290
  onSelectedRowsChange: PropTypes.func.isRequired,
298
291
  selectionEnabled: PropTypes.bool,
292
+ customHeader: PropTypes.node,
293
+ customToolbar: PropTypes.node,
294
+ onApiResponse: PropTypes.func,
295
+ onRefreshReady: PropTypes.func,
299
296
  };
300
297
 
301
298
  SubscriptionsTable.defaultProps = {
299
+ searchQuery: '',
300
+ organizationId: undefined,
301
+ availableQuantities: null,
302
302
  selectionEnabled: false,
303
+ customHeader: undefined,
304
+ customToolbar: undefined,
305
+ onApiResponse: undefined,
306
+ onRefreshReady: undefined,
303
307
  };
304
308
 
305
309
  export default SubscriptionsTable;