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
@@ -2,13 +2,15 @@ import React from 'react';
2
2
  import { renderWithRedux, waitFor, patientlyWaitFor, fireEvent, act } from 'react-testing-lib-wrapper';
3
3
  import nock, { nockInstance, assertNockRequest, mockForemanAutocomplete, mockSetting } from '../../../../../test-utils/nockWrapper';
4
4
  import { foremanApi } from '../../../../../services/api';
5
- import { HOST_TRACES_KEY } from '../HostTracesConstants';
5
+ import { REX_FEATURES } from '../RemoteExecutionConstants';
6
+ import { HOST_TRACES_KEY, TRACES_SEARCH_QUERY } from '../HostTracesConstants';
6
7
  import TracesTab from '../TracesTab';
7
8
  import mockTraceData from './traces.fixtures.json';
8
9
  import mockResolveTraceTask from './resolveTraces.fixtures.json';
9
10
  import emptyTraceResults from './tracerEmptyTraceResults.fixtures.json';
10
11
  import mockJobInvocationStatus from './tracerEnableJobInvocation.fixtures.json';
11
12
 
13
+ const hostName = 'client.example.com';
12
14
  const tracerInstalledResponse = {
13
15
  id: 1,
14
16
  name: 'client.example.com',
@@ -29,6 +31,8 @@ const renderOptions = isTracerInstalled => ({ // sets initial Redux state
29
31
  initialState: {
30
32
  API: {
31
33
  HOST_DETAILS: {
34
+ name: hostName,
35
+ id: 1,
32
36
  response: isTracerInstalled ? tracerInstalledResponse : tracerNotInstalledResponse,
33
37
  status: 'RESOLVED',
34
38
  },
@@ -165,7 +169,6 @@ describe('With tracer installed', () => {
165
169
  });
166
170
  traceCheckbox.click();
167
171
  expect(traceCheckbox.checked).toEqual(true);
168
-
169
172
  const actionMenu = getByLabelText('bulk_actions');
170
173
  actionMenu.click();
171
174
  const viaRexAction = queryByText('Restart via remote execution');
@@ -177,12 +180,53 @@ describe('With tracer installed', () => {
177
180
  assertNockRequest(scope, done);
178
181
  });
179
182
 
183
+ test('Can select all, exclude and bulk restart traces via remote execution', async (done) => {
184
+ // This is the same test as above,
185
+ // but using the table action bar instead of the Restart app button
186
+ const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl);
187
+ const thirdTrace = mockTraceData.results[2];
188
+ const scope = nockInstance
189
+ .get(hostTraces)
190
+ .times(2)
191
+ .reply(200, mockTraceData);
192
+ const jobInvocationBody = ({ job_invocation: { inputs } }) =>
193
+ inputs[TRACES_SEARCH_QUERY] === `id !^ (${firstTrace.id},${thirdTrace.id})`;
194
+
195
+ const resolveTracesScope = nockInstance
196
+ .post(jobInvocations, jobInvocationBody)
197
+ .reply(201, mockResolveTraceTask);
198
+
199
+ const {
200
+ getByLabelText, getByText,
201
+ } = renderWithRedux(
202
+ <TracesTab />,
203
+ renderOptions(true),
204
+ );
205
+
206
+ let traceCheckbox;
207
+ // Assert that the traces are now showing on the screen, but wait for them to appear.
208
+ await patientlyWaitFor(() => {
209
+ const traceNameNode = getByText(firstTrace.application);
210
+ traceCheckbox = checkboxToTheLeftOf(traceNameNode);
211
+ });
212
+ const selectAllCheckbox = getByLabelText('Select all');
213
+ fireEvent.click(selectAllCheckbox);
214
+ expect(traceCheckbox.checked).toEqual(true);
215
+ fireEvent.click(getByLabelText('Select row 0')); // de select
216
+ fireEvent.click(getByLabelText('Select row 2')); // de select
217
+
218
+ fireEvent.click(getByText('Restart app'));
219
+
220
+ assertNockRequest(autocompleteScope);
221
+ assertNockRequest(resolveTracesScope);
222
+ assertNockRequest(scope, done);
223
+ });
224
+
180
225
  test('Can restart a single trace via remote execution', async (done) => {
181
226
  const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl);
182
227
 
183
228
  const scope = nockInstance
184
229
  .get(hostTraces)
185
- .times(2)
186
230
  .reply(200, mockTraceData);
187
231
  const resolveTracesScope = nockInstance
188
232
  .post(jobInvocations)
@@ -214,6 +258,7 @@ describe('With tracer installed', () => {
214
258
  });
215
259
 
216
260
  test('Can restart a single trace via customized remote execution', async (done) => {
261
+ const feature = REX_FEATURES.KATELLO_HOST_TRACER_RESOLVE;
217
262
  const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl);
218
263
  const scope = nockInstance
219
264
  .get(hostTraces)
@@ -230,7 +275,7 @@ describe('With tracer installed', () => {
230
275
  traceActionMenu = actionMenuToTheRightOf(traceNameNode);
231
276
  expect(traceActionMenu).toHaveAttribute('aria-label', 'Actions');
232
277
  });
233
- traceActionMenu.click();
278
+ fireEvent.click(traceActionMenu);
234
279
 
235
280
  let viaCustomizedRexAction;
236
281
  await patientlyWaitFor(() => {
@@ -239,7 +284,7 @@ describe('With tracer installed', () => {
239
284
  });
240
285
  expect(viaCustomizedRexAction).toHaveAttribute(
241
286
  'href',
242
- '/job_invocations/new?feature=katello_host_tracer_resolve&inputs%5Bids%5D=10&host_ids=name%20%5E%20(client.example.com)',
287
+ `/job_invocations/new?feature=${feature}&host_ids=name%20%5E%20(${hostName})&inputs%5BTraces%20search%20query%5D=id%20=%20${firstTrace.id}`,
243
288
  );
244
289
 
245
290
  assertNockRequest(autocompleteScope);
@@ -248,7 +293,7 @@ describe('With tracer installed', () => {
248
293
 
249
294
  test('Can bulk restart traces via customized remote execution', async (done) => {
250
295
  const autocompleteScope = mockForemanAutocomplete(nockInstance, autocompleteUrl);
251
-
296
+ const feature = REX_FEATURES.KATELLO_HOST_TRACER_RESOLVE;
252
297
  const scope = nockInstance
253
298
  .get(hostTraces)
254
299
  .reply(200, mockTraceData);
@@ -266,13 +311,13 @@ describe('With tracer installed', () => {
266
311
  expect(traceCheckbox.checked).toEqual(true);
267
312
 
268
313
  const actionMenu = getByLabelText('bulk_actions');
269
- actionMenu.click();
314
+ fireEvent.click(actionMenu);
270
315
  const viaCustomizedRexAction = queryByText('Restart via customized remote execution');
271
316
 
272
317
  expect(viaCustomizedRexAction).toBeInTheDocument();
273
318
  expect(viaCustomizedRexAction).toHaveAttribute(
274
319
  'href',
275
- '/job_invocations/new?feature=katello_host_tracer_resolve&inputs%5Bids%5D=10&host_ids=name%20%5E%20(client.example.com)',
320
+ `/job_invocations/new?feature=${feature}&host_ids=name%20%5E%20(${hostName})&inputs%5BTraces%20search%20query%5D=id%20%5E%20(${firstTrace.id})`,
276
321
  );
277
322
 
278
323
  assertNockRequest(autocompleteScope);
@@ -359,6 +404,7 @@ describe('Without tracer installed', () => {
359
404
  });
360
405
 
361
406
  test('Can enable tracer via customized remote execution', async () => {
407
+ const feature = REX_FEATURES.KATELLO_PACKAGE_INSTALL;
362
408
  const { getByText, getByRole, queryByText }
363
409
  = renderWithRedux(<TracesTab />, renderOptions(false));
364
410
 
@@ -378,7 +424,7 @@ describe('Without tracer installed', () => {
378
424
  expect(enableTracesModalLink)
379
425
  .toHaveAttribute(
380
426
  'href',
381
- '/job_invocations/new?feature=katello_package_install&inputs%5Bpackage%5D=katello-host-tools-tracer&host_ids=name%20%5E%20(client.example.com)',
427
+ `/job_invocations/new?feature=${feature}&host_ids=name%20%5E%20(${hostName})&inputs%5Bpackage%5D=katello-host-tools-tracer`,
382
428
  );
383
429
  enableTracesModalLink.click();
384
430
  expect(enableTracesModalLink).toHaveClass('pf-m-in-progress');
@@ -1,20 +1,34 @@
1
1
  import { REX_FEATURES } from './RemoteExecutionConstants';
2
- import { KATELLO_TRACER_PACKAGE } from './HostTracesConstants';
2
+ import { KATELLO_TRACER_PACKAGE, TRACES_SEARCH_QUERY } from './HostTracesConstants';
3
+ import { ERRATA_SEARCH_QUERY } from '../HostErrata/HostErrataConstants';
3
4
 
4
- export const katelloPackageInstallUrl = ({ hostname }) => {
5
- const urlQuery = encodeURI([
6
- `feature=${REX_FEATURES.KATELLO_PACKAGE_INSTALL}`,
7
- `inputs[package]=${KATELLO_TRACER_PACKAGE}`,
5
+ export const createJob = ({
6
+ hostname, feature, inputs,
7
+ }) => {
8
+ const inputParams = Object.keys(inputs).map(key => `inputs[${key}]=${inputs[key]}`);
9
+ const params = [
10
+ `feature=${feature}`,
8
11
  `host_ids=name ^ (${hostname})`,
9
- ].join('&'));
12
+ ...inputParams,
13
+ ];
14
+ const urlQuery = encodeURI(params.join('&'));
10
15
  return `/job_invocations/new?${urlQuery}`;
11
16
  };
12
17
 
13
- export const resolveTraceUrl = ({ hostname, ids }) => {
14
- const urlQuery = encodeURI([
15
- `feature=${REX_FEATURES.KATELLO_HOST_TRACER_RESOLVE}`,
16
- `inputs[ids]=${ids.join(',')}`,
17
- `host_ids=name ^ (${hostname})`,
18
- ].join('&'));
19
- return `/job_invocations/new?${urlQuery}`;
20
- };
18
+ export const katelloPackageInstallUrl = ({ hostname }) => createJob({
19
+ hostname,
20
+ feature: REX_FEATURES.KATELLO_PACKAGE_INSTALL,
21
+ inputs: { package: KATELLO_TRACER_PACKAGE },
22
+ });
23
+
24
+ export const resolveTraceUrl = ({ hostname, search }) => createJob({
25
+ hostname,
26
+ feature: REX_FEATURES.KATELLO_HOST_TRACER_RESOLVE,
27
+ inputs: { [TRACES_SEARCH_QUERY]: search },
28
+ });
29
+
30
+ export const errataInstallUrl = ({ hostname, search }) => createJob({
31
+ hostname,
32
+ feature: REX_FEATURES.KATELLO_HOST_ERRATA_INSTALL,
33
+ inputs: { [ERRATA_SEARCH_QUERY]: search },
34
+ });
@@ -10,13 +10,15 @@ html .pagination-pf-pagesize.btn-group {
10
10
 
11
11
  // necessary because of !important table margin css from foreman
12
12
  // https://github.com/theforeman/foreman/blob/develop/app/assets/stylesheets/base.scss#L242
13
- .table + .table-view-pf-pagination {
13
+ .table+.table-view-pf-pagination {
14
14
  margin-top: -6px !important;
15
15
  }
16
16
 
17
17
  // don't use this class if you need a dropdown menu to extend outside the table cell
18
18
  .neat-table-cells {
19
- td, th {
19
+
20
+ td,
21
+ th {
20
22
  overflow: auto;
21
23
  word-wrap: break-word;
22
24
  }
@@ -30,6 +32,7 @@ html .pagination-pf-pagesize.btn-group {
30
32
  word-wrap: break-word;
31
33
  }
32
34
  }
35
+
33
36
  // override foreman's .editable styles, that are conflicting with the patternfly ones
34
37
  .pf-table-inline-edit {
35
38
  .editable {
@@ -45,14 +48,16 @@ html .pagination-pf-pagesize.btn-group {
45
48
  // needed to ensure correct spacing between buttons and the button
46
49
  // container
47
50
  .toolbar-pf .form-group {
51
+
48
52
  .btn,
49
53
  .btn-group,
50
54
  .btn-container,
51
55
  .tooltip-button-helper {
52
- + .btn,
53
- + .btn-group,
54
- + .btn-container,
55
- + .tooltip-button-helper {
56
+
57
+ +.btn,
58
+ +.btn-group,
59
+ +.btn-container,
60
+ +.tooltip-button-helper {
56
61
  margin-left: 5px;
57
62
  }
58
63
  }
@@ -67,17 +72,34 @@ html .pagination-pf-pagesize.btn-group {
67
72
  margin: 24px 0px;
68
73
  }
69
74
 
75
+ // Modal sizing fix
70
76
  .pf-l-bullseye .pf-c-modal-box {
71
77
  margin-top: 76px;
72
78
  max-height: calc(100vh - 76px);
79
+
73
80
  @media (min-width: 768px) {
74
81
  max-width: calc(100vw - 240px);
75
82
  margin-left: 200px;
76
83
  }
77
84
  }
78
85
 
86
+ // Makes question tooltips have a hover state
87
+ .foreman-spaced-icon {
88
+ margin: 0 8px;
89
+
90
+ svg {
91
+ color: var(--pf-global--Color--200)
92
+ }
93
+
94
+ svg:hover {
95
+ color: var(--pf-global--Color--100)
96
+ }
97
+ }
98
+
79
99
  @keyframes hideme {
80
- 0%, 70% {
100
+
101
+ 0%,
102
+ 70% {
81
103
  opacity: 1;
82
104
  }
83
105
 
@@ -87,10 +109,10 @@ html .pagination-pf-pagesize.btn-group {
87
109
  }
88
110
 
89
111
  .tooltip {
90
- margin:auto;
112
+ margin: auto;
91
113
  animation-direction: normal;
92
114
  animation-name: hideme;
93
115
  animation-duration: 2s;
94
116
  animation-iteration-count: 1;
95
117
  animation-fill-mode: forwards;
96
- }
118
+ }
@@ -8,6 +8,7 @@ import ContentTab from './components/extensions/HostDetails/Tabs/ContentTab';
8
8
  import ContentViewDetailsCard from './components/extensions/HostDetails/Cards/ContentViewDetailsCard';
9
9
 
10
10
  // import SubscriptionTab from './components/extensions/HostDetails/Tabs/SubscriptionTab';
11
+ import RepositorySetsTab from './components/extensions/HostDetails/Tabs/RepositorySetsTab/RepositorySetsTab';
11
12
  import TracesTab from './components/extensions/HostDetails/Tabs/TracesTab';
12
13
  import extendReducer from './components/extensions/reducers';
13
14
  import rootReducer from './redux/reducers';
@@ -17,9 +18,10 @@ registerReducer('katello', rootReducer);
17
18
 
18
19
  addGlobalFill('aboutFooterSlot', '[katello]AboutSystemStatuses', <SystemStatuses key="katello-system-statuses" />, 100);
19
20
  addGlobalFill('registrationAdvanced', '[katello]RegistrationCommands', <RegistrationCommands key="katello-reg" />, 100);
20
- addGlobalFill('host-details-page-tabs', 'Content', <ContentTab key="content" />, 100);
21
+ addGlobalFill('host-details-page-tabs', 'Content', <ContentTab key="content" />, 900);
21
22
  /* eslint-disable max-len */
22
23
  // addGlobalFill('host-details-page-tabs', 'Subscription', <SubscriptionTab key="subscription" />, 100);
23
- addGlobalFill('host-details-page-tabs', 'Traces', <TracesTab key="traces" />, 100);
24
+ addGlobalFill('host-details-page-tabs', 'Traces', <TracesTab key="traces" />, 800);
25
+ addGlobalFill('host-details-page-tabs', 'Repository sets', <RepositorySetsTab key="repository-sets" />, 700);
24
26
 
25
27
  addGlobalFill('details-cards', 'Content View Details', <ContentViewDetailsCard key="content-view-details" />);
@@ -56,7 +56,6 @@ export const requestSuccessResponse = Immutable({
56
56
  },
57
57
  last_sync: null,
58
58
  content_counts: {
59
- ostree_branch: 0,
60
59
  docker_manifest: 0,
61
60
  docker_manifest_list: 0,
62
61
  docker_tag: 0,
@@ -97,7 +96,6 @@ export const requestSuccessResponse = Immutable({
97
96
  },
98
97
  last_sync: null,
99
98
  content_counts: {
100
- ostree_branch: 0,
101
99
  docker_manifest: 0,
102
100
  docker_manifest_list: 0,
103
101
  docker_tag: 0,
@@ -5,7 +5,7 @@ import { translate as __ } from 'foremanReact/common/I18n';
5
5
  import ContentInfo from './Details/ContentInfo';
6
6
  import LastSync from '../ContentViews/Details/Repositories/LastSync';
7
7
  import ContentRepositories from './Details/ContentRepositories';
8
- import ContentCounts from './Details/ContentCounts';
8
+ import ContentCounts from '../ContentViews/Details/Repositories/ContentCounts';
9
9
 
10
10
  export default () => [
11
11
  {
@@ -54,13 +54,16 @@ export default () => [
54
54
  {
55
55
  title: __('Sync Status'),
56
56
  getProperty: unit =>
57
- <LastSync lastSyncWords={unit?.last_sync_words} lastSync={unit?.last_sync} />,
57
+ (<LastSync
58
+ startedAt={unit?.last_sync?.started_at}
59
+ lastSyncWords={unit?.last_sync_words}
60
+ lastSync={unit?.last_sync}
61
+ />),
58
62
  },
59
63
  {
60
64
  title: __('Content Count'),
61
- getProperty: (unit, singularLabel) =>
65
+ getProperty: unit =>
62
66
  (<ContentCounts
63
- typeSingularLabel={singularLabel}
64
67
  productId={unit.product.id}
65
68
  repoId={unit.id}
66
69
  counts={unit.content_counts}
@@ -70,6 +73,16 @@ export default () => [
70
73
  },
71
74
  ],
72
75
  },
76
+ {
77
+ names: {
78
+ pluralTitle: __('OSTree Refs'),
79
+ singularTitle: __('OSTree Ref'),
80
+ pluralLowercase: __('OSTree refs'),
81
+ singularLowercase: __('OSTree ref'),
82
+ pluralLabel: 'ostree_refs',
83
+ singularLabel: 'ostree_ref',
84
+ },
85
+ },
73
86
  {
74
87
  names: {
75
88
  pluralTitle: __('Ansible Collections'),
@@ -119,13 +132,16 @@ export default () => [
119
132
  {
120
133
  title: __('Sync Status'),
121
134
  getProperty: unit =>
122
- <LastSync lastSyncWords={unit?.last_sync_words} lastSync={unit?.last_sync} />,
135
+ (<LastSync
136
+ startedAt={unit?.started_at}
137
+ lastSyncWords={unit?.last_sync_words}
138
+ lastSync={unit?.last_sync}
139
+ />),
123
140
  },
124
141
  {
125
142
  title: __('Content Count'),
126
- getProperty: (unit, singularLabel) =>
143
+ getProperty: unit =>
127
144
  (<ContentCounts
128
- typeSingularLabel={singularLabel}
129
145
  productId={unit.product.id}
130
146
  repoId={unit.id}
131
147
  counts={unit.content_counts}
@@ -0,0 +1,18 @@
1
+ import { API_OPERATIONS, get } from 'foremanReact/redux/API';
2
+ import api, { orgId } from '../../services/api';
3
+ import { GET_CONTENT_CREDENTIALS_KEY } from './ContentCredentialConstants';
4
+
5
+ export const getContentCredentials = (params = {}) => {
6
+ const defaultParams = {
7
+ organization_id: orgId(),
8
+ };
9
+
10
+ return get({
11
+ type: API_OPERATIONS.GET,
12
+ key: GET_CONTENT_CREDENTIALS_KEY,
13
+ url: api.getApiUrl('/content_credentials'),
14
+ params: { ...defaultParams, ...params },
15
+ });
16
+ };
17
+
18
+ export default getContentCredentials;
@@ -0,0 +1,2 @@
1
+ export const GET_CONTENT_CREDENTIALS_KEY = 'GET_CONTENT_CREDENTIALS';
2
+ export const CONTENT_CREDENTIAL_CERT_TYPE = 'cert';
@@ -0,0 +1,12 @@
1
+ import {
2
+ selectAPIResponse,
3
+ } from 'foremanReact/redux/API/APISelectors';
4
+
5
+ import { GET_CONTENT_CREDENTIALS_KEY } from './ContentCredentialConstants';
6
+
7
+ export const selectContentCredentials = (state) => {
8
+ const response = selectAPIResponse(state, GET_CONTENT_CREDENTIALS_KEY);
9
+ return response.results;
10
+ };
11
+
12
+ export default selectContentCredentials;
@@ -0,0 +1,73 @@
1
+ import Immutable from 'seamless-immutable';
2
+
3
+ const contentCredentialsResponse = Immutable({
4
+ total: 2,
5
+ subtotal: 2,
6
+ selectable: 2,
7
+ page: 1,
8
+ per_page: 20,
9
+ error: null,
10
+ search: null,
11
+ sort: {
12
+ by: 'name',
13
+ order: 'asc',
14
+ },
15
+ results: [
16
+ {
17
+ name: 'DevelServerCA',
18
+ content_type: 'cert',
19
+ content: '-----BEGIN CERTIFICATE-----\r\nMIIHHzCCBQegAwIBAgIJAIUIoI5kWBt2MA0GCSqGSIb3DQEBCwUAMIGTMQswCQYD\r\nVQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcMB1JhbGVp\r\nZ2gxEDAOBgNVBAoMB0thdGVsbG8xFDASBgNVBAsMC1NvbWVPcmdVbml0MTEwLwYD\r\nVQQDDChjZW50b3M3LWthdGVsbG8tZGV2ZWwuanR1cmVsLmV4YW1wbGUuY29tMB4X\r\nDTIxMDcyOTE1MDgwNVoXDTM4MDExODE1MDgwNVowgZMxCzAJBgNVBAYTAlVTMRcw\r\nFQYDVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEQMA4GA1UE\r\nCgwHS2F0ZWxsbzEUMBIGA1UECwwLU29tZU9yZ1VuaXQxMTAvBgNVBAMMKGNlbnRv\r\nczcta2F0ZWxsby1kZXZlbC5qdHVyZWwuZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3\r\nDQEBAQUAA4ICDwAwggIKAoICAQC4WsCZQpmOrRis/o9IsyW03vUon4FXPD00zm33\r\nykygAktyD93FAY0QhDMGnir+c9Uo3kU194QDyLTcGrOTw2POLHR/GDX7G4H5qEO9\r\nq1ZrGho4bYcgFqMBaGtFwpOuU4MhbgbKnwvfqNqPypshNpah74zcih9tey7fyCxd\r\nSIkarp8zB1bGcec5uvVDEd1EwjnrCSGx7Me1v61n0Fb7SrGlPa3qJC2bsL+jj1DF\r\nMukGEVsUxqvRMXe6i1jy4W7rWNUIsX2vIne1wup4qeojJy9zWWhwi5aGx6mIsUHN\r\nCqyfG+qNgkuJ1DfaZ2DwC8VJ6H17Gzzw7HdkQ4aYqk1hGvpJMS2WXR3vsP7OUO1S\r\n3qeGipksp5e/IEVX7fq+RUEMwrTDDgBsIeHL8R9hOsdtdqOm4RJ1IcGG0tgMA64q\r\nH0qFj0YheqO0x5rM5fD0Xh6TokQO9slSZRjjc4LfhcsRf8oqHfzm8v8dT0HQToNI\r\nDfvmg2TyxPAGsun0/b+9k5UBEIqpoByFPjR5oaH46oAzjiQm40lw8aMkEWK0n/41\r\n601neQMqwJdXsXt20Zz3UeLf8n09lDGUSYVztJkglV3vMNlrWn7hYrPPr1xq7zMs\r\ntfziExBctw2j5xOjOCMf7rt67SqmrQwurr4hSLJ3Iz+4JOd2ksVrjfHfv3/bc/Nk\r\nqgGQZwIDAQABo4IBcjCCAW4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAaYwHQYD\r\nVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMBEGCWCGSAGG+EIBAQQEAwICRDA1\r\nBglghkgBhvhCAQ0EKBYmS2F0ZWxsbyBTU0wgVG9vbCBHZW5lcmF0ZWQgQ2VydGlm\r\naWNhdGUwHQYDVR0OBBYEFEgCBjRDDqs9/Vb4D/rDuddgqGTGMIHIBgNVHSMEgcAw\r\ngb2AFEgCBjRDDqs9/Vb4D/rDuddgqGTGoYGZpIGWMIGTMQswCQYDVQQGEwJVUzEX\r\nMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcMB1JhbGVpZ2gxEDAOBgNV\r\nBAoMB0thdGVsbG8xFDASBgNVBAsMC1NvbWVPcmdVbml0MTEwLwYDVQQDDChjZW50\r\nb3M3LWthdGVsbG8tZGV2ZWwuanR1cmVsLmV4YW1wbGUuY29tggkAhQigjmRYG3Yw\r\nDQYJKoZIhvcNAQELBQADggIBAAVm6c0Rv5m2twcqAwlPLPQVBqBVE3k0+2/4zO0d\r\nNkVz9FPoD5v6psKEBnQS/qQ5pMmCTqJipG4BtVTHh0nLahi0bjHo1uesj/kZg5hg\r\nVbRPDIAhFXAOg1M2qV74DHCaCv1ALYgz6TlZFkeBfg4m/H9eucIKezgZaV/CNhWk\r\nBeKaOgh7qQl8qTCp0CL97csmfmxLe51EzejNXAXjwwZ2R4438mR2K252fbzts0LS\r\nq9Dfx1XK0HmS0l5dhMFYfBQ4nY0ZQ/jgb/h8SxLTeKPJOHHdhzse6IL1f2rBIWL2\r\nmH7bLn8rfQaqyXZh/iKpY/xxVauCSsQcYVNaXOF66h20/wtPIQWx1xxzgnUa3/xW\r\nuMCocIzG3vBBBDeVs8M0mTTxMGRtfx2KMj7wZv6trq2SSyUtVk1CWn80iv8PQUfn\r\nOQwecX1cMdh5K21fK16aAlB48VKXpuxKQPxGYdNSFYVnadMgXvdQAyofjwGWCzWL\r\n9C/N37gtz8WsFXr54QYWkKlbuvYM1tuUNaZdySTW0RPO4Eqbmogh3ffDtrq8RaHh\r\nPBtTLwxf0LZgqqOCxGFhgPrVt3vhj8K9G5IC9dzl7lGamQ8YDJRuBkAhmtD5yxL7\r\nwAmqhAMBTDvNRT83b9WiMAakRVjuWgwIcDwzgeCErjCPCVTFP7Gvl1HveVvFsPXR\r\n7GZO\r\n-----END CERTIFICATE-----\r\n',
20
+ id: 6,
21
+ organization_id: 4,
22
+ organization: {
23
+ name: 'ISS',
24
+ label: 'ISS',
25
+ id: 4,
26
+ },
27
+ created_at: '2021-10-28 16:50:48 -0400',
28
+ updated_at: '2021-10-28 16:50:48 -0400',
29
+ gpg_key_products: [],
30
+ gpg_key_repos: [],
31
+ ssl_ca_products: [],
32
+ ssl_ca_root_repos: [],
33
+ ssl_client_products: [],
34
+ ssl_client_root_repos: [],
35
+ ssl_key_products: [],
36
+ ssl_key_root_repos: [],
37
+ permissions: {
38
+ view_content_credenials: true,
39
+ edit_content_credenials: true,
40
+ destroy_content_credenials: true,
41
+ },
42
+ },
43
+ {
44
+ name: 'UpstreamServerCA',
45
+ content_type: 'cert',
46
+ content: '-----BEGIN CERTIFICATE-----\nMIIHGTCCBQGgAwIBAgIJAK+PvWdMGcRbMA0GCSqGSIb3DQEBCwUAMIGRMQswCQYD\nVQQGEwJVUzEXMBUGA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcMB1JhbGVp\nZ2gxEDAOBgNVBAoMB0thdGVsbG8xFDASBgNVBAsMC1NvbWVPcmdVbml0MS8wLQYD\nVQQDDCZjZW50b3M3LWthdGVsbG8tNC0yLmp0dXJlbC5leGFtcGxlLmNvbTAeFw0y\nMTEwMjYxNTQzMjlaFw0zODAxMTcxNTQzMjlaMIGRMQswCQYDVQQGEwJVUzEXMBUG\nA1UECAwOTm9ydGggQ2Fyb2xpbmExEDAOBgNVBAcMB1JhbGVpZ2gxEDAOBgNVBAoM\nB0thdGVsbG8xFDASBgNVBAsMC1NvbWVPcmdVbml0MS8wLQYDVQQDDCZjZW50b3M3\nLWthdGVsbG8tNC0yLmp0dXJlbC5leGFtcGxlLmNvbTCCAiIwDQYJKoZIhvcNAQEB\nBQADggIPADCCAgoCggIBALKfp6gXOiyUU9z7b1Zrg4arCQ1QK8J2PvwVJo+NeNZC\nVnUzw3hof0rIovL4/cUUpZYGtCME0PSthxsnYwRSXALW2Gmy3qIm6k+3K524+yYX\n9PWE1CVCPjgboLfBIrkb1WlviZZ4pKdoPxF2DUUksw4T9inpeir/Nlul9dEvbGHw\nIXkNxolVrkrD2bD9C0z+JjzfLwlJ8CH/FX/tan3jMUqKF70Gi5MEyL6TDhHmduGG\nNPywwdC5oH6jUg94w38SdVovI7uHb/Pu5Kgw9sVBAZ4I+7vQqFL0M8YG/Di/kp/V\nLlqqRxjn1T7FepMo/gNWb3Yc9ZBcSyxHgqHlZi/dy4zW+l/y3OgCGekGkma5IjzY\n9qJyNxGUXennAMkjW1+P40CLFuqN77rmV7dYwIR+jcPmzhz1eEhkLNyNfvcQlVTf\nCCkqaX53kVH4Cu4MFcWFs74W9v5BiPydhhzfy7O3rhDCrIu7Z9A5Qt0d3Ctj5x/C\ny2sj+oO35QGhj0KsjuvCfR3HxojSNfjM65tkKzdSRDt9hYP8+Up2YT6EDo72Mp6m\ndAiwrPxiAUOQDVEhzeEjMN8Cgsb3vyOy1cnYCttgiPXvTdGOt5NTUoolWn4ubBOY\nnLROTPyJmqevhQjcxQdSwsjPkFnZWFx6xB6WT10leFGFhclUa2lHVWHn5r9ZZf75\nAgMBAAGjggFwMIIBbDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBpjAdBgNVHSUE\nFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEQYJYIZIAYb4QgEBBAQDAgJEMDUGCWCG\nSAGG+EIBDQQoFiZLYXRlbGxvIFNTTCBUb29sIEdlbmVyYXRlZCBDZXJ0aWZpY2F0\nZTAdBgNVHQ4EFgQUdMirW7cQqNXyPyRXrrEb38l2sq8wgcYGA1UdIwSBvjCBu4AU\ndMirW7cQqNXyPyRXrrEb38l2sq+hgZekgZQwgZExCzAJBgNVBAYTAlVTMRcwFQYD\nVQQIDA5Ob3J0aCBDYXJvbGluYTEQMA4GA1UEBwwHUmFsZWlnaDEQMA4GA1UECgwH\nS2F0ZWxsbzEUMBIGA1UECwwLU29tZU9yZ1VuaXQxLzAtBgNVBAMMJmNlbnRvczct\na2F0ZWxsby00LTIuanR1cmVsLmV4YW1wbGUuY29tggkAr4+9Z0wZxFswDQYJKoZI\nhvcNAQELBQADggIBAFriP91uFIPUOwrgVqbFDWykSWQtcP8NrvPJ5LPCkjhSgh6u\nnOL9ZDL2w6/oYzO70q/tQmWbBwnYfv+D5lrHjkXejXIpR2rjOPZbTSKLst0qtTF3\nwqK33vty7jTx/l91dV8HY/Ip/WoXPmGT8FmDN8UWXX6MGA6m6nPMQCJuDYCmXaEz\nMQNd6Hgew0ArtgY4dPTvK0vmvMgEXw9v3FY8xIbgoAzoZ44/C/X5OodkJRPL8qwx\nwEWlPLe4a53WD/jU+qKJA71J4DL+QiXREDfVeuoqRAvWt4NrN0emEgDGlXn+gybS\nbU4s2GotQQKgqbmk9yA0/ZsZbd8zAV13CtRhiApsCPwO6YmIgzG0yqbM8VV6hATo\nkYiLmrgaMaIUJpyZze7P4PDSwAeMjqXs9p4oYA/aBD+pJ+OWI/PhPIdyl5e4kr7L\ne8hZkcuOo7Mw7kyvjKWo8zI/v9NJVSDAFXvBWVY+nYXLc7ovfX/msYgvyF2ylAHq\nNqJR6OZQoS1nWz2kYRqn4p3ygNSKUfctNA24CgorMqKLJ0XNJEBSoNV9rRczKghY\nXKScr3j4HnfLeyHmIo05XFPCCh1SfnQDG0H0rDHXNGABJhfNc35Y6TyXZhUgMxit\nQ9Vgl2JTl8+5swzfVdLemBXg4N6ITISkvyL3/keCca3U+4UTPCw9w/qx7+pd\n-----END CERTIFICATE-----',
47
+ id: 4,
48
+ organization_id: 4,
49
+ organization: {
50
+ name: 'ISS',
51
+ label: 'ISS',
52
+ id: 4,
53
+ },
54
+ created_at: '2021-10-28 12:14:10 -0400',
55
+ updated_at: '2021-10-28 16:25:06 -0400',
56
+ gpg_key_products: [],
57
+ gpg_key_repos: [],
58
+ ssl_ca_products: [],
59
+ ssl_ca_root_repos: [],
60
+ ssl_client_products: [],
61
+ ssl_client_root_repos: [],
62
+ ssl_key_products: [],
63
+ ssl_key_root_repos: [],
64
+ permissions: {
65
+ view_content_credenials: true,
66
+ edit_content_credenials: true,
67
+ destroy_content_credenials: true,
68
+ },
69
+ },
70
+ ],
71
+ });
72
+
73
+ export default contentCredentialsResponse;
@@ -65,7 +65,7 @@ const CopyContentViewForm = ({ cvId, setModalOpen }) => {
65
65
  <Button
66
66
  aria-label="copy_content_view"
67
67
  variant="primary"
68
- isDisabled={saving}
68
+ isDisabled={name.length <= 2 || saving}
69
69
  type="submit"
70
70
  >
71
71
  {__('Copy content view')}
@@ -32,7 +32,7 @@ export const LabelComponent = () => (
32
32
 
33
33
  export const LabelDependencies = () => (
34
34
  <Flex>
35
- <FlexItem spacer={{ default: 'spacerSm' }}>{__('Solve Dependencies')}</FlexItem>
35
+ <FlexItem spacer={{ default: 'spacerSm' }}>{__('Solve dependencies')}</FlexItem>
36
36
  <FlexItem>
37
37
  {HelpToolTip(dependenciesHelpText)}
38
38
  </FlexItem>
@@ -41,7 +41,7 @@ export const LabelDependencies = () => (
41
41
 
42
42
  export const LabelAutoPublish = () => (
43
43
  <Flex>
44
- <FlexItem spacer={{ default: 'spacerSm' }}>{__('Auto Publish')}</FlexItem>
44
+ <FlexItem spacer={{ default: 'spacerSm' }}>{__('Auto publish')}</FlexItem>
45
45
  <FlexItem>
46
46
  {HelpToolTip(autoPublishHelpText)}
47
47
  </FlexItem>
@@ -50,7 +50,7 @@ export const LabelAutoPublish = () => (
50
50
 
51
51
  export const LabelImportOnly = () => (
52
52
  <Flex>
53
- <FlexItem spacer={{ default: 'spacerSm' }}>{__('Import Only')}</FlexItem>
53
+ <FlexItem spacer={{ default: 'spacerSm' }}>{__('Import only')}</FlexItem>
54
54
  <FlexItem>
55
55
  {HelpToolTip(importOnlyHelpText)}
56
56
  </FlexItem>
@@ -10,6 +10,7 @@ import { createContentView } from '../ContentViewsActions';
10
10
  import { selectCreateContentViews, selectCreateContentViewStatus, selectCreateContentViewError } from './ContentViewCreateSelectors';
11
11
  import { LabelDependencies, LabelAutoPublish, LabelImportOnly } from './ContentViewFormComponents';
12
12
  import ContentViewIcon from '../components/ContentViewIcon';
13
+ import './CreateContentViewForm.scss';
13
14
 
14
15
  const CreateContentViewForm = ({ setModalOpen }) => {
15
16
  const dispatch = useDispatch();
@@ -63,6 +64,8 @@ const CreateContentViewForm = ({ setModalOpen }) => {
63
64
  return (<Redirect to={`/content_views/${id}`} />);
64
65
  }
65
66
 
67
+ const submitDisabled = name.length <= 2 || label.length <= 2 || saving;
68
+
66
69
  return (
67
70
  <Form onSubmit={(e) => {
68
71
  e.preventDefault();
@@ -106,6 +109,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
106
109
  <Grid hasGutter>
107
110
  <GridItem span={6}>
108
111
  <Tile
112
+ style={{ height: '100%' }}
109
113
  isStacked
110
114
  aria-label="component_tile"
111
115
  icon={<ContentViewIcon composite={false} />}
@@ -114,11 +118,12 @@ const CreateContentViewForm = ({ setModalOpen }) => {
114
118
  onClick={() => { setComponent(true); setComposite(false); }}
115
119
  isSelected={component}
116
120
  >
117
- {__('Single content view consisting of repositories')}
121
+ {__('Single content view consisting of e.g. repositories')}
118
122
  </Tile>
119
123
  </GridItem>
120
124
  <GridItem span={6}>
121
125
  <Tile
126
+ style={{ height: '100%' }}
122
127
  isStacked
123
128
  aria-label="composite_tile"
124
129
  icon={<ContentViewIcon composite />}
@@ -166,7 +171,7 @@ const CreateContentViewForm = ({ setModalOpen }) => {
166
171
  <Button
167
172
  aria-label="create_content_view"
168
173
  variant="primary"
169
- isDisabled={saving}
174
+ isDisabled={submitDisabled}
170
175
  type="submit"
171
176
  >
172
177
  {__('Create content view')}
@@ -0,0 +1,7 @@
1
+ .pf-c-tile__title {
2
+ font-size: 16px;
3
+ }
4
+
5
+ .pf-c-tile__icon {
6
+ min-height: 38px;
7
+ }
@@ -69,9 +69,9 @@ test('Displays dependent fields correctly', () => {
69
69
  expect(getByText('Label')).toBeInTheDocument();
70
70
  expect(getByText('Composite content view')).toBeInTheDocument();
71
71
  expect(getByText('Component content view')).toBeInTheDocument();
72
- expect(getByText('Solve Dependencies')).toBeInTheDocument();
73
- expect(queryByText('Auto Publish')).not.toBeInTheDocument();
74
- expect(getByText('Import Only')).toBeInTheDocument();
72
+ expect(getByText('Solve dependencies')).toBeInTheDocument();
73
+ expect(queryByText('Auto publish')).not.toBeInTheDocument();
74
+ expect(getByText('Import only')).toBeInTheDocument();
75
75
 
76
76
  // label auto_set
77
77
  fireEvent.change(getByLabelText('input_name'), { target: { value: '123 2123' } });
@@ -79,13 +79,13 @@ test('Displays dependent fields correctly', () => {
79
79
 
80
80
  // display Auto Publish when Composite CV
81
81
  fireEvent.click(getByLabelText('composite_tile'));
82
- expect(queryByText('Solve Dependencies')).not.toBeInTheDocument();
83
- expect(getByText('Auto Publish')).toBeInTheDocument();
84
- expect(queryByText('Import Only')).not.toBeInTheDocument();
82
+ expect(queryByText('Solve dependencies')).not.toBeInTheDocument();
83
+ expect(getByText('Auto publish')).toBeInTheDocument();
84
+ expect(queryByText('Import only')).not.toBeInTheDocument();
85
85
 
86
86
  // display Solve Dependencies when Component CV
87
87
  fireEvent.click(getByLabelText('component_tile'));
88
- expect(getByText('Solve Dependencies')).toBeInTheDocument();
89
- expect(queryByText('Auto Publish')).not.toBeInTheDocument();
90
- expect(getByText('Import Only')).toBeInTheDocument();
88
+ expect(getByText('Solve dependencies')).toBeInTheDocument();
89
+ expect(queryByText('Auto publish')).not.toBeInTheDocument();
90
+ expect(getByText('Import only')).toBeInTheDocument();
91
91
  });