katello 3.7.0 → 3.7.1
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/katello/common/index.js +1 -0
- data/app/assets/javascripts/katello/sync_management/index.js +1 -0
- data/app/controllers/katello/api/v2/host_packages_controller.rb +1 -5
- data/app/controllers/katello/remote_execution_controller.rb +6 -6
- data/app/helpers/katello/hosts_and_hostgroups_helper.rb +37 -9
- data/app/lib/actions/katello/host/hypervisors_update.rb +82 -22
- data/app/lib/actions/pulp/consumer/abstract_content_action.rb +12 -0
- data/app/lib/actions/pulp/consumer/content_install.rb +1 -1
- data/app/lib/actions/pulp/consumer/content_uninstall.rb +1 -1
- data/app/lib/actions/pulp/consumer/content_update.rb +1 -1
- data/app/models/katello/concerns/subscription_facet_host_extensions.rb +1 -1
- data/app/models/katello/content_view.rb +12 -4
- data/app/models/katello/glue/candlepin/pool.rb +11 -11
- data/app/models/katello/host/content_facet.rb +2 -1
- data/app/models/katello/rpm.rb +14 -6
- data/app/models/katello/subscription_status.rb +1 -1
- data/app/services/katello/candlepin/consumer.rb +8 -0
- data/app/views/overrides/activation_keys/_host_environment_select.html.erb +2 -3
- data/config/routes.rb +1 -0
- data/db/migrate/20180612163403_add_foreign_key_to_hypervisor_id.rb +3 -0
- data/db/seeds.d/75-job_templates.rb +5 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-repository-sets-modal.controller.js +4 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/content-hosts-bulk-subscriptions-modal.controller.js +4 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/content/content-host-packages-installed.controller.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/discovery/views/discovery-create.html +1 -1
- data/engines/bastion_katello/app/assets/stylesheets/bastion_katello/bastion_katello.scss +5 -0
- data/lib/katello/tasks/clean_backend_objects.rake +12 -3
- data/lib/katello/version.rb +1 -1
- data/package.json +10 -7
- data/webpack/__mocks__/foremanReact/redux.js +3 -0
- data/webpack/__mocks__/foremanReact/redux/actions/toasts.js +2 -0
- data/webpack/components/Search/Search.test.js +3 -1
- data/webpack/components/SelectOrg/SelectOrg.scss +3 -0
- data/webpack/components/SelectOrg/SelectOrgAction.js +41 -0
- data/webpack/components/SelectOrg/SelectOrgReducer.js +33 -0
- data/webpack/components/SelectOrg/SetOrganization.js +116 -0
- data/webpack/components/WithOrganization/withOrganization.js +28 -0
- data/webpack/containers/Application/config.js +9 -2
- data/webpack/containers/Application/index.js +4 -2
- data/webpack/global_test_setup.js +6 -0
- data/webpack/helpers/caret.js +6 -0
- data/webpack/move_to_foreman/components/common/{emptyState → EmptyState}/index.js +16 -3
- data/webpack/move_to_foreman/components/common/table/components/Table.js +1 -1
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/CollapseSubscriptionGroupButton.test.js.snap +2 -2
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionCell.test.js.snap +1 -1
- data/webpack/move_to_foreman/components/common/table/components/__snapshots__/TableSelectionHeaderCell.test.js.snap +1 -1
- data/webpack/move_to_pf/LoadingState/LoadingState.js +27 -14
- data/webpack/move_to_pf/LoadingState/LoadingState.test.js +8 -4
- data/webpack/move_to_pf/Select/Select.js +40 -0
- data/webpack/move_to_pf/react-bootstrap-select/index.js +12 -1
- data/webpack/redux/actions/RedHatRepositories/enabled.js +0 -1
- data/webpack/redux/actions/RedHatRepositories/helpers.js +5 -5
- data/webpack/redux/consts.js +6 -0
- data/webpack/redux/reducers/index.js +2 -0
- data/webpack/scenes/Products/ProductActions.js +24 -0
- data/webpack/scenes/Products/ProductConstants.js +3 -0
- data/webpack/scenes/Products/__tests__/ProductActions.test.js +40 -0
- data/webpack/scenes/Products/__tests__/products.fixtures.js +90 -0
- data/webpack/scenes/RedHatRepositories/components/EnabledRepository.js +14 -23
- data/webpack/scenes/RedHatRepositories/components/EnabledRepositoryContent.js +34 -0
- data/webpack/scenes/RedHatRepositories/components/RepositorySetRepository.js +1 -1
- data/webpack/scenes/RedHatRepositories/components/SearchBar.js +1 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/EnabledRepository.test.js +36 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/EnabledRepositoryContent.test.js +27 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/EnabledRepository.test.js.snap +25 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/EnabledRepositoryContent.test.js.snap +47 -0
- data/webpack/scenes/RedHatRepositories/components/__tests__/__snapshots__/RecommendedRepositorySetsToggler.test.js.snap +3 -1
- data/webpack/scenes/RedHatRepositories/index.js +7 -3
- data/webpack/scenes/RedHatRepositories/index.scss +1 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailActions.js +1 -1
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailEnabledProducts.js +54 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailProduct.js +29 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetailReducer.js +29 -0
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.js +67 -22
- data/webpack/scenes/Subscriptions/Details/SubscriptionDetails.scss +9 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailEnabledProducts.test.js +18 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetailProduct.test.js +13 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/SubscriptionDetails.test.js +6 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailEnabledProducts.test.js.snap +45 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetailProduct.test.js.snap +67 -0
- data/webpack/scenes/Subscriptions/Details/__tests__/__snapshots__/SubscriptionDetails.test.js.snap +497 -410
- data/webpack/scenes/Subscriptions/Details/__tests__/subscriptionDetails.fixtures.js +4 -0
- data/webpack/scenes/Subscriptions/Details/index.js +3 -1
- data/webpack/scenes/Subscriptions/Manifest/ManageManifestModal.js +78 -34
- data/webpack/scenes/Subscriptions/Manifest/ManifestHistoryReducer.js +8 -0
- data/webpack/scenes/Subscriptions/Manifest/__tests__/ManageManifestModal.test.js +3 -0
- data/webpack/scenes/Subscriptions/Manifest/__tests__/__snapshots__/ManageManifestModal.test.js.snap +34 -7
- data/webpack/scenes/Subscriptions/Manifest/index.js +1 -0
- data/webpack/scenes/Subscriptions/SubscriptionConstants.js +1 -0
- data/webpack/scenes/Subscriptions/SubscriptionHelpers.js +3 -0
- data/webpack/scenes/Subscriptions/SubscriptionReducer.js +6 -2
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +31 -36
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/UpstreamSubscriptionsPage.js +2 -7
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/UpstreamSubscriptionsPage.test.js +1 -1
- data/webpack/scenes/Subscriptions/UpstreamSubscriptions/__tests__/__snapshots__/UpstreamSubscriptionsPage.test.js.snap +3 -6
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +2 -0
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +14 -2
- data/webpack/scenes/Subscriptions/__tests__/subscriptions.fixtures.js +4 -3
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/EntitlementsInlineEditFormatter.js +8 -5
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTable.js +29 -19
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableHelpers.js +9 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +2 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/EntitlementsInlineEditFormatter.test.js +110 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/SubscriptionsTable.test.js +15 -3
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/EntitlementsInlineEditFormatter.test.js.snap +228 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +54 -21
- data/webpack/scenes/Subscriptions/index.js +1 -0
- data/webpack/scenes/Tasks/helpers.js +52 -0
- data/webpack/services/api/index.js +17 -1
- data/webpack/test_setup.js +2 -0
- metadata +31 -4
- data/config/katello.yaml +0 -89
@@ -38,7 +38,7 @@ module Katello
|
|
38
38
|
|
39
39
|
def to_status(options = {})
|
40
40
|
return UNKNOWN unless host.subscription_facet.try(:uuid)
|
41
|
-
status_override = 'unsubscribed_hypervisor' if host.subscription_facet.hypervisor && host.subscription_facet.candlepin_consumer.entitlements
|
41
|
+
status_override = 'unsubscribed_hypervisor' if host.subscription_facet.hypervisor && !host.subscription_facet.candlepin_consumer.entitlements?
|
42
42
|
status_override ||= options.fetch(:status_override, nil)
|
43
43
|
status = status_override || Katello::Candlepin::Consumer.new(host.subscription_facet.uuid, host.organization.label).entitlement_status
|
44
44
|
|
@@ -120,6 +120,14 @@ module Katello
|
|
120
120
|
self.class.friendly_compliance_reasons(Resources::Candlepin::Consumer.compliance(uuid)['reasons'])
|
121
121
|
end
|
122
122
|
|
123
|
+
def entitlements?
|
124
|
+
# use cahced consumer_attributes if possible
|
125
|
+
count = @consumer_attributes.try(:[], 'entitlementCount')
|
126
|
+
return count > 0 if count
|
127
|
+
|
128
|
+
!entitlements.empty?
|
129
|
+
end
|
130
|
+
|
123
131
|
def self.friendly_compliance_reasons(candlepin_reasons)
|
124
132
|
candlepin_reasons.map do |reason|
|
125
133
|
product_name = reason['productName'] || reason['attributes']['name']
|
@@ -35,12 +35,11 @@ end %>
|
|
35
35
|
<% cs_select_name = using_hostgroups_page? ? 'hostgroup[content_source_id]' : 'host[content_facet_attributes][content_source_id]' %>
|
36
36
|
<% cs_select_attr = using_hostgroups_page? ? 'content_source' : 'content_facet.content_source' %>
|
37
37
|
|
38
|
-
<% proxies = accessible_content_proxies(@host || @hostgroup) %>
|
39
38
|
<%= field(f, cs_select_attr, {:label => _("Content Source")}) do
|
40
39
|
if using_hostgroups_page?
|
41
|
-
select_tag cs_select_id,
|
40
|
+
select_tag cs_select_id, content_source_options(@hostgroup, :selected_host_group => @hostgroup.hostgroup, :include_blank => blank_or_inherit_with_id(f, :content_source)), :data => {"spinner_path" => spinner_path},
|
42
41
|
:class => 'form-control', :name => cs_select_name, include_blank: true
|
43
42
|
else
|
44
|
-
select_tag cs_select_id,
|
43
|
+
select_tag cs_select_id, content_source_options(@host, :selected_host_group => @host.hostgroup, :include_blank => blank_or_inherit_with_id(f, :content_source)), :data => {"spinner_path" => spinner_path}, :class => 'form-control', :name => cs_select_name, include_blank: true
|
45
44
|
end
|
46
45
|
end %>
|
data/config/routes.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
1
|
class AddForeignKeyToHypervisorId < ActiveRecord::Migration[5.1]
|
2
2
|
def up
|
3
|
+
# Update all pools that have a hypervisor reference that's not a host before we add the FK
|
4
|
+
::Katello::Pool.where.not(hypervisor_id: nil).where.not(hypervisor_id: Host::Managed.all).update_all(hypervisor_id: nil)
|
5
|
+
|
3
6
|
add_foreign_key(:katello_pools, :hosts,
|
4
7
|
:name => 'katello_pools_hypervisor_fk', :column => 'hypervisor_id')
|
5
8
|
end
|
@@ -7,10 +7,13 @@ if Katello.with_remote_execution?
|
|
7
7
|
sync = !Rails.env.test? && Setting[:remote_execution_sync_templates]
|
8
8
|
# import! was renamed to import_raw! around 1.3.1
|
9
9
|
if JobTemplate.respond_to?('import_raw!')
|
10
|
-
JobTemplate.import_raw!(File.read(template), :default => true, :locked => true, :update => sync)
|
10
|
+
template = JobTemplate.import_raw!(File.read(template), :default => true, :locked => true, :update => sync)
|
11
11
|
else
|
12
|
-
JobTemplate.import!(File.read(template), :default => true, :locked => true, :update => sync)
|
12
|
+
template = JobTemplate.import!(File.read(template), :default => true, :locked => true, :update => sync)
|
13
13
|
end
|
14
|
+
|
15
|
+
template.organizations << Organization.unscoped.all if template && template.organizations.empty?
|
16
|
+
template.locations << Location.unscoped.all if template && template.locations.empty?
|
14
17
|
end
|
15
18
|
end
|
16
19
|
end
|
@@ -28,14 +28,15 @@ angular.module('Bastion.content-hosts').controller('ContentHostsBulkRepositorySe
|
|
28
28
|
nutupaneParams = {
|
29
29
|
'organization_id': CurrentOrganization,
|
30
30
|
'offset': 0,
|
31
|
-
'sort_by': 'name',
|
32
|
-
'sort_order': 'ASC',
|
33
31
|
'paged': true
|
34
32
|
};
|
35
33
|
|
36
|
-
nutupane = new Nutupane(RepositorySet, nutupaneParams,
|
34
|
+
nutupane = new Nutupane(RepositorySet, nutupaneParams,
|
35
|
+
'queryPaged', {disableAutoLoad: true});
|
37
36
|
$scope.controllerName = 'katello_repository_sets';
|
38
37
|
nutupane.masterOnly = true;
|
38
|
+
nutupane.setSearchKey('repoSetsSearch');
|
39
|
+
nutupane.load();
|
39
40
|
|
40
41
|
$scope.table = nutupane.table;
|
41
42
|
|
@@ -44,11 +44,14 @@ angular.module('Bastion.content-hosts').controller('ContentHostsBulkSubscription
|
|
44
44
|
});
|
45
45
|
};
|
46
46
|
|
47
|
-
|
47
|
+
|
48
|
+
$scope.contentNutupane = new Nutupane(Subscription, params,
|
49
|
+
'queryPaged', {disableAutoLoad: true});
|
48
50
|
$scope.controllerName = 'katello_subscriptions';
|
49
51
|
$scope.table = $scope.contentNutupane.table;
|
50
52
|
$scope.contentNutupane.setSearchKey('subscriptionSearch');
|
51
53
|
$scope.contentNutupane.masterOnly = true;
|
54
|
+
$scope.contentNutupane.load();
|
52
55
|
$scope.groupedSubscriptions = {};
|
53
56
|
|
54
57
|
$scope.$watch('table.rows', function (rows) {
|
@@ -18,7 +18,7 @@ angular.module('Bastion.content-hosts').controller('ContentHostPackagesInstalled
|
|
18
18
|
var packagesNutupane;
|
19
19
|
|
20
20
|
$scope.removeSelectedPackages = function () {
|
21
|
-
var selected = $scope.table.getSelected();
|
21
|
+
var selected = _.map($scope.table.getSelected(), 'name');
|
22
22
|
|
23
23
|
if (!$scope.working) {
|
24
24
|
$scope.working = true;
|
@@ -44,7 +44,7 @@
|
|
44
44
|
|
45
45
|
<div bst-form-group ng-show="createRepoChoices.newProduct === 'true' && contentCredentials.length !== 0"
|
46
46
|
label="{{ 'GPG Key' | translate }}">
|
47
|
-
<select class="form-control" ng-model="createRepoChoices.product.
|
47
|
+
<select class="form-control" ng-model="createRepoChoices.product.gpg_key_id"
|
48
48
|
ng-options="content_credential.id as content_credential.name for content_credential in contentCredentials"/>
|
49
49
|
</div>
|
50
50
|
|
@@ -42,17 +42,17 @@ namespace :katello do
|
|
42
42
|
def cleanup_hosts(cleaner)
|
43
43
|
cleaner.hosts_with_nil_facets.each do |host|
|
44
44
|
print "Host #{host.id} #{host.name} is partially missing subscription information. Un-registering\n"
|
45
|
-
execute("Failed to delete host") { Katello::RegistrationManager.unregister_host(host) }
|
45
|
+
execute("Failed to delete host") { Katello::RegistrationManager.unregister_host(host, host_unregister_options(host)) }
|
46
46
|
end
|
47
47
|
|
48
48
|
cleaner.hosts_with_no_subscriptions.each do |host|
|
49
49
|
print "Host #{host.id} #{host.name} #{host.subscription_facet.try(:uuid)} is partially missing subscription information. Un-registering\n"
|
50
|
-
execute("Failed to delete host") { Katello::RegistrationManager.unregister_host(host) }
|
50
|
+
execute("Failed to delete host") { Katello::RegistrationManager.unregister_host(host, host_unregister_options(host)) }
|
51
51
|
end
|
52
52
|
|
53
53
|
cleaner.hosts_with_no_content.each do |host|
|
54
54
|
print "Host #{host.id} #{host.name} #{host.content_facet.try(:uuid)} is partially missing content information. Un-registering\n"
|
55
|
-
execute("Failed to delete host") { Katello::RegistrationManager.unregister_host(host) }
|
55
|
+
execute("Failed to delete host") { Katello::RegistrationManager.unregister_host(host, host_unregister_options(host)) }
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -72,6 +72,15 @@ namespace :katello do
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
def host_unregister_options(host)
|
76
|
+
if host.managed? || host.compute_resource
|
77
|
+
print "Leaving provisioning record for #{host.name} in place, it is either managed or assigned to a compute resource."
|
78
|
+
{:unregistering => true}
|
79
|
+
else
|
80
|
+
{}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
75
84
|
# rubocop:disable HandleExceptions
|
76
85
|
def execute(error_msg)
|
77
86
|
if ENV['COMMIT'] == 'true'
|
data/lib/katello/version.rb
CHANGED
data/package.json
CHANGED
@@ -9,7 +9,9 @@
|
|
9
9
|
"test:current": "jest webpack --watch",
|
10
10
|
"format": "prettier --single-quote --trailing-comma es5 --write 'webpack/**/*.js'",
|
11
11
|
"build": "npm run format && npm run lint",
|
12
|
-
"lint": "eslint
|
12
|
+
"lint": "eslint webpack/ || exit 0",
|
13
|
+
"lint:fix": "eslint --fix webpack/ || exit 0",
|
14
|
+
"lint:test": "npm run lint && npm test"
|
13
15
|
},
|
14
16
|
"repository": {
|
15
17
|
"type": "git",
|
@@ -22,11 +24,11 @@
|
|
22
24
|
"@storybook/react": "^3.2.17",
|
23
25
|
"@storybook/storybook-deployer": "^2.0.0",
|
24
26
|
"babel-core": "^6.26.3",
|
25
|
-
"babel-jest": "^
|
27
|
+
"babel-jest": "^23.4.0",
|
26
28
|
"babel-plugin-transform-class-properties": "^6.24.1",
|
27
29
|
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
28
|
-
"babel-preset-env": "^1.6.0",
|
29
30
|
"babel-polyfill": "^6.26.0",
|
31
|
+
"babel-preset-env": "^1.6.0",
|
30
32
|
"babel-preset-react": "^6.24.1",
|
31
33
|
"enzyme": "^3.2.0",
|
32
34
|
"enzyme-adapter-react-16": "^1.1.0",
|
@@ -34,11 +36,11 @@
|
|
34
36
|
"eslint": "^4.8.0",
|
35
37
|
"eslint-config-airbnb": "^16.0.0",
|
36
38
|
"eslint-plugin-import": "^2.7.0",
|
37
|
-
"eslint-plugin-jest": "^21.
|
39
|
+
"eslint-plugin-jest": "^21.18.0",
|
38
40
|
"eslint-plugin-jsx-a11y": "^6.0.2",
|
39
41
|
"eslint-plugin-react": "^7.4.0",
|
40
42
|
"identity-obj-proxy": "^3.0.0",
|
41
|
-
"jest": "^
|
43
|
+
"jest": "^23.4.1",
|
42
44
|
"prettier": "^1.7.4",
|
43
45
|
"react-test-renderer": "^16.0.0",
|
44
46
|
"redux-mock-store": "^1.3.0",
|
@@ -53,10 +55,10 @@
|
|
53
55
|
"jed": "^1.1.1",
|
54
56
|
"lodash": "^4.17.5",
|
55
57
|
"patternfly": "^3.41.1",
|
56
|
-
"patternfly-react": "2.5.1",
|
58
|
+
"patternfly-react": "^2.5.1",
|
57
59
|
"prop-types": "^15.6.0",
|
58
60
|
"react": "^16.3.1",
|
59
|
-
"react-bootstrap": "^0.
|
61
|
+
"react-bootstrap": "^0.32.1",
|
60
62
|
"react-bootstrap-tooltip-button": "^1.0.6",
|
61
63
|
"react-dom": "^16.3.1",
|
62
64
|
"react-ellipsis-with-tooltip": "^1.0.7",
|
@@ -72,6 +74,7 @@
|
|
72
74
|
"raf/polyfill",
|
73
75
|
"./webpack/test_setup.js"
|
74
76
|
],
|
77
|
+
"setupTestFrameworkScriptFile": "./webpack/global_test_setup.js",
|
75
78
|
"testPathIgnorePatterns": [
|
76
79
|
"/node_modules/",
|
77
80
|
"<rootDir>/foreman/",
|
@@ -1,17 +1,19 @@
|
|
1
1
|
import React from 'react';
|
2
2
|
import { shallow } from 'enzyme';
|
3
3
|
import toJson from 'enzyme-to-json';
|
4
|
+
import { mock as mockApi } from '../../mockRequest';
|
4
5
|
|
5
6
|
import Search from '../Search';
|
6
7
|
|
7
8
|
describe('Search component', () => {
|
8
9
|
const getBaseProps = () => ({
|
9
10
|
onSearch: () => {},
|
10
|
-
getAutoCompleteParams: () => ({}),
|
11
|
+
getAutoCompleteParams: () => ({ endpoint: '/fake' }),
|
11
12
|
});
|
12
13
|
|
13
14
|
describe('rendering', () => {
|
14
15
|
it('renders correctly', () => {
|
16
|
+
mockApi.onGet('/katello/api/v2/fake').reply(200, []);
|
15
17
|
const component = shallow(<Search {...getBaseProps()} />);
|
16
18
|
|
17
19
|
expect(toJson(component)).toMatchSnapshot();
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { foremanApi, foremanEndpoint } from '../../services/api';
|
2
|
+
import {
|
3
|
+
GET_ORGANIZATIONS_LIST_SUCCESS,
|
4
|
+
GET_ORGANIZATIONS_LIST_FAILURE,
|
5
|
+
CHANGE_CURRENT_ORGANIZATION_SUCCESS,
|
6
|
+
CHANGE_CURRENT_ORGANIZATION_FAILURE,
|
7
|
+
GET_ORGANIZATIONS_LIST_REQUEST,
|
8
|
+
} from '../../redux/consts';
|
9
|
+
|
10
|
+
export const getOrganiztionsList = () => (dispatch) => {
|
11
|
+
dispatch({ type: GET_ORGANIZATIONS_LIST_REQUEST });
|
12
|
+
foremanApi
|
13
|
+
.get('/organizations')
|
14
|
+
.then(({ data }) => {
|
15
|
+
dispatch({
|
16
|
+
type: GET_ORGANIZATIONS_LIST_SUCCESS,
|
17
|
+
payload: data,
|
18
|
+
});
|
19
|
+
})
|
20
|
+
.catch((result) => {
|
21
|
+
dispatch({
|
22
|
+
type: GET_ORGANIZATIONS_LIST_FAILURE,
|
23
|
+
payload: result,
|
24
|
+
});
|
25
|
+
});
|
26
|
+
};
|
27
|
+
|
28
|
+
export const changeCurrentOrgaziation = orgID => dispatch => foremanEndpoint
|
29
|
+
.get(`organizations/${orgID}/select`)
|
30
|
+
.then(() => {
|
31
|
+
dispatch({
|
32
|
+
type: CHANGE_CURRENT_ORGANIZATION_SUCCESS,
|
33
|
+
payload: orgID,
|
34
|
+
});
|
35
|
+
})
|
36
|
+
.catch(() => {
|
37
|
+
dispatch({
|
38
|
+
type: CHANGE_CURRENT_ORGANIZATION_FAILURE,
|
39
|
+
payload: orgID,
|
40
|
+
});
|
41
|
+
});
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import Immutable from 'seamless-immutable';
|
2
|
+
import {
|
3
|
+
GET_ORGANIZATIONS_LIST_SUCCESS,
|
4
|
+
GET_ORGANIZATIONS_LIST_REQUEST,
|
5
|
+
GET_ORGANIZATIONS_LIST_FAILURE,
|
6
|
+
CHANGE_CURRENT_ORGANIZATION_SUCCESS,
|
7
|
+
} from '../../redux/consts';
|
8
|
+
|
9
|
+
const initialState = Immutable({ loading: false });
|
10
|
+
export default (state = initialState, action) => {
|
11
|
+
const { payload } = action;
|
12
|
+
|
13
|
+
switch (action.type) {
|
14
|
+
case GET_ORGANIZATIONS_LIST_REQUEST:
|
15
|
+
return state.set('loading', true);
|
16
|
+
|
17
|
+
case GET_ORGANIZATIONS_LIST_SUCCESS:
|
18
|
+
return state
|
19
|
+
.set('list', payload.results)
|
20
|
+
.set('loading', false);
|
21
|
+
|
22
|
+
case CHANGE_CURRENT_ORGANIZATION_SUCCESS:
|
23
|
+
return state
|
24
|
+
.set('currentId', payload)
|
25
|
+
.set('loading', false);
|
26
|
+
|
27
|
+
case GET_ORGANIZATIONS_LIST_FAILURE:
|
28
|
+
return state
|
29
|
+
.set('error', payload);
|
30
|
+
default:
|
31
|
+
return state;
|
32
|
+
}
|
33
|
+
};
|
@@ -0,0 +1,116 @@
|
|
1
|
+
import React, { Component } from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { Form, Button } from 'patternfly-react';
|
4
|
+
import { withRouter } from 'react-router';
|
5
|
+
import { bindActionCreators } from 'redux';
|
6
|
+
import { connect } from 'react-redux';
|
7
|
+
import Select from '../../move_to_pf/Select/Select';
|
8
|
+
import * as SelectOrgActions from './SelectOrgAction';
|
9
|
+
import reducer from './SelectOrgReducer';
|
10
|
+
import { LoadingState } from '../../move_to_pf/LoadingState';
|
11
|
+
import './SelectOrg.scss';
|
12
|
+
|
13
|
+
class SetOrganization extends Component {
|
14
|
+
constructor(props) {
|
15
|
+
super(props);
|
16
|
+
this.onSelectItem = this.onSelectItem.bind(this);
|
17
|
+
this.onSend = this.onSend.bind(this);
|
18
|
+
this.state = { disabled: true };
|
19
|
+
}
|
20
|
+
|
21
|
+
componentDidMount() {
|
22
|
+
this.props.getOrganiztionsList();
|
23
|
+
}
|
24
|
+
|
25
|
+
onSelectItem(e) {
|
26
|
+
this.setState({
|
27
|
+
item: e.target.options[e.target.selectedIndex].text,
|
28
|
+
id: e.target.value,
|
29
|
+
disabled: false,
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
onSend() {
|
34
|
+
const {
|
35
|
+
history,
|
36
|
+
changeCurrentOrgaziation,
|
37
|
+
redirectPath,
|
38
|
+
} = this.props;
|
39
|
+
const { id, item } = this.state;
|
40
|
+
|
41
|
+
changeCurrentOrgaziation(`${id}-${item}`).then(() =>
|
42
|
+
history.push({
|
43
|
+
pathname: redirectPath,
|
44
|
+
state: { orgChanged: this.state.item },
|
45
|
+
}));
|
46
|
+
}
|
47
|
+
|
48
|
+
render() {
|
49
|
+
const {
|
50
|
+
list,
|
51
|
+
loading,
|
52
|
+
} = this.props;
|
53
|
+
|
54
|
+
return (
|
55
|
+
<div id="select-org" className="well col-sm-6 col-sm-offset-3">
|
56
|
+
<LoadingState loading={loading} loadingText={__('Loading')}>
|
57
|
+
<Form>
|
58
|
+
<h1 className="text-center">{__('Select an Organization')}</h1>
|
59
|
+
<p className="text-center">
|
60
|
+
{__('The page you are attempting to access requires selecting a specific organization.')}
|
61
|
+
</p>
|
62
|
+
<p className="text-center">
|
63
|
+
{__('Please select one from the list below and you will be redirected.')}
|
64
|
+
</p>
|
65
|
+
|
66
|
+
<div className="form-group">
|
67
|
+
<div className="col-sm-6 col-sm-offset-3">
|
68
|
+
<Select
|
69
|
+
value={this.state.id}
|
70
|
+
placeholder={__('Select an organization')}
|
71
|
+
id="organization"
|
72
|
+
name="organization"
|
73
|
+
className="form-control"
|
74
|
+
options={list}
|
75
|
+
onChange={this.onSelectItem}
|
76
|
+
/>
|
77
|
+
|
78
|
+
</div>
|
79
|
+
|
80
|
+
<div className="col-sm-3">
|
81
|
+
<Button disabled={this.state.disabled} className="btn btn-primary" onClick={this.onSend}>
|
82
|
+
{__('Select')}
|
83
|
+
</Button>
|
84
|
+
</div>
|
85
|
+
</div>
|
86
|
+
</Form>
|
87
|
+
</LoadingState>
|
88
|
+
</div>
|
89
|
+
);
|
90
|
+
}
|
91
|
+
}
|
92
|
+
|
93
|
+
|
94
|
+
SetOrganization.propTypes = {
|
95
|
+
list: PropTypes.arrayOf(PropTypes.object),
|
96
|
+
loading: PropTypes.bool.isRequired,
|
97
|
+
changeCurrentOrgaziation: PropTypes.func.isRequired,
|
98
|
+
history: PropTypes.shape({}).isRequired,
|
99
|
+
redirectPath: PropTypes.string.isRequired,
|
100
|
+
getOrganiztionsList: PropTypes.func.isRequired,
|
101
|
+
};
|
102
|
+
|
103
|
+
SetOrganization.defaultProps = {
|
104
|
+
list: [],
|
105
|
+
};
|
106
|
+
|
107
|
+
const mapStateToProps = state => ({
|
108
|
+
orgId: state.katello.setOrganization.currentId,
|
109
|
+
list: state.katello.setOrganization.list,
|
110
|
+
loading: state.katello.setOrganization.loading,
|
111
|
+
});
|
112
|
+
export const setOrganization = reducer;
|
113
|
+
const mapDispatchToProps = dispatch =>
|
114
|
+
bindActionCreators(SelectOrgActions, dispatch);
|
115
|
+
|
116
|
+
export default connect(mapStateToProps, mapDispatchToProps)(withRouter(SetOrganization));
|