katello 4.3.0.rc1 → 4.3.0.rc2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of katello might be problematic. Click here for more details.

Files changed (208) hide show
  1. checksums.yaml +4 -4
  2. data/app/controllers/katello/api/v2/api_controller.rb +4 -0
  3. data/app/controllers/katello/api/v2/host_errata_controller.rb +5 -0
  4. data/app/controllers/katello/api/v2/host_packages_controller.rb +2 -0
  5. data/app/controllers/katello/api/v2/host_tracer_controller.rb +4 -0
  6. data/app/controllers/katello/api/v2/repository_sets_controller.rb +2 -2
  7. data/app/controllers/katello/api/v2/root_controller.rb +10 -19
  8. data/app/controllers/katello/concerns/api/v2/bulk_extensions.rb +3 -13
  9. data/app/controllers/katello/remote_execution_controller.rb +1 -1
  10. data/app/lib/actions/katello/capsule_content/sync_capsule.rb +7 -5
  11. data/app/lib/actions/katello/repository/destroy.rb +3 -3
  12. data/app/lib/actions/pulp/repository/sync.rb +0 -2
  13. data/app/lib/actions/pulp3/abstract_async_task.rb +16 -4
  14. data/app/lib/katello/resources/cdn.rb +10 -1
  15. data/app/models/katello/concerns/host_managed_extensions.rb +7 -4
  16. data/app/models/katello/concerns/smart_proxy_extensions.rb +6 -2
  17. data/app/models/katello/content_view_version.rb +1 -6
  18. data/app/models/katello/glue/pulp/repo.rb +1 -2
  19. data/app/models/katello/host_tracer.rb +2 -0
  20. data/app/models/katello/repository.rb +2 -30
  21. data/app/models/katello/root_repository.rb +3 -43
  22. data/app/presenters/katello/host_package_presenter.rb +21 -0
  23. data/app/services/katello/bulk_items_helper.rb +35 -0
  24. data/app/services/katello/smart_proxy_helper.rb +10 -1
  25. data/app/views/foreman/job_templates/install_errata.erb +8 -6
  26. data/app/views/foreman/job_templates/resolve_traces.erb +4 -5
  27. data/app/views/foreman/job_templates/resolve_traces_-_katello_ansible_default.erb +3 -5
  28. data/app/views/foreman/smart_proxies/_content_sync.html.erb +7 -0
  29. data/app/views/katello/api/v2/capsule_content/sync_status.json.rabl +4 -0
  30. data/app/views/katello/api/v2/{organizations/cdn_configuration.rabl → cdn_configurations/show.json.rabl} +4 -0
  31. data/app/views/katello/api/v2/content_facet/show.json.rabl +8 -0
  32. data/app/views/katello/api/v2/content_view_filters/show.json.rabl +0 -1
  33. data/app/views/katello/api/v2/content_views/base.json.rabl +1 -1
  34. data/app/views/katello/api/v2/host_packages/base.json.rabl +2 -0
  35. data/app/views/katello/api/v2/organizations/show.json.rabl +1 -1
  36. data/app/views/katello/api/v2/repositories/show.json.rabl +0 -3
  37. data/config/routes/api/v2.rb +0 -10
  38. data/db/migrate/20211115215210_drop_ostree_branches.rb +13 -0
  39. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion-katello-bootstrap.js +0 -2
  40. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/bastion_katello.js +0 -3
  41. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/content-views.routes.js +0 -10
  42. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-versions.html +0 -3
  43. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-version-content.controller.js +0 -10
  44. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/content-view-versions.module.js +0 -1
  45. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version.html +0 -7
  46. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/content.service.js +0 -5
  47. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.module.js +0 -1
  48. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/environments.routes.js +0 -11
  49. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/organizations/fenced-pages.service.js +1 -2
  50. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +2 -4
  51. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.filter.js +0 -10
  52. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +1 -1
  53. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/new-repository.controller.js +3 -6
  54. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +4 -1
  55. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/os-versions.service.js +1 -0
  56. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/repositories.routes.js +0 -9
  57. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +0 -8
  58. data/engines/bastion_katello/lib/bastion_katello/engine.rb +0 -1
  59. data/lib/katello/permission_creator.rb +0 -1
  60. data/lib/katello/plugin.rb +0 -10
  61. data/lib/katello/tasks/reset.rake +2 -2
  62. data/lib/katello/version.rb +1 -1
  63. data/webpack/components/Packages/index.js +63 -0
  64. data/webpack/components/Search/Search.js +7 -1
  65. data/webpack/components/SelectAllCheckbox/index.js +2 -2
  66. data/webpack/components/Table/MainTable.scss +7 -1
  67. data/webpack/components/Table/TableHooks.js +10 -19
  68. data/webpack/components/Table/TableWrapper.js +0 -2
  69. data/webpack/components/WithOrganization/__snapshots__/withOrganization.test.js.snap +3 -3
  70. data/webpack/components/extensions/HostDetails/HostDetailsConstants.js +1 -0
  71. data/webpack/components/extensions/HostDetails/HostDetailsSelectors.js +16 -0
  72. data/webpack/components/extensions/HostDetails/HostErrata/HostErrataConstants.js +2 -0
  73. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesActions.js +11 -0
  74. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesConstants.js +2 -0
  75. data/webpack/components/extensions/HostDetails/HostPackages/HostPackagesSelectors.js +16 -0
  76. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/SecondaryTabsRoutes.js +4 -0
  77. data/webpack/components/extensions/HostDetails/Tabs/ContentTab/constants.js +1 -0
  78. data/webpack/components/extensions/HostDetails/Tabs/ErrataTab.js +119 -25
  79. data/webpack/components/extensions/HostDetails/Tabs/HostTracesConstants.js +1 -0
  80. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab.js +127 -0
  81. data/webpack/components/extensions/HostDetails/Tabs/PackagesTab.scss +11 -0
  82. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionActions.js +30 -4
  83. data/webpack/components/extensions/HostDetails/Tabs/RemoteExecutionConstants.js +1 -0
  84. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsActions.js +73 -0
  85. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsConstants.js +2 -0
  86. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsSelectors.js +16 -0
  87. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.js +347 -0
  88. data/webpack/components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab.scss +7 -0
  89. data/webpack/components/extensions/HostDetails/Tabs/TracesTab.js +38 -31
  90. data/webpack/components/extensions/HostDetails/Tabs/__tests__/bookmarks.fixtures.json +12 -0
  91. data/webpack/components/extensions/HostDetails/Tabs/__tests__/contentOverrides.fixtures.json +227 -0
  92. data/webpack/components/extensions/HostDetails/Tabs/__tests__/errataTab.test.js +423 -2
  93. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packages.fixtures.json +28 -0
  94. data/webpack/components/extensions/HostDetails/Tabs/__tests__/packagesTab.test.js +91 -0
  95. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySets.fixtures.json +120 -0
  96. data/webpack/components/extensions/HostDetails/Tabs/__tests__/repositorySetsTab.test.js +307 -0
  97. data/webpack/components/extensions/HostDetails/Tabs/__tests__/resolveErrata.fixtures.json +35 -0
  98. data/webpack/components/extensions/HostDetails/Tabs/__tests__/tracesTab.test.js +55 -9
  99. data/webpack/components/extensions/HostDetails/Tabs/customizedRexUrlHelpers.js +28 -14
  100. data/webpack/containers/Application/overrides.scss +31 -9
  101. data/webpack/global_index.js +4 -2
  102. data/webpack/redux/reducers/RedHatRepositories/enabled.fixtures.js +0 -2
  103. data/webpack/scenes/Content/ContentConfig.js +23 -7
  104. data/webpack/scenes/ContentCredentials/ContentCredentialActions.js +18 -0
  105. data/webpack/scenes/ContentCredentials/ContentCredentialConstants.js +2 -0
  106. data/webpack/scenes/ContentCredentials/ContentCredentialSelectors.js +12 -0
  107. data/webpack/scenes/ContentCredentials/__tests__/contentCredentials.fixtures.js +73 -0
  108. data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +1 -1
  109. data/webpack/scenes/ContentViews/Create/ContentViewFormComponents.js +3 -3
  110. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +7 -2
  111. data/webpack/scenes/ContentViews/Create/CreateContentViewForm.scss +7 -0
  112. data/webpack/scenes/ContentViews/Create/__tests__/createContentView.test.js +9 -9
  113. data/webpack/scenes/ContentViews/Delete/ContentViewDeleteWizard.js +6 -6
  114. data/webpack/scenes/ContentViews/Delete/Steps/CVDeleteEnvironmentsSelection.js +39 -37
  115. data/webpack/scenes/ContentViews/Delete/Steps/CVDeletionReview.js +35 -33
  116. data/webpack/scenes/ContentViews/Delete/__tests__/contentViewDelete.test.js +7 -5
  117. data/webpack/scenes/ContentViews/Delete/__tests__/cvVersionsData.fixtures.json +2 -6
  118. data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentEnvironments.js +13 -14
  119. data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +18 -9
  120. data/webpack/scenes/ContentViews/Details/ContentViewInfo.js +3 -2
  121. data/webpack/scenes/ContentViews/Details/Filters/Add/__tests__/cvFilterCreateResult.fixtures.json +1 -2
  122. data/webpack/scenes/ContentViews/Details/Filters/__tests__/CVRpmFilterContent.test.js +1 -1
  123. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewErrataByDateDetails.fixtures.json +1 -8
  124. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetail.fixtures.json +1 -2
  125. data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilterDetails.test.js +3 -8
  126. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvAllRepos.fixtures.json +0 -2
  127. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvErratumFilterDetails.fixtures.json +1 -2
  128. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvFilterDetailModuleAffectedRepos.fixtures.json +1 -8
  129. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvFilterDetailWithAffectedRepos.fixtures.json +1 -8
  130. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvModuleStreamFilterDetails.fixtures.json +1 -2
  131. data/webpack/scenes/ContentViews/Details/Filters/__tests__/cvPackageFilterDetail.fixtures.json +1 -3
  132. data/webpack/scenes/ContentViews/Details/Promote/ContentViewVersionPromote.js +44 -28
  133. data/webpack/scenes/ContentViews/Details/Repositories/ContentCounts.js +2 -1
  134. data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +1 -1
  135. data/webpack/scenes/ContentViews/Details/Repositories/LastSync.js +46 -8
  136. data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewDetailRepos.fixtures.json +0 -2
  137. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionContent.js +19 -3
  138. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionEnvironments.js +2 -2
  139. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionErrata.js +5 -3
  140. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersionErrata.scss +5 -2
  141. data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +7 -4
  142. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVEnvironmentSelectionForm.js +59 -53
  143. data/webpack/scenes/ContentViews/Details/Versions/Delete/RemoveSteps/CVVersionRemoveReview.js +24 -17
  144. data/webpack/scenes/ContentViews/Details/Versions/Delete/__tests__/versionsResponseData.fixtures.json +1 -4
  145. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/ContentViewVersionRepositoryCell.js +8 -3
  146. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionComponent.fixtures.json +1 -4
  147. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetails.fixtures.json +1 -2
  148. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionDetailsCounts.fixtures.json +1 -2
  149. data/webpack/scenes/ContentViews/Details/Versions/VersionDetails/__tests__/ContentViewVersionRepositories.fixtures.json +1 -18
  150. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.fixtures.json +5 -5
  151. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +1 -0
  152. data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersionsWithTask.fixtures.json +1 -3
  153. data/webpack/scenes/ContentViews/Details/contentViewInfo.scss +0 -4
  154. data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +66 -53
  155. data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +40 -28
  156. data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +3 -3
  157. data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +14 -14
  158. data/webpack/scenes/ContentViews/Publish/cvPublishForm.scss +6 -0
  159. data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +53 -12
  160. data/webpack/scenes/ContentViews/Table/tableDataGenerator.js +12 -6
  161. data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +6 -6
  162. data/webpack/scenes/ContentViews/components/ContentViewIcon.js +6 -5
  163. data/webpack/scenes/ContentViews/components/ContentViewsCounter.js +2 -2
  164. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +26 -27
  165. data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.scss +18 -6
  166. data/webpack/scenes/ContentViews/components/WizardHeader.js +44 -0
  167. data/webpack/scenes/ContentViews/components/contentViewIcon.scss +13 -2
  168. data/webpack/scenes/Organizations/OrganizationActions.js +22 -24
  169. data/webpack/scenes/Organizations/OrganizationConstants.js +1 -3
  170. data/webpack/scenes/Organizations/OrganizationReducer.js +0 -7
  171. data/webpack/scenes/Organizations/OrganizationSelectors.js +16 -0
  172. data/webpack/scenes/Organizations/__tests__/OrganizationActions.test.js +1 -21
  173. data/webpack/scenes/Organizations/__tests__/OrganizationReducer.test.js +0 -20
  174. data/webpack/scenes/Organizations/__tests__/organizations.fixtures.js +34 -23
  175. data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +151 -14
  176. data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +150 -31
  177. data/webpack/scenes/Subscriptions/Manifest/index.js +14 -3
  178. data/webpack/utils/dateTimeHelpers.js +7 -0
  179. data/webpack/utils/helpers.js +1 -1
  180. metadata +45 -43
  181. data/app/controllers/katello/api/v2/ostree_branches_controller.rb +0 -16
  182. data/app/lib/actions/pulp/repository/presenters/ostree_presenter.rb +0 -91
  183. data/app/models/katello/ostree_branch.rb +0 -12
  184. data/app/models/katello/repository_ostree_branch.rb +0 -7
  185. data/app/services/katello/pulp/ostree_branch.rb +0 -14
  186. data/app/services/katello/pulp/repository/ostree.rb +0 -48
  187. data/app/views/katello/api/v2/ostree_branches/compare.json.rabl +0 -10
  188. data/app/views/katello/api/v2/ostree_branches/index.json.rabl +0 -7
  189. data/app/views/katello/api/v2/ostree_branches/show.json.rabl +0 -5
  190. data/app/views/katello/api/v2/root/resource_list.json.rabl +0 -3
  191. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/versions/views/content-view-version-ostree-branches.html +0 -26
  192. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/environments/details/views/environment-ostree.html +0 -27
  193. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/ostree-branch-repositories.controller.js +0 -77
  194. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/ostree-branch.controller.js +0 -31
  195. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch-info.html +0 -15
  196. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch-repositories.html +0 -72
  197. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/details/views/ostree-branch.html +0 -30
  198. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branch.factory.js +0 -27
  199. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branches.controller.js +0 -67
  200. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branches.module.js +0 -15
  201. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/ostree-branches.routes.js +0 -50
  202. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/ostree-branches/views/ostree-branches.html +0 -40
  203. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-manage-ostree-branches.html +0 -40
  204. data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/ostree-upstream-sync-policy.service.js +0 -26
  205. data/webpack/components/extensions/HostDetails/Tabs/SubscriptionTab.js +0 -12
  206. data/webpack/scenes/Content/Details/ContentCounts.js +0 -42
  207. data/webpack/scenes/Subscriptions/Manifest/__tests__/SimpleContentAccess.test.js +0 -108
  208. data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +0 -158
