katello 4.1.4 → 4.2.0.rc1
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/controllers/katello/api/rhsm/candlepin_proxies_controller.rb +2 -2
- data/app/controllers/katello/api/v2/content_credentials_controller.rb +3 -3
- data/app/controllers/katello/api/v2/content_uploads_controller.rb +3 -1
- data/app/controllers/katello/api/v2/content_view_components_controller.rb +33 -1
- data/app/controllers/katello/api/v2/content_views_controller.rb +12 -0
- data/app/controllers/katello/api/v2/host_errata_controller.rb +1 -1
- data/app/controllers/katello/api/v2/products_bulk_actions_controller.rb +1 -2
- data/app/controllers/katello/api/v2/products_controller.rb +4 -4
- data/app/controllers/katello/api/v2/repositories_bulk_actions_controller.rb +3 -11
- data/app/controllers/katello/api/v2/repositories_controller.rb +68 -47
- data/app/controllers/katello/api/v2/upstream_subscriptions_controller.rb +0 -28
- data/app/controllers/katello/concerns/api/v2/registration_commands_controller_extensions.rb +26 -5
- data/app/controllers/katello/concerns/api/v2/registration_controller_extensions.rb +26 -1
- data/app/lib/actions/candlepin/environment/destroy.rb +2 -0
- data/app/lib/actions/katello/agent_action.rb +2 -2
- data/app/lib/actions/katello/capsule_content/sync_capsule.rb +3 -2
- data/app/lib/actions/katello/{gpg_key → content_credential}/update.rb +1 -1
- data/app/lib/actions/katello/content_view/publish.rb +6 -1
- data/app/lib/actions/katello/content_view_version/create_repos.rb +1 -1
- data/app/lib/actions/katello/content_view_version/incremental_update.rb +0 -47
- data/app/lib/actions/katello/orphan_cleanup/remove_orphans.rb +1 -1
- data/app/lib/actions/katello/repository/clone_contents.rb +1 -7
- data/app/lib/actions/katello/repository/clone_to_environment.rb +1 -7
- data/app/lib/actions/katello/repository/create.rb +4 -8
- data/app/lib/actions/katello/repository/create_root.rb +1 -1
- data/app/lib/actions/katello/repository/destroy.rb +1 -3
- data/app/lib/actions/katello/repository/import_upload.rb +3 -2
- data/app/lib/actions/katello/repository/instance_update.rb +1 -1
- data/app/lib/actions/katello/repository/metadata_generate.rb +2 -8
- data/app/lib/actions/katello/repository/multi_clone_contents.rb +0 -1
- data/app/lib/actions/katello/repository/refresh_repository.rb +1 -4
- data/app/lib/actions/katello/repository/remove_content.rb +6 -4
- data/app/lib/actions/katello/repository/sync.rb +5 -25
- data/app/lib/actions/katello/repository/update.rb +1 -2
- data/app/lib/actions/katello/repository/update_http_proxy_details.rb +2 -5
- data/app/lib/actions/katello/repository/update_redhat_repository.rb +1 -1
- data/app/lib/actions/katello/repository/upload_files.rb +8 -3
- data/app/lib/actions/katello/repository/upload_package_group.rb +2 -11
- data/app/lib/actions/katello/repository/verify_checksum.rb +0 -1
- data/app/lib/actions/katello/repository_set/enable_repository.rb +1 -1
- data/app/lib/actions/pulp3/orchestration/repository/create.rb +2 -2
- data/app/lib/actions/pulp3/repository/create.rb +3 -4
- data/app/lib/actions/pulp3/repository/create_remote.rb +1 -6
- data/app/lib/actions/pulp3/repository/repair.rb +4 -0
- data/app/lib/katello/errors.rb +1 -0
- data/app/lib/katello/http_resource.rb +26 -73
- data/app/lib/katello/qpid/connection.rb +1 -3
- data/app/lib/katello/resources/candlepin/consumer.rb +1 -1
- data/app/lib/katello/resources/candlepin/environment.rb +2 -0
- data/app/lib/katello/resources/registry.rb +7 -20
- data/app/lib/katello/util/http_proxy.rb +0 -3
- data/app/lib/katello/validators/gpg_key_content_validator.rb +1 -1
- data/app/models/katello/authorization/{gpg_key.rb → content_credential.rb} +1 -1
- data/app/models/katello/authorization/product.rb +0 -4
- data/app/models/katello/concerns/host_managed_extensions.rb +2 -16
- data/app/models/katello/concerns/organization_extensions.rb +1 -1
- data/app/models/katello/concerns/pulp_database_unit.rb +13 -5
- data/app/models/katello/concerns/smart_proxy_extensions.rb +45 -41
- data/app/models/katello/{gpg_key.rb → content_credential.rb} +4 -4
- data/app/models/katello/content_view.rb +6 -1
- data/app/models/katello/generic_content_unit.rb +16 -0
- data/app/models/katello/glue/pulp/repos.rb +9 -25
- data/app/models/katello/kt_environment.rb +1 -1
- data/app/models/katello/product.rb +4 -4
- data/app/models/katello/repository.rb +13 -7
- data/app/models/katello/repository_generic_content_unit.rb +7 -0
- data/app/models/katello/root_repository.rb +38 -7
- data/app/models/setting/content.rb +5 -0
- data/app/services/cert/certs.rb +16 -8
- data/app/services/katello/applicability/applicable_content_helper.rb +1 -2
- data/app/services/katello/candlepin/consumer.rb +6 -0
- data/app/services/katello/component_view_presenter.rb +27 -0
- data/app/services/katello/pulp/repository.rb +1 -1
- data/app/services/katello/pulp/server.rb +2 -2
- data/app/services/katello/pulp3/api/core.rb +4 -0
- data/app/services/katello/pulp3/api/generic.rb +68 -0
- data/app/services/katello/pulp3/generic_content_unit.rb +29 -0
- data/app/services/katello/pulp3/pulp_content_unit.rb +5 -1
- data/app/services/katello/pulp3/repository/generic.rb +94 -0
- data/app/services/katello/pulp3/repository/yum.rb +4 -5
- data/app/services/katello/pulp3/repository.rb +27 -12
- data/app/services/katello/pulp3/repository_mirror.rb +2 -2
- data/app/services/katello/pulp3/smart_proxy_repository.rb +4 -4
- data/app/services/katello/registration_manager.rb +18 -7
- data/app/services/katello/repository_type.rb +59 -1
- data/app/services/katello/repository_type_manager.rb +116 -24
- data/app/views/katello/api/v2/content_views/base.json.rabl +4 -4
- data/app/views/katello/api/v2/repositories/show.json.rabl +1 -0
- data/app/views/smart_proxies/plugins/_pulpcore.html.erb +2 -5
- data/app/views/smart_proxies/pulp_status.html.erb +0 -7
- data/config/katello.yaml.example +0 -21
- data/config/routes/api/v2.rb +2 -1
- data/db/functions/deb_version_cmp_v01.sql +200 -0
- data/db/migrate/20171110082124_add_ssl_certs_to_products_and_repos.rb +5 -1
- data/db/migrate/20200402130013_add_repsoitory_docker_meta_tag_f_key.rb +3 -1
- data/db/migrate/20210624221630_katello_generic_content.rb +22 -0
- data/db/migrate/20210625095042_add_retain_package_versions_count.rb +9 -0
- data/db/migrate/20210628182553_add_generic_remote_options_to_root_repository.rb +5 -0
- data/db/migrate/20210714140440_remove_repo_export_permission.rb +5 -0
- data/db/migrate/20210721163730_change_gpg_keys_to_content_credentials.rb +8 -0
- data/db/migrate/20210728130748_create_function_deb_version_cmp.rb +12 -0
- data/db/seeds.d/111-upgrade_tasks.rb +1 -2
- data/engines/bastion/app/views/bastion/layouts/assets.html.erb +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/capsule-content/capsule-content.controller.js +7 -5
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-hosts/bulk/views/content-hosts-bulk-errata-modal.html +4 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/content-views/details/views/content-view-details.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/apply-errata.controller.js +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/errata/views/apply-errata-confirm.html +2 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/i18n/bastion_katello.pot +25 -33
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/bulk/views/products-bulk-advanced-sync-modal.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/product-repositories.controller.js +1 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.controller.js +10 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details-info.filter.js +9 -0
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/repository-details.controller.js +0 -2
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-advanced-sync-options.html +1 -25
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-details.html +1 -1
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/details/views/repository-info.html +31 -13
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/new/views/new-repository.html +11 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/products/details/repositories/views/product-repositories.html +0 -6
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/aggregate-task.factory.js +3 -3
- data/engines/bastion_katello/app/assets/javascripts/bastion_katello/tasks/task.factory.js +1 -1
- data/lib/katello/engine.rb +2 -4
- data/lib/katello/permission_creator.rb +6 -12
- data/lib/katello/plugin.rb +76 -80
- data/lib/katello/repository_types/python.rb +37 -0
- data/lib/katello/tasks/reimport.rake +0 -9
- data/lib/katello/tasks/repository.rake +3 -4
- data/lib/katello/version.rb +1 -1
- data/locale/action_names.rb +28 -29
- data/locale/bn/katello.po +699 -221
- data/locale/cs/katello.po +167 -59
- data/locale/de/katello.po +585 -352
- data/locale/en/katello.po +167 -59
- data/locale/es/katello.po +1388 -1189
- data/locale/fr/katello.po +1740 -1494
- data/locale/gu/katello.po +896 -416
- data/locale/hi/katello.po +892 -415
- data/locale/it/katello.po +371 -170
- data/locale/ja/katello.po +1657 -1439
- data/locale/katello.pot +933 -736
- data/locale/kn/katello.po +894 -416
- data/locale/ko/katello.po +515 -317
- data/locale/mr/katello.po +857 -415
- data/locale/or/katello.po +894 -416
- data/locale/pa/katello.po +874 -411
- data/locale/pt/katello.po +347 -154
- data/locale/pt_BR/katello.po +1398 -1215
- data/locale/ru/katello.po +671 -463
- data/locale/ta/katello.po +697 -221
- data/locale/te/katello.po +891 -415
- data/locale/zh_CN/katello.po +2029 -1845
- data/locale/zh_TW/katello.po +735 -407
- data/package.json +3 -1
- data/webpack/components/EditableTextInput/EditableTextInput.js +3 -3
- data/webpack/components/RoutedTabs/RoutedTabs.js +7 -8
- data/webpack/components/Table/TableWrapper.js +19 -11
- data/webpack/components/Table/helpers.js +1 -1
- data/webpack/components/extensions/HostDetails/Tabs/ContentTab.js +42 -0
- data/webpack/components/extensions/HostDetails/Tabs/SubscriptionTab.js +12 -0
- data/webpack/components/extensions/RegistrationCommands/__tests__/__snapshots__/ActivationKeys.test.js.snap +4 -0
- data/webpack/components/extensions/RegistrationCommands/fields/ActivationKeys.js +1 -1
- data/webpack/components/extensions/RegistrationCommands/index.js +1 -2
- data/webpack/components/pf3Table/formatters/selectionHeaderCellFormatter.js +2 -1
- data/webpack/fills_index.js +4 -1
- data/webpack/redux/actions/RedHatRepositories/helpers.js +2 -4
- data/webpack/redux/reducers/RedHatRepositories/enabled.js +4 -1
- data/webpack/scenes/ContentViews/ContentViewsActions.js +16 -1
- data/webpack/scenes/ContentViews/ContentViewsConstants.js +15 -0
- data/webpack/scenes/ContentViews/ContentViewsPage.js +12 -22
- data/webpack/scenes/ContentViews/Copy/CopyContentViewForm.js +4 -3
- data/webpack/scenes/ContentViews/Create/CreateContentViewForm.js +25 -14
- data/webpack/scenes/ContentViews/Create/CreateContentViewModal.js +4 -2
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js +153 -0
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentVersion.js +21 -10
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/ContentViewComponents.js +157 -19
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.fixtures.json +100 -108
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/contentViewComponents.test.js +140 -16
- data/webpack/scenes/ContentViews/Details/ComponentContentViews/__tests__/publishedContentViewDetails.fixtures.json +367 -0
- data/webpack/scenes/ContentViews/Details/ContentViewDetailActions.js +59 -6
- data/webpack/scenes/ContentViews/Details/ContentViewDetailSelectors.js +43 -0
- data/webpack/scenes/ContentViews/Details/ContentViewDetails.js +44 -13
- data/webpack/scenes/ContentViews/Details/Filters/Add/CVFilterAddModal.js +161 -0
- data/webpack/scenes/ContentViews/Details/Filters/Add/__tests__/cvFilterAdd.test.js +54 -0
- data/webpack/scenes/ContentViews/Details/Filters/Add/__tests__/cvFilterCreateResult.fixtures.json +124 -0
- data/webpack/scenes/ContentViews/Details/Filters/CVPackageGroupFilterContent.js +8 -6
- data/webpack/scenes/ContentViews/Details/Filters/CVRpmFilterContent.js +7 -6
- data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilterDetails.js +4 -3
- data/webpack/scenes/ContentViews/Details/Filters/ContentViewFilters.js +71 -12
- data/webpack/scenes/ContentViews/Details/Filters/__tests__/contentViewFilters.test.js +77 -0
- data/webpack/scenes/ContentViews/Details/Histories/ContentViewHistories.js +13 -12
- data/webpack/scenes/ContentViews/Details/Histories/__tests__/contentViewHistory.test.js +2 -2
- data/webpack/scenes/ContentViews/Details/Repositories/ContentViewRepositories.js +17 -14
- data/webpack/scenes/ContentViews/Details/Repositories/LastSync.js +3 -3
- data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewAddRemove.test.js +2 -2
- data/webpack/scenes/ContentViews/Details/Repositories/__tests__/contentViewDetailRepos.test.js +6 -2
- data/webpack/scenes/ContentViews/Details/Versions/ContentViewVersions.js +61 -20
- data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewTaskInProgressResponse.fixtures.json +71 -0
- data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewTaskResponse.fixtures.json +75 -0
- data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersions.test.js +86 -1
- data/webpack/scenes/ContentViews/Details/Versions/__tests__/contentViewVersionsWithTask.fixtures.json +713 -0
- data/webpack/scenes/ContentViews/Details/__tests__/contentViewDetail.test.js +3 -0
- data/webpack/scenes/ContentViews/Publish/CVPublishFinish.js +184 -0
- data/webpack/scenes/ContentViews/Publish/CVPublishForm.js +104 -0
- data/webpack/scenes/ContentViews/Publish/CVPublishReview.js +71 -0
- data/webpack/scenes/ContentViews/Publish/ContentViewPublishSelectors.js +17 -0
- data/webpack/scenes/ContentViews/Publish/PublishContentViewWizard.js +145 -0
- data/webpack/scenes/ContentViews/Publish/__tests__/environmentPaths.fixtures.json +352 -0
- data/webpack/scenes/ContentViews/Publish/__tests__/publishContentView.test.js +184 -0
- data/webpack/scenes/ContentViews/Publish/__tests__/publishResponse.fixture.json +69 -0
- data/webpack/scenes/ContentViews/Publish/cvPublishForm.scss +3 -0
- data/webpack/scenes/ContentViews/Table/ContentViewsTable.js +75 -48
- data/webpack/scenes/ContentViews/Table/tableDataGenerator.js +15 -2
- data/webpack/scenes/ContentViews/__tests__/contentViewPage.test.js +6 -10
- data/webpack/scenes/ContentViews/components/EnvironmentLabels.js +22 -10
- data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPathActions.js +12 -0
- data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPathConstants.js +2 -0
- data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPathSelectors.js +16 -0
- data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.js +72 -0
- data/webpack/scenes/ContentViews/components/EnvironmentPaths/EnvironmentPaths.scss +8 -0
- data/webpack/scenes/ContentViews/components/TaskPresenter/TaskPresenter.js +85 -0
- data/webpack/scenes/SmartProxy/SmartProxyContentTable.js +9 -8
- data/webpack/scenes/Subscriptions/SubscriptionsPage.js +4 -25
- data/webpack/scenes/Subscriptions/__tests__/SubscriptionsPage.test.js +0 -3
- data/webpack/scenes/Subscriptions/__tests__/__snapshots__/SubscriptionsPage.test.js.snap +3 -3
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/SubscriptionsTableSchema.js +4 -2
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/__tests__/__snapshots__/SubscriptionsTable.test.js.snap +24 -0
- data/webpack/scenes/Subscriptions/components/SubscriptionsTable/components/Table.js +4 -1
- data/webpack/scenes/Subscriptions/index.js +1 -4
- metadata +74 -39
- data/app/lib/actions/candlepin/environment/create.rb +0 -21
- data/app/lib/actions/foreman/environment/destroy.rb +0 -23
- data/app/lib/actions/katello/content_view/environment_create.rb +0 -21
- data/app/lib/actions/katello/repository/export.rb +0 -85
- data/app/lib/actions/katello/repository/purge_empty_content.rb +0 -16
- data/app/lib/actions/katello/repository/upload_errata.rb +0 -38
- data/app/lib/katello/util/proxy_uri.rb +0 -64
- data/app/models/katello/rhsm_fact_importer.rb +0 -20
- data/app/models/katello/rhsm_fact_name.rb +0 -17
- data/app/models/katello/rhsm_fact_parser.rb +0 -120
data/webpack/scenes/ContentViews/Details/ComponentContentViews/ComponentContentViewAddModal.js
ADDED
@@ -0,0 +1,153 @@
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { Modal, ModalVariant, FormSelect,
|
4
|
+
FormSelectOption, Checkbox, Form, FormGroup,
|
5
|
+
ActionGroup, Button } from '@patternfly/react-core';
|
6
|
+
import { useDispatch, useSelector, shallowEqual } from 'react-redux';
|
7
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
8
|
+
import { STATUS } from 'foremanReact/constants';
|
9
|
+
import { selectCVDetails,
|
10
|
+
selectCVDetailStatus,
|
11
|
+
selectCVDetailError } from '../../Details/ContentViewDetailSelectors';
|
12
|
+
import { addComponent } from '../ContentViewDetailActions';
|
13
|
+
|
14
|
+
const ComponentContentViewAddModal = ({
|
15
|
+
cvId, componentCvId, componentId, latest, show, setIsOpen,
|
16
|
+
}) => {
|
17
|
+
const dispatch = useDispatch();
|
18
|
+
const componentDetails = useSelector(
|
19
|
+
state => selectCVDetails(state, componentCvId),
|
20
|
+
shallowEqual,
|
21
|
+
);
|
22
|
+
const componentStatus = useSelector(
|
23
|
+
state => selectCVDetailStatus(state, componentCvId),
|
24
|
+
shallowEqual,
|
25
|
+
);
|
26
|
+
const componentError = useSelector(
|
27
|
+
state => selectCVDetailError(state, componentCvId),
|
28
|
+
shallowEqual,
|
29
|
+
);
|
30
|
+
const [cvName, setCvName] = useState('');
|
31
|
+
const [options, setOptions] = useState([]);
|
32
|
+
const [formLatest, setFormLatest] = useState(componentId ? latest : false);
|
33
|
+
const [selected, setSelected] = useState(null);
|
34
|
+
const versionsLoading = componentStatus === STATUS.PENDING;
|
35
|
+
|
36
|
+
useEffect(() => {
|
37
|
+
if (!versionsLoading && componentDetails) {
|
38
|
+
const { name, versions } = componentDetails;
|
39
|
+
const versionMutable = versions;
|
40
|
+
setCvName(name);
|
41
|
+
const opt = versionMutable.map(item => ({ value: item.id, label: __(`Version ${item.version}`) }));
|
42
|
+
setOptions([...opt].reverse());
|
43
|
+
setSelected(opt.slice(-1)[0].value);
|
44
|
+
}
|
45
|
+
}, [componentDetails, componentStatus, componentError, versionsLoading]);
|
46
|
+
|
47
|
+
const getAddParams = () => {
|
48
|
+
if (formLatest) {
|
49
|
+
return [{ latest: true, content_view_id: componentCvId }];
|
50
|
+
}
|
51
|
+
return [{ content_view_version_id: selected }];
|
52
|
+
};
|
53
|
+
|
54
|
+
const getUpdateParams = () => {
|
55
|
+
if (formLatest) {
|
56
|
+
return { id: componentId, latest: formLatest, compositeContentViewId: cvId };
|
57
|
+
}
|
58
|
+
return { id: componentId, compositeContentViewId: cvId, content_view_version_id: selected };
|
59
|
+
};
|
60
|
+
|
61
|
+
const updateLatest = (checked) => {
|
62
|
+
setFormLatest(checked);
|
63
|
+
if (checked) setSelected(options[0]);
|
64
|
+
};
|
65
|
+
|
66
|
+
const onSubmit = () => {
|
67
|
+
if (componentId) {
|
68
|
+
dispatch(addComponent({
|
69
|
+
compositeContentViewId: cvId,
|
70
|
+
components: getUpdateParams(),
|
71
|
+
}));
|
72
|
+
} else {
|
73
|
+
dispatch(addComponent({
|
74
|
+
compositeContentViewId: cvId,
|
75
|
+
components: getAddParams(),
|
76
|
+
}));
|
77
|
+
}
|
78
|
+
setIsOpen(false);
|
79
|
+
};
|
80
|
+
|
81
|
+
if (show && versionsLoading) return null;
|
82
|
+
|
83
|
+
return (
|
84
|
+
<Modal
|
85
|
+
title={componentId ? __('Update version') : __('Add component')}
|
86
|
+
variant={ModalVariant.small}
|
87
|
+
isOpen={show}
|
88
|
+
description={__(`Select available version of ${cvName} to use`)}
|
89
|
+
onClose={() => {
|
90
|
+
setIsOpen(false);
|
91
|
+
}}
|
92
|
+
appendTo={document.body}
|
93
|
+
>
|
94
|
+
<Form>
|
95
|
+
<FormGroup label={__('Version')} isRequired fieldId="version">
|
96
|
+
<FormSelect
|
97
|
+
value={selected}
|
98
|
+
isDisabled={formLatest || options.length === 1}
|
99
|
+
onChange={value => setSelected(value)}
|
100
|
+
id="horzontal-form-title"
|
101
|
+
name="horizontal-form-title"
|
102
|
+
aria-label="CvVersion"
|
103
|
+
>
|
104
|
+
{options.map((option, index) => (
|
105
|
+
// eslint-disable-next-line react/no-array-index-key
|
106
|
+
<FormSelectOption key={index} value={option.value} label={option.label} />
|
107
|
+
))}
|
108
|
+
</FormSelect>
|
109
|
+
</FormGroup>
|
110
|
+
<FormGroup fieldId="latest">
|
111
|
+
<Checkbox
|
112
|
+
style={{ marginTop: 0 }}
|
113
|
+
id="latest"
|
114
|
+
name="latest"
|
115
|
+
label={__('Always update to latest version')}
|
116
|
+
isChecked={formLatest}
|
117
|
+
onChange={checked => updateLatest(checked)}
|
118
|
+
/>
|
119
|
+
</FormGroup>
|
120
|
+
<ActionGroup>
|
121
|
+
<Button aria-label="add_component" variant="primary" onClick={() => onSubmit()}>{__('Submit')}</Button>
|
122
|
+
<Button variant="link" onClick={() => setIsOpen(false)}>{__('Cancel')}</Button>
|
123
|
+
</ActionGroup>
|
124
|
+
</Form>
|
125
|
+
</Modal>);
|
126
|
+
};
|
127
|
+
|
128
|
+
ComponentContentViewAddModal.propTypes = {
|
129
|
+
cvId: PropTypes.oneOfType([
|
130
|
+
PropTypes.number,
|
131
|
+
PropTypes.string,
|
132
|
+
]).isRequired,
|
133
|
+
componentCvId: PropTypes.oneOfType([
|
134
|
+
PropTypes.number,
|
135
|
+
PropTypes.string,
|
136
|
+
]).isRequired,
|
137
|
+
componentId: PropTypes.oneOfType([
|
138
|
+
PropTypes.number,
|
139
|
+
PropTypes.string,
|
140
|
+
]),
|
141
|
+
latest: PropTypes.bool,
|
142
|
+
show: PropTypes.bool,
|
143
|
+
setIsOpen: PropTypes.func,
|
144
|
+
};
|
145
|
+
|
146
|
+
ComponentContentViewAddModal.defaultProps = {
|
147
|
+
componentId: null,
|
148
|
+
latest: false,
|
149
|
+
show: false,
|
150
|
+
setIsOpen: null,
|
151
|
+
};
|
152
|
+
|
153
|
+
export default ComponentContentViewAddModal;
|
@@ -10,33 +10,44 @@ import {
|
|
10
10
|
} from '@patternfly/react-core';
|
11
11
|
|
12
12
|
const ComponentVersion = ({ componentCV }) => {
|
13
|
-
const {
|
13
|
+
const {
|
14
|
+
id: componentId, latest, content_view_version: cvVersion, content_view: cv,
|
15
|
+
} = componentCV;
|
14
16
|
const {
|
15
17
|
id,
|
16
18
|
latest_version: latestVersion,
|
17
19
|
} = cv;
|
18
|
-
const { version } = cvVersion;
|
20
|
+
const { version } = cvVersion || {};
|
21
|
+
const noVersionText = __('Not yet published');
|
19
22
|
const latestDescription = __('Latest (automatically updates)');
|
20
23
|
const manualVersionText = (latestVersion === version) ? __('Latest version') : __(`New version is available: Version ${latestVersion}`);
|
24
|
+
if (componentId) {
|
25
|
+
return (
|
26
|
+
<>
|
27
|
+
<Link to={urlBuilder('labs/content_views', '', id)}>{version ? `Version ${version}` : noVersionText}</Link>
|
28
|
+
<TextContent>
|
29
|
+
<Text component={TextVariants.small}>
|
30
|
+
{latest ? latestDescription : manualVersionText}
|
31
|
+
</Text>
|
32
|
+
</TextContent>
|
33
|
+
</>
|
34
|
+
);
|
35
|
+
}
|
21
36
|
return (
|
22
|
-
|
23
|
-
<Link to={urlBuilder('labs/content_views', '', id)}> Version {version}</Link>
|
24
|
-
<TextContent>
|
25
|
-
<Text component={TextVariants.small}>{latest ? latestDescription : manualVersionText}</Text>
|
26
|
-
</TextContent>
|
27
|
-
</>
|
37
|
+
<Link to={urlBuilder('labs/content_views', '', id)}>{latestVersion ? `Version ${latestVersion}` : noVersionText}</Link>
|
28
38
|
);
|
29
39
|
};
|
30
40
|
|
31
41
|
ComponentVersion.propTypes = {
|
32
42
|
componentCV: PropTypes.shape({
|
43
|
+
id: PropTypes.number,
|
33
44
|
latest: PropTypes.bool.isRequired,
|
34
45
|
content_view_version: PropTypes.shape({
|
35
|
-
version: PropTypes.string
|
46
|
+
version: PropTypes.string,
|
36
47
|
}),
|
37
48
|
content_view: PropTypes.shape({
|
38
49
|
id: PropTypes.number.isRequired,
|
39
|
-
latest_version: PropTypes.string
|
50
|
+
latest_version: PropTypes.string,
|
40
51
|
}),
|
41
52
|
}).isRequired,
|
42
53
|
};
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import React, { useState,
|
2
|
-
import
|
3
|
-
import {
|
4
|
-
|
5
|
-
} from '@patternfly/react-core';
|
1
|
+
import React, { useState, useCallback } from 'react';
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
3
|
+
import { useDispatch, useSelector } from 'react-redux';
|
4
|
+
import { Bullseye, Split, SplitItem, Button } from '@patternfly/react-core';
|
6
5
|
import { Link } from 'react-router-dom';
|
7
6
|
import { TableVariant, fitContent, TableText } from '@patternfly/react-table';
|
7
|
+
import { PencilAltIcon } from '@patternfly/react-icons';
|
8
8
|
import { STATUS } from 'foremanReact/constants';
|
9
9
|
import { translate as __ } from 'foremanReact/common/I18n';
|
10
10
|
import { urlBuilder } from 'foremanReact/common/urlHelpers';
|
@@ -16,21 +16,39 @@ import {
|
|
16
16
|
selectCVComponents,
|
17
17
|
selectCVComponentsStatus,
|
18
18
|
selectCVComponentsError,
|
19
|
+
selectCVComponentAddStatus,
|
20
|
+
selectCVComponentRemoveStatus,
|
19
21
|
} from '../ContentViewDetailSelectors';
|
20
|
-
import {
|
22
|
+
import getContentViewDetails, {
|
23
|
+
addComponent, getContentViewComponents,
|
24
|
+
removeComponent,
|
25
|
+
} from '../ContentViewDetailActions';
|
21
26
|
import AddedStatusLabel from '../../../../components/AddedStatusLabel';
|
22
27
|
import ComponentVersion from './ComponentVersion';
|
23
28
|
import ComponentEnvironments from './ComponentEnvironments';
|
24
29
|
import ContentViewIcon from '../../components/ContentViewIcon';
|
30
|
+
import { ADDED, ALL_STATUSES, NOT_ADDED } from '../../ContentViewsConstants';
|
31
|
+
import SelectableDropdown from '../../../../components/SelectableDropdown/SelectableDropdown';
|
32
|
+
import '../../../../components/EditableTextInput/editableTextInput.scss';
|
33
|
+
import ComponentContentViewAddModal from './ComponentContentViewAddModal';
|
25
34
|
|
26
35
|
const ContentViewComponents = ({ cvId, details }) => {
|
27
36
|
const response = useSelector(state => selectCVComponents(state, cvId));
|
28
37
|
const status = useSelector(state => selectCVComponentsStatus(state, cvId));
|
29
38
|
const error = useSelector(state => selectCVComponentsError(state, cvId));
|
30
|
-
|
39
|
+
const componentAddedStatus = useSelector(state => selectCVComponentAddStatus(state, cvId));
|
40
|
+
const componentRemovedStatus = useSelector(state => selectCVComponentRemoveStatus(state, cvId));
|
31
41
|
const [rows, setRows] = useState([]);
|
32
42
|
const [metadata, setMetadata] = useState({});
|
33
43
|
const [searchQuery, updateSearchQuery] = useState('');
|
44
|
+
const [statusSelected, setStatusSelected] = useState(ALL_STATUSES);
|
45
|
+
const [versionEditing, setVersionEditing] = useState(false);
|
46
|
+
const [compositeCvEditing, setCompositeCvEditing] = useState(null);
|
47
|
+
const [componentCvEditing, setComponentCvEditing] = useState(null);
|
48
|
+
const [componentLatest, setComponentLatest] = useState(false);
|
49
|
+
const [componentId, setComponentId] = useState(null);
|
50
|
+
const dispatch = useDispatch();
|
51
|
+
|
34
52
|
const columnHeaders = [
|
35
53
|
{ title: __('Type'), transforms: [fitContent] },
|
36
54
|
{ title: __('Name') },
|
@@ -41,12 +59,53 @@ const ContentViewComponents = ({ cvId, details }) => {
|
|
41
59
|
{ title: __('Description') },
|
42
60
|
];
|
43
61
|
const loading = status === STATUS.PENDING;
|
62
|
+
const addComponentsResolved = componentAddedStatus === STATUS.RESOLVED;
|
63
|
+
const removeComponentsResolved = componentRemovedStatus === STATUS.RESOLVED;
|
64
|
+
|
44
65
|
const { label } = details || {};
|
45
66
|
|
46
|
-
const
|
67
|
+
const bulkRemoveEnabled = () => rows.some(row => row.selected && row.added);
|
68
|
+
|
69
|
+
const onAdd = useCallback(({
|
70
|
+
componentCvId, published, added, latest,
|
71
|
+
}) => {
|
72
|
+
if (published) {
|
73
|
+
dispatch(getContentViewDetails(componentCvId));
|
74
|
+
setVersionEditing(true);
|
75
|
+
setCompositeCvEditing(cvId);
|
76
|
+
setComponentCvEditing(componentCvId);
|
77
|
+
setComponentLatest(latest);
|
78
|
+
setComponentId(added);
|
79
|
+
} else {
|
80
|
+
dispatch(addComponent({
|
81
|
+
compositeContentViewId: cvId,
|
82
|
+
components: [{ latest: true, content_view_id: componentCvId }],
|
83
|
+
}));
|
84
|
+
}
|
85
|
+
}, [cvId, dispatch]);
|
86
|
+
|
87
|
+
const removeBulk = () => {
|
88
|
+
const componentIds = [];
|
89
|
+
rows.forEach(row => row.selected && componentIds.push(row.added));
|
90
|
+
dispatch(removeComponent({
|
91
|
+
compositeContentViewId: cvId,
|
92
|
+
component_ids: componentIds,
|
93
|
+
}));
|
94
|
+
};
|
95
|
+
|
96
|
+
const onRemove = (componentIdToRemove) => {
|
97
|
+
dispatch(removeComponent({
|
98
|
+
compositeContentViewId: cvId,
|
99
|
+
component_ids: [componentIdToRemove],
|
100
|
+
}));
|
101
|
+
};
|
102
|
+
|
103
|
+
const buildRows = useCallback((results) => {
|
47
104
|
const newRows = [];
|
48
105
|
results.forEach((componentCV) => {
|
49
|
-
const {
|
106
|
+
const {
|
107
|
+
id: componentCvId, content_view: cv, content_view_version: cvVersion, latest,
|
108
|
+
} = componentCV;
|
50
109
|
const { environments, repositories } = cvVersion || {};
|
51
110
|
const {
|
52
111
|
id,
|
@@ -57,25 +116,72 @@ const ContentViewComponents = ({ cvId, details }) => {
|
|
57
116
|
const cells = [
|
58
117
|
{ title: <Bullseye><ContentViewIcon composite={false} /></Bullseye> },
|
59
118
|
{ title: <Link to={urlBuilder('labs/content_views', '', id)}>{name}</Link> },
|
60
|
-
{
|
61
|
-
|
119
|
+
{
|
120
|
+
title:
|
121
|
+
<Split>
|
122
|
+
<SplitItem>
|
123
|
+
<ComponentVersion {...{ componentCV }} />
|
124
|
+
</SplitItem>
|
125
|
+
{componentCvId && cvVersion &&
|
126
|
+
<SplitItem>
|
127
|
+
<Button
|
128
|
+
className="foreman-edit-icon"
|
129
|
+
aria-label="edit_version"
|
130
|
+
variant="plain"
|
131
|
+
onClick={() => {
|
132
|
+
onAdd({
|
133
|
+
componentCvId: id, published: cvVersion, added: componentCvId, latest,
|
134
|
+
});
|
135
|
+
}}
|
136
|
+
>
|
137
|
+
<PencilAltIcon />
|
138
|
+
</Button>
|
139
|
+
</SplitItem>}
|
140
|
+
</Split>,
|
141
|
+
},
|
142
|
+
{ title: environments ? <ComponentEnvironments {...{ environments }} /> : __('Not yet published') },
|
62
143
|
{ title: <Link to={urlBuilder(`labs/content_views/${id}#repositories`, '')}>{ repositories ? repositories.length : 0 }</Link> },
|
63
144
|
{
|
64
|
-
title: <AddedStatusLabel added />,
|
145
|
+
title: <AddedStatusLabel added={componentCvId} />,
|
65
146
|
},
|
66
|
-
{ title: <TableText wrapModifier="truncate">{description || 'No description'}</TableText> },
|
147
|
+
{ title: <TableText wrapModifier="truncate">{description || __('No description')}</TableText> },
|
67
148
|
];
|
68
|
-
newRows.push({
|
149
|
+
newRows.push({
|
150
|
+
componentCvId: id, added: componentCvId, published: cvVersion, latest, cells,
|
151
|
+
});
|
69
152
|
});
|
70
153
|
return newRows;
|
71
|
-
};
|
154
|
+
}, [onAdd]);
|
155
|
+
|
156
|
+
const actionResolver = (rowData, { _rowIndex }) => [
|
157
|
+
{
|
158
|
+
title: __('Add'),
|
159
|
+
isDisabled: rowData.added,
|
160
|
+
onClick: (_event, rowId, rowInfo) => {
|
161
|
+
onAdd({
|
162
|
+
componentCvId: rowInfo.componentCvId,
|
163
|
+
published: rowInfo.published,
|
164
|
+
added: rowInfo.added,
|
165
|
+
latest: rowInfo.latest,
|
166
|
+
});
|
167
|
+
},
|
168
|
+
},
|
169
|
+
{
|
170
|
+
title: __('Remove'),
|
171
|
+
isDisabled: !rowData.added,
|
172
|
+
onClick: (_event, rowId, rowInfo) => {
|
173
|
+
onRemove(rowInfo.added);
|
174
|
+
},
|
175
|
+
},
|
176
|
+
];
|
72
177
|
|
73
178
|
const emptyContentTitle = __(`No content views belong to ${label}`);
|
74
179
|
const emptyContentBody = __('Please add some content views.');
|
75
180
|
const emptySearchTitle = __('No matching content views found');
|
76
181
|
const emptySearchBody = __('Try changing your search settings.');
|
182
|
+
const activeFilters = statusSelected && statusSelected !== ALL_STATUSES;
|
77
183
|
|
78
|
-
|
184
|
+
useDeepCompareEffect(() => {
|
79
185
|
const { results, ...meta } = response;
|
80
186
|
setMetadata(meta);
|
81
187
|
|
@@ -83,7 +189,7 @@ const ContentViewComponents = ({ cvId, details }) => {
|
|
83
189
|
const newRows = buildRows(results);
|
84
190
|
setRows(newRows);
|
85
191
|
}
|
86
|
-
}, [
|
192
|
+
}, [response, buildRows, loading]);
|
87
193
|
|
88
194
|
return (
|
89
195
|
<TableWrapper
|
@@ -98,13 +204,45 @@ const ContentViewComponents = ({ cvId, details }) => {
|
|
98
204
|
updateSearchQuery,
|
99
205
|
error,
|
100
206
|
status,
|
207
|
+
activeFilters,
|
208
|
+
actionResolver,
|
101
209
|
}}
|
102
210
|
onSelect={onSelect(rows, setRows)}
|
103
211
|
cells={columnHeaders}
|
104
212
|
variant={TableVariant.compact}
|
105
213
|
autocompleteEndpoint="/content_views/auto_complete_search"
|
106
|
-
fetchItems={params =>
|
107
|
-
|
214
|
+
fetchItems={useCallback(params =>
|
215
|
+
getContentViewComponents(cvId, params, statusSelected), [cvId, statusSelected])}
|
216
|
+
additionalListeners={[statusSelected, addComponentsResolved, removeComponentsResolved]}
|
217
|
+
>
|
218
|
+
<Split hasGutter>
|
219
|
+
<SplitItem>
|
220
|
+
<SelectableDropdown
|
221
|
+
items={[ADDED, NOT_ADDED, ALL_STATUSES]}
|
222
|
+
title={__('Status')}
|
223
|
+
selected={statusSelected}
|
224
|
+
setSelected={setStatusSelected}
|
225
|
+
placeholderText={__('Status')}
|
226
|
+
/>
|
227
|
+
</SplitItem>
|
228
|
+
<SplitItem>
|
229
|
+
<Button onClick={removeBulk} isDisabled={!(bulkRemoveEnabled())} variant="secondary" aria-label="remove_components">
|
230
|
+
{__('Remove content views')}
|
231
|
+
</Button>
|
232
|
+
</SplitItem>
|
233
|
+
</Split>
|
234
|
+
{versionEditing &&
|
235
|
+
<ComponentContentViewAddModal
|
236
|
+
cvId={compositeCvEditing}
|
237
|
+
componentCvId={componentCvEditing}
|
238
|
+
componentId={componentId}
|
239
|
+
latest={componentLatest}
|
240
|
+
show={versionEditing}
|
241
|
+
setIsOpen={setVersionEditing}
|
242
|
+
aria-label="copy_content_view_modal"
|
243
|
+
/>
|
244
|
+
}
|
245
|
+
</TableWrapper>
|
108
246
|
);
|
109
247
|
};
|
110
248
|
|