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
@@ -0,0 +1,161 @@
|
|
1
|
+
import React, { useState } from 'react';
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
3
|
+
import { Redirect } from 'react-router-dom';
|
4
|
+
import { useDispatch, useSelector } from 'react-redux';
|
5
|
+
import { STATUS } from 'foremanReact/constants';
|
6
|
+
import PropTypes from 'prop-types';
|
7
|
+
import { translate as __ } from 'foremanReact/common/I18n';
|
8
|
+
import { Modal, ModalVariant, Form, FormGroup, TextInput, ActionGroup, Button, Radio, TextArea,
|
9
|
+
Split, SplitItem, Select, SelectOption } from '@patternfly/react-core';
|
10
|
+
import { createContentViewFilter } from '../../ContentViewDetailActions';
|
11
|
+
import {
|
12
|
+
selectCreateContentViewFilter, selectCreateContentViewFilterStatus,
|
13
|
+
selectCreateContentViewFilterError,
|
14
|
+
} from '../../../Details/ContentViewDetailSelectors';
|
15
|
+
import { FILTER_TYPES } from '../../../ContentViewsConstants';
|
16
|
+
import ContentType from '../ContentType';
|
17
|
+
|
18
|
+
const CVFilterAddModal = ({ cvId, show, setIsOpen }) => {
|
19
|
+
const [inclusion, setInclusion] = useState(true);
|
20
|
+
const [name, setName] = useState('');
|
21
|
+
const [description, setDescription] = useState('');
|
22
|
+
const [type, setType] = useState('rpm');
|
23
|
+
const [saving, setSaving] = useState(false);
|
24
|
+
const [typeSelectOpen, setTypeSelectOpen] = useState(false);
|
25
|
+
const dispatch = useDispatch();
|
26
|
+
const response = useSelector(state => selectCreateContentViewFilter(state));
|
27
|
+
const status = useSelector(state => selectCreateContentViewFilterStatus(state));
|
28
|
+
const error = useSelector(state => selectCreateContentViewFilterError(state));
|
29
|
+
const [redirect, setRedirect] = useState(false);
|
30
|
+
|
31
|
+
const onSave = () => {
|
32
|
+
setSaving(true);
|
33
|
+
dispatch(createContentViewFilter(
|
34
|
+
cvId,
|
35
|
+
{
|
36
|
+
name, description, inclusion, type,
|
37
|
+
},
|
38
|
+
));
|
39
|
+
};
|
40
|
+
|
41
|
+
const onSelect = (event, selection) => {
|
42
|
+
setType(selection);
|
43
|
+
setTypeSelectOpen(false);
|
44
|
+
};
|
45
|
+
|
46
|
+
useDeepCompareEffect(() => {
|
47
|
+
const { id } = response || {};
|
48
|
+
if (id && status === STATUS.RESOLVED && saving) {
|
49
|
+
setSaving(false);
|
50
|
+
setRedirect(true);
|
51
|
+
} else if (status === STATUS.ERROR) {
|
52
|
+
setSaving(false);
|
53
|
+
}
|
54
|
+
}, [response, status, error, saving]);
|
55
|
+
|
56
|
+
if (redirect) {
|
57
|
+
const { id } = response;
|
58
|
+
return (<Redirect to={`/labs/content_views/${cvId}#filters?subContentId=${id}`} />);
|
59
|
+
}
|
60
|
+
|
61
|
+
return (
|
62
|
+
<Modal
|
63
|
+
title={__('Create filter')}
|
64
|
+
variant={ModalVariant.small}
|
65
|
+
isOpen={show}
|
66
|
+
onClose={() => {
|
67
|
+
setIsOpen(false);
|
68
|
+
}}
|
69
|
+
appendTo={document.body}
|
70
|
+
>
|
71
|
+
<Form>
|
72
|
+
<FormGroup label={__('Name')} isRequired fieldId="name">
|
73
|
+
<TextInput
|
74
|
+
isRequired
|
75
|
+
type="text"
|
76
|
+
id="name"
|
77
|
+
aria-label="input_name"
|
78
|
+
name="name"
|
79
|
+
value={name}
|
80
|
+
onChange={value => setName(value)}
|
81
|
+
/>
|
82
|
+
</FormGroup>
|
83
|
+
<FormGroup>
|
84
|
+
<Split hasGutter>
|
85
|
+
<SplitItem>
|
86
|
+
<Radio
|
87
|
+
isChecked={inclusion}
|
88
|
+
name="radio-1"
|
89
|
+
onChange={checked => setInclusion(checked)}
|
90
|
+
label="Include Filter"
|
91
|
+
id="include_filter"
|
92
|
+
value="includeFilter"
|
93
|
+
/>
|
94
|
+
</SplitItem>
|
95
|
+
<SplitItem>
|
96
|
+
<Radio
|
97
|
+
isChecked={!inclusion}
|
98
|
+
name="radio-1"
|
99
|
+
onChange={checked => setInclusion(!checked)}
|
100
|
+
label="Exclude Filter"
|
101
|
+
id="exclude_filter"
|
102
|
+
value="excludeFilter"
|
103
|
+
/>
|
104
|
+
</SplitItem>
|
105
|
+
</Split>
|
106
|
+
</FormGroup>
|
107
|
+
<FormGroup label={__('Content type')} isRequired fieldId="content_type">
|
108
|
+
<Select
|
109
|
+
selections={type}
|
110
|
+
onSelect={onSelect}
|
111
|
+
isOpen={typeSelectOpen}
|
112
|
+
onToggle={isExpanded => setTypeSelectOpen(isExpanded)}
|
113
|
+
id="content_type"
|
114
|
+
name="content_type"
|
115
|
+
aria-label="ContentType"
|
116
|
+
>
|
117
|
+
{
|
118
|
+
FILTER_TYPES.map(item =>
|
119
|
+
<SelectOption key={item} value={item}><ContentType type={item} /></SelectOption>)
|
120
|
+
}
|
121
|
+
</Select>
|
122
|
+
</FormGroup>
|
123
|
+
<FormGroup label={__('Description')} fieldId="description">
|
124
|
+
<TextArea
|
125
|
+
type="text"
|
126
|
+
id="description"
|
127
|
+
name="description"
|
128
|
+
aria-label="input_description"
|
129
|
+
value={description}
|
130
|
+
onChange={value => setDescription(value)}
|
131
|
+
/>
|
132
|
+
</FormGroup>
|
133
|
+
<ActionGroup>
|
134
|
+
<Button
|
135
|
+
aria-label="create_filter"
|
136
|
+
variant="primary"
|
137
|
+
isDisabled={saving}
|
138
|
+
onClick={() => onSave()}
|
139
|
+
>
|
140
|
+
{__('Create filter')}
|
141
|
+
</Button>
|
142
|
+
<Button variant="link" onClick={() => setIsOpen(false)}>
|
143
|
+
{__('Cancel')}
|
144
|
+
</Button>
|
145
|
+
</ActionGroup>
|
146
|
+
</Form>
|
147
|
+
</Modal>
|
148
|
+
);
|
149
|
+
};
|
150
|
+
|
151
|
+
CVFilterAddModal.propTypes = {
|
152
|
+
cvId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
153
|
+
show: PropTypes.bool.isRequired,
|
154
|
+
setIsOpen: PropTypes.func,
|
155
|
+
};
|
156
|
+
|
157
|
+
CVFilterAddModal.defaultProps = {
|
158
|
+
setIsOpen: null,
|
159
|
+
};
|
160
|
+
|
161
|
+
export default CVFilterAddModal;
|
@@ -0,0 +1,54 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import { renderWithRedux, patientlyWaitFor, fireEvent } from 'react-testing-lib-wrapper';
|
3
|
+
|
4
|
+
|
5
|
+
import api from '../../../../../../services/api';
|
6
|
+
import CVFilterAddModal from '../CVFilterAddModal';
|
7
|
+
import { nockInstance, assertNockRequest } from '../../../../../../test-utils/nockWrapper';
|
8
|
+
|
9
|
+
const cvCreateData = require('./cvFilterCreateResult.fixtures.json');
|
10
|
+
|
11
|
+
const cvCreateFilterPath = api.getApiUrl('/content_view_filters?content_view_id=5');
|
12
|
+
|
13
|
+
const setIsOpen = jest.fn();
|
14
|
+
|
15
|
+
const createDetails = {
|
16
|
+
name: 'test',
|
17
|
+
description: 'Creating filter',
|
18
|
+
inclusion: true,
|
19
|
+
type: 'rpm',
|
20
|
+
};
|
21
|
+
|
22
|
+
const createdCVDetails = { ...cvCreateData };
|
23
|
+
|
24
|
+
const form = <CVFilterAddModal cvId={5} show setIsOpen={setIsOpen} />;
|
25
|
+
|
26
|
+
test('Can save content view filter from form', (done) => {
|
27
|
+
const createFilterscope = nockInstance
|
28
|
+
.post(cvCreateFilterPath, createDetails)
|
29
|
+
.reply(201, createdCVDetails);
|
30
|
+
const { queryByText, getByLabelText } = renderWithRedux(form);
|
31
|
+
expect(queryByText('Description')).toBeInTheDocument();
|
32
|
+
|
33
|
+
fireEvent.change(getByLabelText('input_name'), { target: { value: 'test' } });
|
34
|
+
fireEvent.change(getByLabelText('input_description'), { target: { value: 'Creating filter' } });
|
35
|
+
|
36
|
+
getByLabelText('create_filter').click();
|
37
|
+
assertNockRequest(createFilterscope, done);
|
38
|
+
});
|
39
|
+
|
40
|
+
test('Closes content view filter form upon save', async (done) => {
|
41
|
+
const createFilterscope = nockInstance
|
42
|
+
.post(cvCreateFilterPath, createDetails)
|
43
|
+
.reply(201, createdCVDetails);
|
44
|
+
const { queryByText, getByLabelText } = renderWithRedux(form);
|
45
|
+
fireEvent.change(getByLabelText('input_name'), { target: { value: 'test' } });
|
46
|
+
fireEvent.change(getByLabelText('input_description'), { target: { value: 'Creating filter' } });
|
47
|
+
|
48
|
+
getByLabelText('create_filter').click();
|
49
|
+
await patientlyWaitFor(() => {
|
50
|
+
expect(queryByText('Description')).not.toBeInTheDocument();
|
51
|
+
});
|
52
|
+
|
53
|
+
assertNockRequest(createFilterscope, done);
|
54
|
+
});
|
data/webpack/scenes/ContentViews/Details/Filters/Add/__tests__/cvFilterCreateResult.fixtures.json
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
{
|
2
|
+
"inclusion": true,
|
3
|
+
"id": 9,
|
4
|
+
"name": "test",
|
5
|
+
"description": "Creating filter",
|
6
|
+
"created_at": "2021-07-16 12:57:17 -0400",
|
7
|
+
"updated_at": "2021-07-16 12:57:17 -0400",
|
8
|
+
"content_view": {
|
9
|
+
"composite": false,
|
10
|
+
"component_ids": [],
|
11
|
+
"default": false,
|
12
|
+
"version_count": 2,
|
13
|
+
"latest_version": "2.0",
|
14
|
+
"latest_version_id": 7,
|
15
|
+
"auto_publish": false,
|
16
|
+
"solve_dependencies": false,
|
17
|
+
"import_only": false,
|
18
|
+
"repository_ids": [
|
19
|
+
1
|
20
|
+
],
|
21
|
+
"id": 5,
|
22
|
+
"name": "test_capsule_syncing",
|
23
|
+
"label": "test_capsule_syncing",
|
24
|
+
"description": "",
|
25
|
+
"organization_id": 1,
|
26
|
+
"organization": {
|
27
|
+
"name": "Default Organization",
|
28
|
+
"label": "Default_Organization",
|
29
|
+
"id": 1
|
30
|
+
},
|
31
|
+
"created_at": "2021-07-16 10:22:02 -0400",
|
32
|
+
"updated_at": "2021-07-16 12:36:29 -0400",
|
33
|
+
"last_task": {
|
34
|
+
"id": "8130bdae-3b9f-425a-b25e-55ee9f2fff74",
|
35
|
+
"result": "success",
|
36
|
+
"last_sync_words": "20 minutes"
|
37
|
+
},
|
38
|
+
"latest_version_environments": [
|
39
|
+
{
|
40
|
+
"id": 1,
|
41
|
+
"name": "Library",
|
42
|
+
"label": "Library"
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"id": 2,
|
46
|
+
"name": "dev",
|
47
|
+
"label": "dev"
|
48
|
+
}
|
49
|
+
],
|
50
|
+
"environments": [
|
51
|
+
{
|
52
|
+
"id": 1,
|
53
|
+
"name": "Library",
|
54
|
+
"label": "Library",
|
55
|
+
"permissions": {
|
56
|
+
"readable": true
|
57
|
+
}
|
58
|
+
},
|
59
|
+
{
|
60
|
+
"id": 2,
|
61
|
+
"name": "dev",
|
62
|
+
"label": "dev",
|
63
|
+
"permissions": {
|
64
|
+
"readable": true
|
65
|
+
}
|
66
|
+
}
|
67
|
+
],
|
68
|
+
"repositories": [
|
69
|
+
{
|
70
|
+
"id": 1,
|
71
|
+
"name": "repo1",
|
72
|
+
"label": "repo1",
|
73
|
+
"content_type": "yum",
|
74
|
+
"product": {
|
75
|
+
"id": 1,
|
76
|
+
"name": "test1"
|
77
|
+
},
|
78
|
+
"content_counts": {
|
79
|
+
"ostree_branch": 0,
|
80
|
+
"docker_manifest": 0,
|
81
|
+
"docker_tag": 0,
|
82
|
+
"rpm": 8,
|
83
|
+
"package": 8,
|
84
|
+
"package_group": 0,
|
85
|
+
"erratum": 2,
|
86
|
+
"module_stream": 0
|
87
|
+
}
|
88
|
+
}
|
89
|
+
],
|
90
|
+
"versions": [
|
91
|
+
{
|
92
|
+
"id": 6,
|
93
|
+
"version": "1.0",
|
94
|
+
"published": "2021-07-16 10:22:26 -0400",
|
95
|
+
"environment_ids": []
|
96
|
+
},
|
97
|
+
{
|
98
|
+
"id": 7,
|
99
|
+
"version": "2.0",
|
100
|
+
"published": "2021-07-16 12:36:29 -0400",
|
101
|
+
"environment_ids": [
|
102
|
+
1,
|
103
|
+
2
|
104
|
+
]
|
105
|
+
}
|
106
|
+
],
|
107
|
+
"components": [],
|
108
|
+
"content_view_components": [],
|
109
|
+
"activation_keys": [],
|
110
|
+
"hosts": [],
|
111
|
+
"next_version": "3.0",
|
112
|
+
"last_published": "2021-07-16 12:36:29 -0400",
|
113
|
+
"permissions": {
|
114
|
+
"view_content_views": true,
|
115
|
+
"edit_content_views": true,
|
116
|
+
"destroy_content_views": true,
|
117
|
+
"publish_content_views": true,
|
118
|
+
"promote_or_remove_content_views": true
|
119
|
+
}
|
120
|
+
},
|
121
|
+
"repositories": [],
|
122
|
+
"type": "package_group",
|
123
|
+
"rules": []
|
124
|
+
}
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import React, {
|
1
|
+
import React, { useState, useCallback } from 'react';
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
2
3
|
import PropTypes from 'prop-types';
|
3
4
|
import { shallowEqual, useSelector } from 'react-redux';
|
4
5
|
import { TableVariant } from '@patternfly/react-table';
|
@@ -38,7 +39,7 @@ const CVPackageGroupFilterContent = ({ cvId, filterId }) => {
|
|
38
39
|
__('Status'),
|
39
40
|
];
|
40
41
|
|
41
|
-
const buildRows = (results) => {
|
42
|
+
const buildRows = useCallback((results) => {
|
42
43
|
const newRows = [];
|
43
44
|
results.forEach((packageGroups) => {
|
44
45
|
const {
|
@@ -62,9 +63,9 @@ const CVPackageGroupFilterContent = ({ cvId, filterId }) => {
|
|
62
63
|
});
|
63
64
|
|
64
65
|
return newRows;
|
65
|
-
};
|
66
|
+
}, [filterId]);
|
66
67
|
|
67
|
-
|
68
|
+
useDeepCompareEffect(() => {
|
68
69
|
const { results, ...meta } = response;
|
69
70
|
setMetadata(meta);
|
70
71
|
|
@@ -72,7 +73,7 @@ const CVPackageGroupFilterContent = ({ cvId, filterId }) => {
|
|
72
73
|
const newRows = buildRows(results);
|
73
74
|
setRows(newRows);
|
74
75
|
}
|
75
|
-
}, [
|
76
|
+
}, [response, loading, buildRows]);
|
76
77
|
|
77
78
|
const emptyContentTitle = __('No package groups have been added to this filter.');
|
78
79
|
const emptyContentBody = __("Add to this filter using the 'Add package group' button.");
|
@@ -101,7 +102,8 @@ const CVPackageGroupFilterContent = ({ cvId, filterId }) => {
|
|
101
102
|
cells={columnHeaders}
|
102
103
|
variant={TableVariant.compact}
|
103
104
|
autocompleteEndpoint={`/package_groups/auto_complete_search?filterid=${filterId}`}
|
104
|
-
fetchItems={params =>
|
105
|
+
fetchItems={useCallback(params =>
|
106
|
+
getCVFilterPackageGroups(cvId, filterId, params), [cvId, filterId])}
|
105
107
|
/>
|
106
108
|
</div>
|
107
109
|
</Tab>
|
@@ -1,4 +1,5 @@
|
|
1
|
-
import React, {
|
1
|
+
import React, { useState, useCallback } from 'react';
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
2
3
|
import PropTypes from 'prop-types';
|
3
4
|
import { shallowEqual, useSelector } from 'react-redux';
|
4
5
|
import { TableVariant } from '@patternfly/react-table';
|
@@ -42,7 +43,7 @@ const CVRpmFilterContent = ({ filterId, inclusion }) => {
|
|
42
43
|
return 'All versions';
|
43
44
|
};
|
44
45
|
|
45
|
-
const buildRows = (results) => {
|
46
|
+
const buildRows = useCallback((results) => {
|
46
47
|
const newRows = [];
|
47
48
|
results.forEach((rule) => {
|
48
49
|
const { name, architecture } = rule;
|
@@ -56,9 +57,9 @@ const CVRpmFilterContent = ({ filterId, inclusion }) => {
|
|
56
57
|
});
|
57
58
|
|
58
59
|
return newRows;
|
59
|
-
};
|
60
|
+
}, []);
|
60
61
|
|
61
|
-
|
62
|
+
useDeepCompareEffect(() => {
|
62
63
|
const { results, ...meta } = response;
|
63
64
|
setMetadata(meta);
|
64
65
|
|
@@ -66,7 +67,7 @@ const CVRpmFilterContent = ({ filterId, inclusion }) => {
|
|
66
67
|
const newRows = buildRows(results);
|
67
68
|
setRows(newRows);
|
68
69
|
}
|
69
|
-
}, [
|
70
|
+
}, [response, loading, buildRows]);
|
70
71
|
|
71
72
|
const emptyContentTitle = __('No rules have been added to this filter.');
|
72
73
|
const emptyContentBody = __("Add to this filter using the 'Add RPM' button.");
|
@@ -95,7 +96,7 @@ const CVRpmFilterContent = ({ filterId, inclusion }) => {
|
|
95
96
|
cells={columnHeaders}
|
96
97
|
variant={TableVariant.compact}
|
97
98
|
autocompleteEndpoint={`/content_view_filters/${filterId}/rules/auto_complete_search`}
|
98
|
-
fetchItems={params => getCVFilterRules(filterId, params)}
|
99
|
+
fetchItems={useCallback(params => getCVFilterRules(filterId, params), [filterId])}
|
99
100
|
/>
|
100
101
|
</div>
|
101
102
|
</Tab>
|
@@ -1,4 +1,5 @@
|
|
1
1
|
import React, { useEffect, useState } from 'react';
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
2
3
|
import { useParams } from 'react-router-dom';
|
3
4
|
import { shallowEqual, useSelector, useDispatch } from 'react-redux';
|
4
5
|
import { STATUS } from 'foremanReact/constants';
|
@@ -25,11 +26,11 @@ const ContentViewFilterDetails = () => {
|
|
25
26
|
|
26
27
|
useEffect(() => {
|
27
28
|
dispatch(getCVFilterDetails(cvId, filterId));
|
28
|
-
}, []);
|
29
|
+
}, [dispatch, cvId, filterId]);
|
29
30
|
|
30
|
-
|
31
|
+
useDeepCompareEffect(() => {
|
31
32
|
if (loaded) setDetails(response);
|
32
|
-
}, [
|
33
|
+
}, [response, loaded]);
|
33
34
|
|
34
35
|
const { type, inclusion } = details;
|
35
36
|
|
@@ -1,6 +1,7 @@
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
2
|
-
import
|
3
|
-
import {
|
1
|
+
import React, { useState, useEffect, useCallback } from 'react';
|
2
|
+
import useDeepCompareEffect from 'use-deep-compare-effect';
|
3
|
+
import { shallowEqual, useSelector, useDispatch } from 'react-redux';
|
4
|
+
import { Label, Split, SplitItem, Button, Dropdown, DropdownItem, KebabToggle } from '@patternfly/react-core';
|
4
5
|
import { TableVariant } from '@patternfly/react-table';
|
5
6
|
import { STATUS } from 'foremanReact/constants';
|
6
7
|
import LongDateTime from 'foremanReact/components/common/dates/LongDateTime';
|
@@ -10,7 +11,7 @@ import PropTypes from 'prop-types';
|
|
10
11
|
|
11
12
|
import TableWrapper from '../../../../components/Table/TableWrapper';
|
12
13
|
import onSelect from '../../../../components/Table/helpers';
|
13
|
-
import { getContentViewFilters } from '../ContentViewDetailActions';
|
14
|
+
import { deleteContentViewFilter, deleteContentViewFilters, getContentViewFilters } from '../ContentViewDetailActions';
|
14
15
|
import {
|
15
16
|
selectCVFilters,
|
16
17
|
selectCVFiltersStatus,
|
@@ -18,10 +19,12 @@ import {
|
|
18
19
|
} from '../ContentViewDetailSelectors';
|
19
20
|
import { truncate } from '../../../../utils/helpers';
|
20
21
|
import ContentType from './ContentType';
|
22
|
+
import CVFilterAddModal from './Add/CVFilterAddModal';
|
21
23
|
|
22
24
|
const cvFilterUrl = (cvId, filterId) => `/labs/content_views/${cvId}#filters?subContentId=${filterId}`;
|
23
25
|
|
24
26
|
const ContentViewFilters = ({ cvId }) => {
|
27
|
+
const dispatch = useDispatch();
|
25
28
|
const response = useSelector(state => selectCVFilters(state, cvId), shallowEqual);
|
26
29
|
const status = useSelector(state => selectCVFiltersStatus(state, cvId), shallowEqual);
|
27
30
|
const error = useSelector(state => selectCVFiltersError(state, cvId), shallowEqual);
|
@@ -29,6 +32,12 @@ const ContentViewFilters = ({ cvId }) => {
|
|
29
32
|
const [metadata, setMetadata] = useState({});
|
30
33
|
const [searchQuery, updateSearchQuery] = useState('');
|
31
34
|
const loading = status === STATUS.PENDING;
|
35
|
+
const [addModalOpen, setAddModalOpen] = useState(false);
|
36
|
+
const [bulkActionOpen, setBulkActionOpen] = useState(false);
|
37
|
+
const [bulkActionEnabled, setBulkActionEnabled] = useState(false);
|
38
|
+
const toggleBulkAction = () => setBulkActionOpen(prevState => !prevState);
|
39
|
+
|
40
|
+
const openAddModal = () => setAddModalOpen(true);
|
32
41
|
|
33
42
|
const columnHeaders = [
|
34
43
|
__('Name'),
|
@@ -38,14 +47,14 @@ const ContentViewFilters = ({ cvId }) => {
|
|
38
47
|
__('Inclusion type'),
|
39
48
|
];
|
40
49
|
|
41
|
-
const buildRows = (results) => {
|
50
|
+
const buildRows = useCallback((results) => {
|
42
51
|
const newRows = [];
|
43
52
|
results.forEach((filter) => {
|
44
53
|
let errataByDate = false;
|
45
54
|
const {
|
46
|
-
id, name, type, description, updated_at: updatedAt, inclusion,
|
55
|
+
id, name, type, description, updated_at: updatedAt, inclusion, rules,
|
47
56
|
} = filter;
|
48
|
-
if (
|
57
|
+
if (type === 'erratum' && rules[0]?.types) errataByDate = true;
|
49
58
|
|
50
59
|
const cells = [
|
51
60
|
{ title: (type === 'package_group' || type === 'rpm') ? <Link to={cvFilterUrl(cvId, id)}>{name}</Link> : name },
|
@@ -60,12 +69,24 @@ const ContentViewFilters = ({ cvId }) => {
|
|
60
69
|
},
|
61
70
|
];
|
62
71
|
|
63
|
-
newRows.push({ cells });
|
72
|
+
newRows.push({ cells, id });
|
64
73
|
});
|
65
74
|
return newRows;
|
75
|
+
}, [cvId]);
|
76
|
+
|
77
|
+
const bulkRemove = () => {
|
78
|
+
setBulkActionOpen(false);
|
79
|
+
const filterIds = rows.filter(({ selected }) => selected).map(({ id }) => id);
|
80
|
+
dispatch(deleteContentViewFilters(cvId, filterIds, () =>
|
81
|
+
dispatch(getContentViewFilters(cvId, {}))));
|
66
82
|
};
|
67
83
|
|
68
84
|
useEffect(() => {
|
85
|
+
const rowsAreSelected = rows.some(row => row.selected);
|
86
|
+
setBulkActionEnabled(rowsAreSelected);
|
87
|
+
}, [rows]);
|
88
|
+
|
89
|
+
useDeepCompareEffect(() => {
|
69
90
|
const { results, ...meta } = response;
|
70
91
|
setMetadata(meta);
|
71
92
|
|
@@ -73,13 +94,22 @@ const ContentViewFilters = ({ cvId }) => {
|
|
73
94
|
const newRows = buildRows(results);
|
74
95
|
setRows(newRows);
|
75
96
|
}
|
76
|
-
}, [
|
97
|
+
}, [response, loading, buildRows]);
|
98
|
+
|
99
|
+
const actionResolver = () => [
|
100
|
+
{
|
101
|
+
title: __('Remove'),
|
102
|
+
onClick: (_event, _rowId, { id }) => {
|
103
|
+
dispatch(deleteContentViewFilter(id, () =>
|
104
|
+
dispatch(getContentViewFilters(cvId, {}))));
|
105
|
+
},
|
106
|
+
},
|
107
|
+
];
|
77
108
|
|
78
109
|
const emptyContentTitle = __("You currently don't have any filters for this content view.");
|
79
110
|
const emptyContentBody = __("Add filters using the 'Add filter' button above."); // needs link
|
80
111
|
const emptySearchTitle = __('No matching filters found');
|
81
112
|
const emptySearchBody = __('Try changing your search settings.');
|
82
|
-
|
83
113
|
return (
|
84
114
|
<TableWrapper
|
85
115
|
{...{
|
@@ -93,13 +123,42 @@ const ContentViewFilters = ({ cvId }) => {
|
|
93
123
|
updateSearchQuery,
|
94
124
|
error,
|
95
125
|
status,
|
126
|
+
actionResolver,
|
96
127
|
}}
|
97
128
|
onSelect={onSelect(rows, setRows)}
|
98
129
|
cells={columnHeaders}
|
99
130
|
variant={TableVariant.compact}
|
100
131
|
autocompleteEndpoint="/content_view_filters/auto_complete_search"
|
101
|
-
fetchItems={params => getContentViewFilters(cvId, params)}
|
102
|
-
|
132
|
+
fetchItems={useCallback(params => getContentViewFilters(cvId, params), [cvId])}
|
133
|
+
>
|
134
|
+
<Split hasGutter>
|
135
|
+
<SplitItem>
|
136
|
+
<Button onClick={openAddModal} variant="secondary" aria-label="create_filter">
|
137
|
+
{__('Create filter')}
|
138
|
+
</Button>
|
139
|
+
</SplitItem>
|
140
|
+
<SplitItem>
|
141
|
+
<Dropdown
|
142
|
+
toggle={<KebabToggle aria-label="bulk_actions" onToggle={toggleBulkAction} />}
|
143
|
+
isOpen={bulkActionOpen}
|
144
|
+
isPlain
|
145
|
+
dropdownItems={[
|
146
|
+
<DropdownItem aria-label="bulk_remove" key="bulk_remove" isDisabled={!bulkActionEnabled} component="button" onClick={bulkRemove}>
|
147
|
+
{__('Remove')}
|
148
|
+
</DropdownItem>]
|
149
|
+
}
|
150
|
+
/>
|
151
|
+
</SplitItem>
|
152
|
+
</Split>
|
153
|
+
{addModalOpen &&
|
154
|
+
<CVFilterAddModal
|
155
|
+
cvId={cvId}
|
156
|
+
show={addModalOpen}
|
157
|
+
setIsOpen={setAddModalOpen}
|
158
|
+
aria-label="add_filter_modal"
|
159
|
+
/>
|
160
|
+
}
|
161
|
+
</TableWrapper>);
|
103
162
|
};
|
104
163
|
|
105
164
|
|
@@ -90,3 +90,80 @@ test('Can search for filter', async (done) => {
|
|
90
90
|
assertNockRequest(initialScope);
|
91
91
|
assertNockRequest(searchResultScope, done);
|
92
92
|
});
|
93
|
+
|
94
|
+
test('Can remove a filter', async (done) => {
|
95
|
+
const { id } = firstFilter;
|
96
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
97
|
+
|
98
|
+
const getContentViewScope = nockInstance
|
99
|
+
.get(cvFilters)
|
100
|
+
.query(true)
|
101
|
+
.reply(200, cvFilterFixtures);
|
102
|
+
|
103
|
+
const removeFilterScope = nockInstance
|
104
|
+
.delete(api.getApiUrl(`/content_view_filters/${id}`))
|
105
|
+
.query(true)
|
106
|
+
.reply(200, {});
|
107
|
+
|
108
|
+
const callbackGetContentViewScope = nockInstance
|
109
|
+
.get(cvFilters)
|
110
|
+
.query(true)
|
111
|
+
.reply(200, {});
|
112
|
+
|
113
|
+
const { getAllByLabelText, getByText } = renderWithRedux(
|
114
|
+
<ContentViewFilters cvId={1} />,
|
115
|
+
renderOptions,
|
116
|
+
);
|
117
|
+
|
118
|
+
await patientlyWaitFor(() => {
|
119
|
+
expect(getAllByLabelText('Actions')[0]).toHaveAttribute('aria-expanded', 'false');
|
120
|
+
});
|
121
|
+
fireEvent.click(getAllByLabelText('Actions')[0]);
|
122
|
+
expect(getAllByLabelText('Actions')[0]).toHaveAttribute('aria-expanded', 'true');
|
123
|
+
await patientlyWaitFor(() => expect(getByText('Remove')).toBeInTheDocument());
|
124
|
+
fireEvent.click(getByText('Remove'));
|
125
|
+
|
126
|
+
assertNockRequest(autocompleteScope);
|
127
|
+
assertNockRequest(getContentViewScope);
|
128
|
+
assertNockRequest(removeFilterScope);
|
129
|
+
assertNockRequest(callbackGetContentViewScope, done);
|
130
|
+
});
|
131
|
+
|
132
|
+
test('Can remove multiple filters', async (done) => {
|
133
|
+
const autocompleteScope = mockAutocomplete(nockInstance, autocompleteUrl);
|
134
|
+
const getContentViewScope = nockInstance
|
135
|
+
.get(cvFilters)
|
136
|
+
.query(true)
|
137
|
+
.reply(200, cvFilterFixtures);
|
138
|
+
|
139
|
+
const removeFilterScope = nockInstance
|
140
|
+
.put(
|
141
|
+
api.getApiUrl('/content_views/1/remove_filters'),
|
142
|
+
{ filter_ids: [4, 5, 6, 7, 8, 9] },
|
143
|
+
)
|
144
|
+
.reply(200, {});
|
145
|
+
|
146
|
+
const callbackGetContentViewScope = nockInstance
|
147
|
+
.get(cvFilters)
|
148
|
+
.query(true)
|
149
|
+
.reply(200, {});
|
150
|
+
|
151
|
+
const { getAllByLabelText, getByLabelText, getByText } = renderWithRedux(
|
152
|
+
<ContentViewFilters cvId={1} />,
|
153
|
+
renderOptions,
|
154
|
+
);
|
155
|
+
|
156
|
+
await patientlyWaitFor(() => {
|
157
|
+
fireEvent.click(getByLabelText('Select all rows'));
|
158
|
+
expect(getAllByLabelText('bulk_actions')[0]).toHaveAttribute('aria-expanded', 'false');
|
159
|
+
});
|
160
|
+
fireEvent.click(getAllByLabelText('bulk_actions')[0]);
|
161
|
+
expect(getAllByLabelText('bulk_actions')[0]).toHaveAttribute('aria-expanded', 'true');
|
162
|
+
await patientlyWaitFor(() => expect(getByText('Remove')).toBeInTheDocument());
|
163
|
+
fireEvent.click(getByText('Remove'));
|
164
|
+
|
165
|
+
assertNockRequest(autocompleteScope);
|
166
|
+
assertNockRequest(getContentViewScope);
|
167
|
+
assertNockRequest(removeFilterScope);
|
168
|
+
assertNockRequest(callbackGetContentViewScope, done);
|
169
|
+
});
|