@@ -3,6 +3,8 @@ import { REX_JOB_INVOCATIONS_KEY, REX_FEATURES } from './RemoteExecutionConstant
3
3
  import { foremanApi } from '../../../../services/api';
4
4
  import { getResponseErrorMsgs } from '../../../../utils/helpers';
5
5
  import { renderTaskStartedToast } from '../../../../scenes/Tasks/helpers';
6
+ import { ERRATA_SEARCH_QUERY } from '../HostErrata/HostErrataConstants';
7
+ import { TRACES_SEARCH_QUERY } from './HostTracesConstants';
6
8
 
7
9
  const errorToast = (error) => {
8
10
  const message = getResponseErrorMsgs(error.response);
@@ -24,13 +26,21 @@ const katelloPackageInstallParams = ({ hostname, packageName }) =>
24
26
  feature: REX_FEATURES.KATELLO_PACKAGE_INSTALL,
25
27
  });
26
28
 
27
- const katelloTracerResolveParams = ({ hostname, ids }) =>
29
+ const katelloTracerResolveParams = ({ hostname, search }) =>
28
30
  baseParams({
29
31
  hostname,
30
- inputs: { ids },
32
+ inputs: { [TRACES_SEARCH_QUERY]: search },
31
33
  feature: REX_FEATURES.KATELLO_HOST_TRACER_RESOLVE,
32
34
  });
33
35
 
36
+ const katelloHostErrataInstallParams = ({
37
+ hostname, search,
38
+ }) => baseParams({
39
+ hostname,
40
+ inputs: { [ERRATA_SEARCH_QUERY]: search },
41
+ feature: REX_FEATURES.KATELLO_HOST_ERRATA_INSTALL,
42
+ });
43
+
34
44
  export const installPackage = ({ hostname, packageName }) => post({
35
45
  type: API_OPERATIONS.POST,
36
46
  key: REX_JOB_INVOCATIONS_KEY,
@@ -43,14 +53,30 @@ export const installPackage = ({ hostname, packageName }) => post({
43
53
  errorToast: error => errorToast(error),
44
54
  });
45
55
 
46
- export const resolveTraces = ({ hostname, ids }) => post({
56
+ export const resolveTraces = ({ hostname, search }) => post({
47
57
  type: API_OPERATIONS.POST,
48
58
  key: REX_JOB_INVOCATIONS_KEY,
49
59
  url: foremanApi.getApiUrl('/job_invocations'),
50
- params: katelloTracerResolveParams({ hostname, ids }),
60
+ params: katelloTracerResolveParams({ hostname, search }),
51
61
  handleSuccess: response => renderTaskStartedToast({
52
62
  humanized: { action: `Resolve traces on ${hostname}` },
53
63
  id: response?.data?.dynflow_task?.id,
54
64
  }),
55
65
  errorToast: error => errorToast(error),
56
66
  });
67
+
68
+ export const installErrata = ({
69
+ hostname, search,
70
+ }) => post({
71
+ type: API_OPERATIONS.POST,
72
+ key: REX_JOB_INVOCATIONS_KEY,
73
+ url: foremanApi.getApiUrl('/job_invocations'),
74
+ params: katelloHostErrataInstallParams({
75
+ hostname, search,
76
+ }),
77
+ handleSuccess: response => renderTaskStartedToast({
78
+ humanized: { action: `Install Errata on ${hostname}` },
79
+ id: response?.data?.dynflow_task?.id,
80
+ }),
81
+ errorToast: error => errorToast(error),
82
+ });
@@ -2,4 +2,5 @@ export const REX_JOB_INVOCATIONS_KEY = 'REX_JOB_INVOCATIONS';
2
2
  export const REX_FEATURES = {
3
3
  KATELLO_PACKAGE_INSTALL: 'katello_package_install',
4
4
  KATELLO_HOST_TRACER_RESOLVE: 'katello_host_tracer_resolve',
5
+ KATELLO_HOST_ERRATA_INSTALL: 'katello_errata_install',
5
6
  };
@@ -0,0 +1,73 @@
1
+ import { translate as __ } from 'foremanReact/common/I18n';
2
+ import { API_OPERATIONS, get, put } from 'foremanReact/redux/API';
3
+ import katelloApi, { foremanApi } from '../../../../../services/api';
4
+ import { REPOSITORY_SETS_KEY, CONTENT_OVERRIDES_KEY } from './RepositorySetsConstants';
5
+ import { getResponseErrorMsgs } from '../../../../../utils/helpers';
6
+
7
+ const errorToast = (error) => {
8
+ const message = getResponseErrorMsgs(error.response);
9
+ return message;
10
+ };
11
+
12
+ export const getHostRepositorySets = params => get({
13
+ type: API_OPERATIONS.GET,
14
+ key: REPOSITORY_SETS_KEY,
15
+ url: katelloApi.getApiUrl('/repository_sets'),
16
+ errorToast: error => errorToast(error),
17
+ params,
18
+ });
19
+
20
+ export const enableRepoSetRepo = ({ hostId, labels, updateResults }) => put({
21
+ type: API_OPERATIONS.PUT,
22
+ key: CONTENT_OVERRIDES_KEY,
23
+ url: foremanApi.getApiUrl(`/hosts/${hostId}/subscriptions/content_override`),
24
+ params: {
25
+ content_overrides: labels.map(label => ({
26
+ content_label: label,
27
+ name: 'enabled',
28
+ value: true,
29
+ })),
30
+ },
31
+ updateData: () => {
32
+ updateResults({ labels, enabled: true });
33
+ },
34
+ successToast: () => (labels.length === 1 ? __('Repository set enabled') : __('Repository sets enabled')),
35
+ errorToast: error => errorToast(error),
36
+ });
37
+
38
+ export const disableRepoSetRepo = ({ hostId, labels, updateResults }) => put({
39
+ type: API_OPERATIONS.PUT,
40
+ key: CONTENT_OVERRIDES_KEY,
41
+ url: foremanApi.getApiUrl(`/hosts/${hostId}/subscriptions/content_override`),
42
+ params: {
43
+ content_overrides: labels.map(label => ({
44
+ content_label: label,
45
+ name: 'enabled',
46
+ value: false,
47
+ })),
48
+ },
49
+ updateData: () => {
50
+ updateResults({ labels, enabled: false });
51
+ },
52
+ successToast: () => (labels.length === 1 ? __('Repository set disabled') : __('Repository sets disabled')),
53
+ errorToast: error => errorToast(error),
54
+ });
55
+
56
+ export const resetRepoSetRepo = ({ hostId, labels, updateResults }) => put({
57
+ type: API_OPERATIONS.PUT,
58
+ key: CONTENT_OVERRIDES_KEY,
59
+ url: foremanApi.getApiUrl(`/hosts/${hostId}/subscriptions/content_override`),
60
+ params: {
61
+ content_overrides: labels.map(label => ({
62
+ content_label: label,
63
+ name: 'enabled',
64
+ value: false,
65
+ remove: true,
66
+ })),
67
+ },
68
+ updateData: (_, resp) => {
69
+ updateResults({ labels, enabled: null, newResponse: resp });
70
+ },
71
+ successToast: () => (labels.length === 1 ? __('Repository set reset to default') : __('Repository sets reset to default')),
72
+ errorToast: error => errorToast(error),
73
+ });
@@ -0,0 +1,2 @@
1
+ export const REPOSITORY_SETS_KEY = 'HOST_DETAIL_REPOSITORY_SETS';
2
+ export const CONTENT_OVERRIDES_KEY = 'HOST_DETAIL_CONTENT_OVERRIDES';
@@ -0,0 +1,16 @@
1
+ import {
2
+ selectAPIStatus,
3
+ selectAPIError,
4
+ selectAPIResponse,
5
+ } from 'foremanReact/redux/API/APISelectors';
6
+ import { STATUS } from 'foremanReact/constants';
7
+ import { REPOSITORY_SETS_KEY } from './RepositorySetsConstants';
8
+
9
+ export const selectRepositorySets = state =>
10
+ selectAPIResponse(state, REPOSITORY_SETS_KEY) || {};
11
+
12
+ export const selectRepositorySetsStatus = state =>
13
+ selectAPIStatus(state, REPOSITORY_SETS_KEY) || STATUS.PENDING;
14
+
15
+ export const selectRepositorySetsError = state =>
16
+ selectAPIError(state, REPOSITORY_SETS_KEY);
@@ -0,0 +1,347 @@
1
+ import React, { useCallback, useState, useEffect } from 'react';
2
+ import { FormattedMessage } from 'react-intl';
3
+ import PropTypes from 'prop-types';
4
+ import { useSelector, useDispatch } from 'react-redux';
5
+ import { Skeleton, ToggleGroup, ToggleGroupItem, Label, Tooltip, Alert, AlertActionCloseButton } from '@patternfly/react-core';
6
+ import {
7
+ TableVariant,
8
+ Thead,
9
+ Tbody,
10
+ Tr,
11
+ Th,
12
+ Td,
13
+ } from '@patternfly/react-table';
14
+ import { FlagIcon } from '@patternfly/react-icons';
15
+ import { translate as __ } from 'foremanReact/common/I18n';
16
+ import { propsToCamelCase } from 'foremanReact/common/helpers';
17
+ import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
18
+ import { STATUS } from 'foremanReact/constants';
19
+ import TableWrapper from '../../../../../components/Table/TableWrapper';
20
+ import { enableRepoSetRepo, disableRepoSetRepo, resetRepoSetRepo, getHostRepositorySets } from './RepositorySetsActions';
21
+ import { selectRepositorySetsStatus } from './RepositorySetsSelectors';
22
+ import { selectHostDetailsStatus } from '../../HostDetailsSelectors.js';
23
+ import { useBulkSelect } from '../../../../../components/Table/TableHooks';
24
+ import { REPOSITORY_SETS_KEY } from './RepositorySetsConstants.js';
25
+ import './RepositorySetsTab.scss';
26
+
27
+ const getEnabledValue = ({ enabled, enabledContentOverride }) => {
28
+ const isOverridden = (enabledContentOverride !== null);
29
+ return {
30
+ isOverridden,
31
+ isEnabled: (isOverridden ? enabledContentOverride : enabled),
32
+ };
33
+ };
34
+
35
+ const EnabledIcon = ({ isEnabled, isOverridden }) => {
36
+ const enabledLabel = (
37
+ <Label
38
+ color={isEnabled ? 'green' : 'gray'}
39
+ icon={isOverridden ? <FlagIcon /> : null}
40
+ className={`${isEnabled ? 'enabled' : 'disabled'}-label${isOverridden ? ' content-override' : ''}`}
41
+ >
42
+ {isEnabled ? __('Enabled') : __('Disabled')}
43
+ </Label>
44
+ );
45
+ if (isOverridden) {
46
+ return (
47
+ <Tooltip
48
+ position="right"
49
+ content={__('Overridden')}
50
+ >
51
+ {enabledLabel}
52
+ </Tooltip>
53
+ );
54
+ }
55
+ return enabledLabel;
56
+ };
57
+
58
+ EnabledIcon.propTypes = {
59
+ isEnabled: PropTypes.bool.isRequired,
60
+ isOverridden: PropTypes.bool.isRequired,
61
+ };
62
+
63
+ const RepositorySetsTab = () => {
64
+ const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
65
+ const {
66
+ id: hostId,
67
+ subscription_status: subscriptionStatus,
68
+ content_facet_attributes: contentFacetAttributes,
69
+ } = hostDetails;
70
+ const contentFacet = propsToCamelCase(contentFacetAttributes ?? {});
71
+ const {
72
+ contentViewDefault,
73
+ lifecycleEnvironmentLibrary,
74
+ contentViewName,
75
+ lifecycleEnvironmentName,
76
+ } = contentFacet;
77
+ const nonLibraryHost = contentViewDefault === false &&
78
+ lifecycleEnvironmentLibrary === false;
79
+ const simpleContentAccess = (Number(subscriptionStatus) === 5);
80
+ const dispatch = useDispatch();
81
+ const toggleGroupStates = ['noLimit', 'limitToEnvironment'];
82
+ const [noLimit, limitToEnvironment] = toggleGroupStates;
83
+ const defaultToggleGroupState = nonLibraryHost ? limitToEnvironment : noLimit;
84
+ const [toggleGroupState, setToggleGroupState] =
85
+ useState(defaultToggleGroupState);
86
+ const [alertShowing, setAlertShowing] = useState(false);
87
+ const emptyContentTitle = __('No repository sets to show.');
88
+ const emptyContentBody = __('Repository sets will appear here when available.');
89
+ const emptySearchTitle = __('No matching repository sets found');
90
+ const emptySearchBody = __('Try changing your search query.');
91
+ const columnHeaders = [
92
+ __('Repository'),
93
+ __('Product'),
94
+ __('Repository path'),
95
+ __('Status'),
96
+ ];
97
+ const fetchItems = useCallback(
98
+ params => (hostId ?
99
+ getHostRepositorySets({
100
+ content_access_mode_env: toggleGroupState === limitToEnvironment,
101
+ content_access_mode_all: simpleContentAccess,
102
+ host_id: hostId,
103
+ ...params,
104
+ }) : null),
105
+ [hostId, toggleGroupState, limitToEnvironment, simpleContentAccess],
106
+ );
107
+
108
+ const response = useSelector(state => selectAPIResponse(state, REPOSITORY_SETS_KEY));
109
+ const { results, ...metadata } = response;
110
+ const status = useSelector(state => selectRepositorySetsStatus(state));
111
+ const {
112
+ selectOne, isSelected, searchQuery, selectedCount, isSelectable,
113
+ updateSearchQuery, selectNone, fetchBulkParams, ...selectAll
114
+ } = useBulkSelect({
115
+ results,
116
+ metadata,
117
+ isSelectable: () => false,
118
+ });
119
+
120
+ const hostDetailsStatus = useSelector(state => selectHostDetailsStatus(state));
121
+
122
+ useEffect(() => {
123
+ // wait until host details are loaded to set alertShowing
124
+ if (hostDetailsStatus === STATUS.RESOLVED) {
125
+ setAlertShowing(nonLibraryHost);
126
+ }
127
+ }, [hostDetailsStatus, nonLibraryHost]);
128
+
129
+ if (!hostId) return <Skeleton />;
130
+
131
+ const updateResults = ({ labels, enabled, newResponse }) => dispatch({
132
+ type: `${REPOSITORY_SETS_KEY}_SUCCESS`,
133
+ key: REPOSITORY_SETS_KEY,
134
+ response: {
135
+ ...response,
136
+ results: results.map((result) => {
137
+ if (labels.includes(result.label)) {
138
+ const isEnabled = enabled === null ?
139
+ newResponse.results.find(r => r.id === result.id).enabled :
140
+ enabled;
141
+ return { ...result, enabled: isEnabled, enabled_content_override: enabled };
142
+ }
143
+ return result;
144
+ }),
145
+ },
146
+ });
147
+ const overrideToEnabled = ({ labels }) =>
148
+ dispatch(enableRepoSetRepo({ hostId, labels, updateResults }));
149
+ const overrideToDisabled = ({ labels }) =>
150
+ dispatch(disableRepoSetRepo({ hostId, labels, updateResults }));
151
+ const resetToDefault = ({ labels }) =>
152
+ dispatch(resetRepoSetRepo({ hostId, labels, updateResults }));
153
+
154
+ // uncomment (and remove rule disablement) when Select All is added
155
+ /* eslint-disable max-len */
156
+ // const dropdownItems = [
157
+ // <DropdownItem aria-label="bulk_enable" key="bulk_enable" component="button" onClick={overrideToEnabled}>
158
+ // {__('Override to enabled')}
159
+ // </DropdownItem>,
160
+ // <DropdownItem aria-label="bulk_disable" key="bulk_disable" component="button" onClick={overrideToDisabled}>
161
+ // {__('Override to disabled')}
162
+ // </DropdownItem>,
163
+ // <DropdownItem aria-label="bulk_disable" key="bulk_disable" component="button" onClick={resetToDefault}>
164
+ // {__('Reset to default')}
165
+ // </DropdownItem>,
166
+ // ];
167
+ /* eslint-enable max-len */
168
+
169
+ let toggleGroup;
170
+ if (nonLibraryHost) {
171
+ toggleGroup = (
172
+ <ToggleGroup aria-label="Repository Set toggle">
173
+ <ToggleGroupItem
174
+ text={__('Show all')}
175
+ buttonId="no-limit-toggle"
176
+ aria-label="No limit"
177
+ isSelected={toggleGroupState === noLimit}
178
+ onChange={() => setToggleGroupState(noLimit)}
179
+ />
180
+ <ToggleGroupItem
181
+ text={__('Limit to environment')}
182
+ buttonId="limit-to-env-toggle"
183
+ aria-label="Limit to environment"
184
+ isSelected={toggleGroupState === limitToEnvironment}
185
+ onChange={() => setToggleGroupState(limitToEnvironment)}
186
+ />
187
+ </ToggleGroup>
188
+ );
189
+ }
190
+
191
+ const hostEnvText = 'the "{contentViewName}" content view and "{lifecycleEnvironmentName}" environment';
192
+
193
+ const scaAlert = (toggleGroupState === limitToEnvironment ?
194
+ `Showing only repositories in ${hostEnvText}.` :
195
+ 'Showing all available repositories.');
196
+
197
+ const nonScaAlert = (toggleGroupState === limitToEnvironment ?
198
+ `Showing repositories in ${hostEnvText} that are available through subscriptions.` :
199
+ 'Showing all repositories available through subscriptions.');
200
+
201
+ let alertText;
202
+ if (simpleContentAccess) {
203
+ alertText = scaAlert;
204
+ } else {
205
+ alertText = nonScaAlert;
206
+ }
207
+
208
+ return (
209
+ <div>
210
+ <div id="repo-sets-tab">
211
+ <div className="content-header">
212
+ <div className="repo-sets-blurb">
213
+ <FormattedMessage
214
+ className="repo-sets-blurb"
215
+ id="repo-sets-blurb"
216
+ defaultMessage={__('Below are the repository sets currently available for this content host. For Red Hat subscriptions, additional content can be made available through the {rhrp}. Changing default settings requires subscription-manager 1.10 or newer to be installed on this host.')}
217
+ values={{
218
+ rhrp: <a href="/redhat_repositories">{__('Red Hat Repositories page')}</a>,
219
+ }}
220
+ />
221
+ </div>
222
+ {alertShowing &&
223
+ <Alert
224
+ variant="info"
225
+ className="repo-sets-alert"
226
+ isInline
227
+ title={
228
+ <FormattedMessage
229
+ className="repo-sets-alert-title"
230
+ id="repo-sets-alert-title"
231
+ defaultMessage={alertText}
232
+ values={{
233
+ contentViewName,
234
+ lifecycleEnvironmentName,
235
+ }}
236
+ />
237
+ }
238
+ actionClose={<AlertActionCloseButton onClose={() => setAlertShowing(false)} />}
239
+ />
240
+ }
241
+ </div>
242
+ <TableWrapper
243
+ {...{
244
+ metadata,
245
+ emptyContentTitle,
246
+ emptyContentBody,
247
+ emptySearchTitle,
248
+ emptySearchBody,
249
+ status,
250
+ searchQuery,
251
+ updateSearchQuery,
252
+ selectedCount,
253
+ selectNone,
254
+ toggleGroup,
255
+ }
256
+ }
257
+ activeFilters={[toggleGroupState]}
258
+ defaultFilters={[defaultToggleGroupState]}
259
+ additionalListeners={[hostId, toggleGroupState]}
260
+ fetchItems={fetchItems}
261
+ autocompleteEndpoint="/repository_sets/auto_complete_search"
262
+ bookmarkController="katello_product_contents" // Katello::ProductContent.table_name
263
+ rowsCount={results?.length}
264
+ variant={TableVariant.compact}
265
+ {...selectAll}
266
+ displaySelectAllCheckbox={false}
267
+ >
268
+ <Thead>
269
+ <Tr>
270
+ <Th key="select-all" />
271
+ {columnHeaders.map(col =>
272
+ <Th key={col}>{col}</Th>)}
273
+ <Th />
274
+ <Th key="action-menu" />
275
+ </Tr>
276
+ </Thead>
277
+ <>
278
+ {results?.map((repoSet, rowIndex) => {
279
+ const {
280
+ id,
281
+ label,
282
+ content: { name: repoName },
283
+ enabled,
284
+ enabled_content_override: enabledContentOverride,
285
+ contentUrl: repoPath,
286
+ product: { name: productName, id: productId },
287
+ } = repoSet;
288
+ const { isEnabled, isOverridden } =
289
+ getEnabledValue({ enabled, enabledContentOverride });
290
+ return (
291
+ <Tbody key={`${id}_${repoPath}`}>
292
+ <Tr>
293
+ <Td select={{
294
+ disable: !isSelectable(id),
295
+ isSelected: isSelected(id),
296
+ onSelect: (event, selected) => selectOne(selected, id),
297
+ rowIndex,
298
+ variant: 'checkbox',
299
+ }}
300
+ />
301
+ <Td>
302
+ <span>{repoName}</span>
303
+ </Td>
304
+ <Td>
305
+ <a href={`/products/${productId}`}>{productName}</a>
306
+ </Td>
307
+ <Td>
308
+ <span>{repoPath}</span>
309
+ </Td>
310
+ <Td>
311
+ <span><EnabledIcon key={`enabled-icon-${id}`} {...{ isEnabled, isOverridden }} /></span>
312
+ </Td>
313
+ <Td
314
+ key={`rowActions-${id}`}
315
+ actions={{
316
+ items: [
317
+ {
318
+ title: __('Override to disabled'),
319
+ isDisabled: isOverridden && !isEnabled,
320
+ onClick: () => overrideToDisabled({ labels: [label] }),
321
+ },
322
+ {
323
+ title: __('Override to enabled'),
324
+ isDisabled: isOverridden && isEnabled,
325
+ onClick: () => overrideToEnabled({ labels: [label] }),
326
+ },
327
+ {
328
+ title: __('Reset to default'),
329
+ isDisabled: !isOverridden,
330
+ onClick: () => resetToDefault({ labels: [label] }),
331
+ },
332
+ ],
333
+ }}
334
+ />
335
+ </Tr>
336
+ </Tbody>
337
+ );
338
+ })
339
+ }
340
+ </>
341
+ </TableWrapper>
342
+ </div>
343
+ </div>
344
+ );
345
+ };
346
+
347
+ export default RepositorySetsTab;
@@ -0,0 +1,7 @@
1
+ #repo-sets-tab .content-header .repo-sets-alert {
2
+ margin: 15px 24px;
3
+ }
4
+
5
+ #repo-sets-tab .content-header > .repo-sets-blurb {
6
+ margin: 15px 24px;
7
+ }
@@ -7,7 +7,7 @@ import { useSelector, useDispatch } from 'react-redux';
7
7
  import { selectAPIResponse } from 'foremanReact/redux/API/APISelectors';
8
8
  import EnableTracerEmptyState from './EnableTracerEmptyState';
9
9
  import TableWrapper from '../../../Table/TableWrapper';
10
- import { useSelectionSet } from '../../../Table/TableHooks';
10
+ import { useBulkSelect } from '../../../Table/TableHooks';
11
11
  import { getHostTraces } from './HostTracesActions';
12
12
  import { resolveTraces } from './RemoteExecutionActions';
13
13
  import { selectHostTracesStatus } from './HostTracesSelectors';
@@ -15,7 +15,6 @@ import { resolveTraceUrl } from './customizedRexUrlHelpers';
15
15
  import './TracesTab.scss';
16
16
 
17
17
  const TracesTab = () => {
18
- const [searchQuery, updateSearchQuery] = useState('');
19
18
  const hostDetails = useSelector(state => selectAPIResponse(state, 'HOST_DETAILS'));
20
19
  const dispatch = useDispatch();
21
20
  const {
@@ -37,34 +36,40 @@ const TracesTab = () => {
37
36
  const toggleBulkAction = () => setIsBulkActionOpen(prev => !prev);
38
37
  const response = useSelector(state => selectAPIResponse(state, 'HOST_TRACES'));
39
38
  const { results, ...meta } = response;
39
+ const tracesSearchQuery = id => `id = ${id}`;
40
40
  const {
41
- selectOne,
42
- isSelected, isSelectable,
43
- selectionSet: selectedTraces,
44
- ...selectAll
45
- } = useSelectionSet({
41
+ selectOne, isSelected, searchQuery, selectedCount, isSelectable,
42
+ updateSearchQuery, selectNone, fetchBulkParams, ...selectAll
43
+ } = useBulkSelect({
46
44
  results,
47
45
  metadata: meta,
48
46
  isSelectable: result => !!result.restart_command,
49
47
  });
50
48
 
51
- const onBulkRestartApp = (ids) => {
52
- dispatch(resolveTraces({ hostname, ids: [...ids].join(',') }));
53
- selectedTraces.clear();
54
49
 
50
+ const onBulkRestartApp = () => {
51
+ dispatch(resolveTraces({
52
+ hostname, search: fetchBulkParams(),
53
+ }));
54
+ selectNone();
55
55
  const params = { page: meta.page, per_page: meta.per_page, search: meta.search };
56
56
  dispatch(getHostTraces(hostId, params));
57
57
  };
58
58
 
59
- const bulkCustomizedRexUrl = ids => resolveTraceUrl({ hostname, ids: [...ids] });
59
+ const onRestartApp = id => dispatch(resolveTraces({
60
+ hostname,
61
+ search: tracesSearchQuery(id),
62
+ }));
60
63
 
61
- const onRestartApp = id => onBulkRestartApp([id]);
64
+ const bulkCustomizedRexUrl = () => resolveTraceUrl({
65
+ hostname, search: (selectedCount > 0) ? fetchBulkParams() : '',
66
+ });
62
67
 
63
68
  const dropdownItems = [
64
- <DropdownItem isDisabled={!selectedTraces.size} aria-label="bulk_rex" key="bulk_rex" component="button" onClick={() => onBulkRestartApp(selectedTraces)}>
69
+ <DropdownItem isDisabled={selectedCount === 0} aria-label="bulk_rex" key="bulk_rex" component="button" onClick={onBulkRestartApp}>
65
70
  {__('Restart via remote execution')}
66
71
  </DropdownItem>,
67
- <DropdownItem isDisabled={!selectedTraces.size} aria-label="bulk_rex_customized" key="bulk_rex_customized" component="a" href={bulkCustomizedRexUrl(selectedTraces)}>
72
+ <DropdownItem isDisabled={selectedCount === 0} aria-label="bulk_rex_customized" key="bulk_rex_customized" component="a" href={bulkCustomizedRexUrl()}>
68
73
  {__('Restart via customized remote execution')}
69
74
  </DropdownItem>,
70
75
  ];
@@ -76,8 +81,8 @@ const TracesTab = () => {
76
81
  <ActionListItem>
77
82
  <Button
78
83
  variant="secondary"
79
- isDisabled={!selectedTraces.size}
80
- onClick={() => onBulkRestartApp(selectedTraces)}
84
+ isDisabled={selectedCount === 0}
85
+ onClick={onBulkRestartApp}
81
86
  >
82
87
  {__('Restart app')}
83
88
  </Button>
@@ -96,9 +101,6 @@ const TracesTab = () => {
96
101
 
97
102
  );
98
103
  const status = useSelector(state => selectHostTracesStatus(state));
99
- // const selectAll = () => {
100
- // // leaving blank until we can implement selectAll Katello-wide
101
- // };
102
104
  if (showEnableTracer) return <EnableTracerEmptyState />;
103
105
 
104
106
  if (!hostId) return <Skeleton />;
@@ -108,21 +110,26 @@ const TracesTab = () => {
108
110
  <div id="traces-tab">
109
111
  <h3>{__('Tracer helps administrators identify applications that need to be restarted after a system is patched.')}</h3>
110
112
  <TableWrapper
111
- actionButtons={actionButtons}
112
- searchQuery={searchQuery}
113
- emptyContentBody={emptyContentBody}
114
- emptyContentTitle={emptyContentTitle}
115
- emptySearchBody={emptySearchBody}
116
- emptySearchTitle={emptySearchTitle}
117
- updateSearchQuery={updateSearchQuery}
118
- fetchItems={fetchItems}
113
+ {...{
114
+ emptyContentTitle,
115
+ emptyContentBody,
116
+ emptySearchTitle,
117
+ emptySearchBody,
118
+ status,
119
+ searchQuery,
120
+ updateSearchQuery,
121
+ selectedCount,
122
+ selectNone,
123
+ fetchItems,
124
+ actionButtons,
125
+ }
126
+ }
127
+ metadata={meta}
119
128
  autocompleteEndpoint={`/hosts/${hostId}/traces/auto_complete_search`}
120
129
  foremanApiAutoComplete
121
- displaySelectAllCheckbox
122
130
  rowsCount={results?.length}
123
131
  variant={TableVariant.compact}
124
- status={status}
125
- metadata={meta}
132
+ displaySelectAllCheckbox
126
133
  {...selectAll}
127
134
  >
128
135
  <Thead>
@@ -146,7 +153,7 @@ const TracesTab = () => {
146
153
  let rowDropdownItems = [
147
154
  { title: 'Restart via remote execution', onClick: () => onRestartApp(id) },
148
155
  {
149
- component: 'a', href: resolveTraceUrl({ hostname, ids: [id] }), title: 'Restart via customized remote execution',
156
+ component: 'a', href: resolveTraceUrl({ hostname, search: tracesSearchQuery(id) }), title: 'Restart via customized remote execution',
150
157
  },
151
158
  ];
152
159
  if (resolveDisabled) {
@@ -0,0 +1,12 @@
1
+ {
2
+ "total": 20,
3
+ "subtotal": 1,
4
+ "page": 1,
5
+ "per_page": 20,
6
+ "search": "controller=katello_product_contents",
7
+ "sort": {
8
+ "by": null,
9
+ "order": null
10
+ },
11
+ "results": []
12
+ }