summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--awx/ui_next/package-lock.json389
-rw-r--r--awx/ui_next/package.json7
-rw-r--r--awx/ui_next/src/components/AlertModal/AlertModal.jsx18
-rw-r--r--awx/ui_next/src/components/AlertModal/AlertModal.test.jsx4
-rw-r--r--awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx2
-rw-r--r--awx/ui_next/src/components/AppContainer/AppContainer.jsx12
-rw-r--r--awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx22
-rw-r--r--awx/ui_next/src/components/AssociateModal/AssociateModal.jsx4
-rw-r--r--awx/ui_next/src/components/Background/Background.jsx12
-rw-r--r--awx/ui_next/src/components/Background/Background.test.jsx2
-rw-r--r--awx/ui_next/src/components/Breadcrumbs/Breadcrumbs.jsx10
-rw-r--r--awx/ui_next/src/components/Card/TabbedCardHeader.js13
-rw-r--r--awx/ui_next/src/components/Card/index.js1
-rw-r--r--awx/ui_next/src/components/CardCloseButton/CardCloseButton.jsx36
-rw-r--r--awx/ui_next/src/components/CardCloseButton/CardCloseButton.test.jsx23
-rw-r--r--awx/ui_next/src/components/CardCloseButton/index.js1
-rw-r--r--awx/ui_next/src/components/ChipGroup/ChipGroup.jsx2
-rw-r--r--awx/ui_next/src/components/CodeMirrorInput/VariablesDetail.jsx2
-rw-r--r--awx/ui_next/src/components/CodeMirrorInput/VariablesField.jsx2
-rw-r--r--awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx2
-rw-r--r--awx/ui_next/src/components/ContentEmpty/ContentEmpty.jsx4
-rw-r--r--awx/ui_next/src/components/ContentError/ContentError.jsx2
-rw-r--r--awx/ui_next/src/components/CredentialChip/CredentialChip.jsx2
-rw-r--r--awx/ui_next/src/components/DataListToolbar/DataListToolbar.jsx67
-rw-r--r--awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx2
-rw-r--r--awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx2
-rw-r--r--awx/ui_next/src/components/FormField/FormField.jsx8
-rw-r--r--awx/ui_next/src/components/FormField/PasswordField.jsx2
-rw-r--r--awx/ui_next/src/components/FormField/PasswordInput.jsx2
-rw-r--r--awx/ui_next/src/components/HostForm/HostForm.jsx4
-rw-r--r--awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.jsx4
-rw-r--r--awx/ui_next/src/components/LaunchPrompt/steps/SurveyStep.jsx6
-rw-r--r--awx/ui_next/src/components/ListHeader/ListHeader.jsx15
-rw-r--r--awx/ui_next/src/components/Lookup/CredentialLookup.jsx2
-rw-r--r--awx/ui_next/src/components/Lookup/Lookup.jsx4
-rw-r--r--awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx2
-rw-r--r--awx/ui_next/src/components/Lookup/OrganizationLookup.jsx2
-rw-r--r--awx/ui_next/src/components/Lookup/ProjectLookup.jsx2
-rw-r--r--awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx4
-rw-r--r--awx/ui_next/src/components/MultiSelect/TagMultiSelect.test.jsx2
-rw-r--r--awx/ui_next/src/components/NotificationList/__snapshots__/NotificationListItem.test.jsx.snap282
-rw-r--r--awx/ui_next/src/components/OptionsList/OptionsList.jsx2
-rw-r--r--awx/ui_next/src/components/PaginatedDataList/__snapshots__/ToolbarDeleteButton.test.jsx.snap54
-rw-r--r--awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx8
-rw-r--r--awx/ui_next/src/components/ResourceAccessList/ResourceAccessListItem.jsx2
-rw-r--r--awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap913
-rw-r--r--awx/ui_next/src/components/ResourceAccessList/__snapshots__/ResourceAccessListItem.test.jsx.snap234
-rw-r--r--awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx4
-rw-r--r--awx/ui_next/src/components/Schedule/Schedule.jsx21
-rw-r--r--awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx3
-rw-r--r--awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.test.jsx3
-rw-r--r--awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.jsx2
-rw-r--r--awx/ui_next/src/components/Schedule/shared/FrequencyDetailSubform.jsx22
-rw-r--r--awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx18
-rw-r--r--awx/ui_next/src/components/Search/Search.jsx24
-rw-r--r--awx/ui_next/src/components/Search/Search.test.jsx89
-rw-r--r--awx/ui_next/src/components/UserAndTeamAccessAdd/UserAndTeamAccessAdd.test.jsx13
-rw-r--r--awx/ui_next/src/components/Wizard/Wizard.jsx2
-rw-r--r--awx/ui_next/src/screens/Application/ApplicationAdd/ApplicationAdd.test.jsx4
-rw-r--r--awx/ui_next/src/screens/Application/shared/ApplicationForm.test.jsx4
-rw-r--r--awx/ui_next/src/screens/AuthSetting/AuthSettings.jsx4
-rw-r--r--awx/ui_next/src/screens/Credential/Credential.jsx28
-rw-r--r--awx/ui_next/src/screens/Credential/Credential.test.jsx4
-rw-r--r--awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx4
-rw-r--r--awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx16
-rw-r--r--awx/ui_next/src/screens/Credential/shared/TypeInputsSubForm.jsx4
-rw-r--r--awx/ui_next/src/screens/Dashboard/Dashboard.jsx4
-rw-r--r--awx/ui_next/src/screens/Host/Host.jsx31
-rw-r--r--awx/ui_next/src/screens/InstanceGroup/InstanceGroups.jsx4
-rw-r--r--awx/ui_next/src/screens/Inventory/Inventory.jsx37
-rw-r--r--awx/ui_next/src/screens/Inventory/Inventory.test.jsx2
-rw-r--r--awx/ui_next/src/screens/Inventory/InventoryGroup/InventoryGroup.jsx19
-rw-r--r--awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx18
-rw-r--r--awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx18
-rw-r--r--awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx20
-rw-r--r--awx/ui_next/src/screens/Inventory/SmartInventory.jsx28
-rw-r--r--awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx2
-rw-r--r--awx/ui_next/src/screens/Inventory/shared/InventorySourceForm.jsx8
-rw-r--r--awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SCMSubForm.jsx4
-rw-r--r--awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SharedFields.jsx2
-rw-r--r--awx/ui_next/src/screens/InventoryScript/InventoryScripts.jsx4
-rw-r--r--awx/ui_next/src/screens/Job/Job.jsx28
-rw-r--r--awx/ui_next/src/screens/Job/JobOutput/HostEventModal.jsx56
-rw-r--r--awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx11
-rw-r--r--awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx1
-rw-r--r--awx/ui_next/src/screens/Job/JobOutput/JobOutput.test.jsx2
-rw-r--r--awx/ui_next/src/screens/JobsSetting/JobsSettings.jsx4
-rw-r--r--awx/ui_next/src/screens/License/License.jsx4
-rw-r--r--awx/ui_next/src/screens/ManagementJob/ManagementJobs.jsx4
-rw-r--r--awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.jsx4
-rw-r--r--awx/ui_next/src/screens/Organization/Organization.jsx34
-rw-r--r--awx/ui_next/src/screens/Organization/Organization.test.jsx4
-rw-r--r--awx/ui_next/src/screens/Portal/Portal.jsx4
-rw-r--r--awx/ui_next/src/screens/Project/Project.jsx33
-rw-r--r--awx/ui_next/src/screens/Project/Project.test.jsx12
-rw-r--r--awx/ui_next/src/screens/Project/shared/ProjectForm.jsx8
-rw-r--r--awx/ui_next/src/screens/Project/shared/ProjectSubForms/ManualSubForm.jsx2
-rw-r--r--awx/ui_next/src/screens/Project/shared/ProjectSubForms/SharedFields.jsx4
-rw-r--r--awx/ui_next/src/screens/SystemSetting/SystemSettings.jsx4
-rw-r--r--awx/ui_next/src/screens/Team/Team.jsx28
-rw-r--r--awx/ui_next/src/screens/Team/TeamAccess/TeamAccessListItem.jsx6
-rw-r--r--awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx2
-rw-r--r--awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx5
-rw-r--r--awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.test.jsx9
-rw-r--r--awx/ui_next/src/screens/Template/Survey/SurveyToolbar.jsx44
-rw-r--r--awx/ui_next/src/screens/Template/Survey/SurveyToolbar.test.jsx2
-rw-r--r--awx/ui_next/src/screens/Template/Template.jsx32
-rw-r--r--awx/ui_next/src/screens/Template/Template.test.jsx6
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplate.jsx36
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.test.jsx4
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkAddModal.jsx4
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkEditModal.jsx4
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.jsx2
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeModal.test.jsx8
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx4
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.jsx4
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.jsx2
-rw-r--r--awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx6
-rw-r--r--awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx8
-rw-r--r--awx/ui_next/src/screens/Template/shared/LabelSelect.jsx4
-rw-r--r--awx/ui_next/src/screens/UISetting/UISettings.jsx4
-rw-r--r--awx/ui_next/src/screens/User/User.jsx29
-rw-r--r--awx/ui_next/src/screens/User/User.test.jsx14
-rw-r--r--awx/ui_next/src/screens/User/UserAccess/UserAccessListItem.jsx6
-rw-r--r--awx/ui_next/src/screens/User/shared/UserForm.jsx4
125 files changed, 1332 insertions, 1831 deletions
diff --git a/awx/ui_next/package-lock.json b/awx/ui_next/package-lock.json
index e9635701b6..049b48ad8d 100644
--- a/awx/ui_next/package-lock.json
+++ b/awx/ui_next/package-lock.json
@@ -1150,31 +1150,6 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
- "@emotion/babel-utils": {
- "version": "0.6.10",
- "resolved": "https://registry.npmjs.org/@emotion/babel-utils/-/babel-utils-0.6.10.tgz",
- "integrity": "sha512-/fnkM/LTEp3jKe++T0KyTszVGWNKPNOUJfjNKLO17BzQ6QPxgbg3whayom1Qr2oLFH3V92tDymU+dT5q676uow==",
- "requires": {
- "@emotion/hash": "^0.6.6",
- "@emotion/memoize": "^0.6.6",
- "@emotion/serialize": "^0.9.1",
- "convert-source-map": "^1.5.1",
- "find-root": "^1.1.0",
- "source-map": "^0.7.2"
- },
- "dependencies": {
- "source-map": {
- "version": "0.7.3",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
- "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ=="
- }
- }
- },
- "@emotion/hash": {
- "version": "0.6.6",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.6.6.tgz",
- "integrity": "sha512-ojhgxzUHZ7am3D2jHkMzPpsBAiB005GF5YU4ea+8DNPybMk01JJUM9V9YRlF/GE95tcOm8DxQvWA2jq19bGalQ=="
- },
"@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
@@ -1190,50 +1165,6 @@
}
}
},
- "@emotion/memoize": {
- "version": "0.6.6",
- "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.6.6.tgz",
- "integrity": "sha512-h4t4jFjtm1YV7UirAFuSuFGyLa+NNxjdkq6DpFLANNQY5rHueFZHVY+8Cu1HYVP6DrheB0kv4m5xPjo7eKT7yQ=="
- },
- "@emotion/serialize": {
- "version": "0.9.1",
- "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-0.9.1.tgz",
- "integrity": "sha512-zTuAFtyPvCctHBEL8KZ5lJuwBanGSutFEncqLn/m9T1a6a93smBStK+bZzcNPgj4QS8Rkw9VTwJGhRIUVO8zsQ==",
- "requires": {
- "@emotion/hash": "^0.6.6",
- "@emotion/memoize": "^0.6.6",
- "@emotion/unitless": "^0.6.7",
- "@emotion/utils": "^0.8.2"
- }
- },
- "@emotion/stylis": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.7.1.tgz",
- "integrity": "sha512-/SLmSIkN13M//53TtNxgxo57mcJk/UJIDFRKwOiLIBEyBHEcipgR6hNMQ/59Sl4VjCJ0Z/3zeAZyvnSLPG/1HQ=="
- },
- "@emotion/unitless": {
- "version": "0.6.7",
- "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.6.7.tgz",
- "integrity": "sha512-Arj1hncvEVqQ2p7Ega08uHLr1JuRYBuO5cIvcA+WWEQ5+VmkOE3ZXzl04NbQxeQpWX78G7u6MqxKuNX3wvYZxg=="
- },
- "@emotion/utils": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-0.8.2.tgz",
- "integrity": "sha512-rLu3wcBWH4P5q1CGoSSH/i9hrXs7SlbRLkoq9IGuoPYNGQvDJ3pt/wmOM+XgYjIDRMVIdkUWt0RsfzF50JfnCw=="
- },
- "@fortawesome/fontawesome-common-types": {
- "version": "0.2.28",
- "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.28.tgz",
- "integrity": "sha512-gtis2/5yLdfI6n0ia0jH7NJs5i/Z/8M/ZbQL6jXQhCthEOe5Cr5NcQPhgTvFxNOtURE03/ZqUcEskdn2M+QaBg=="
- },
- "@fortawesome/free-brands-svg-icons": {
- "version": "5.13.0",
- "resolved": "https://registry.npmjs.org/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-5.13.0.tgz",
- "integrity": "sha512-/6xXiJFCMEQxqxXbL0FPJpwq5Cv6MRrjsbJEmH/t5vOvB4dILDpnY0f7zZSlA8+TG7jwlt12miF/yZpZkykucA==",
- "requires": {
- "@fortawesome/fontawesome-common-types": "^0.2.28"
- }
- },
"@hapi/address": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@hapi/address/-/address-2.1.4.tgz",
@@ -1704,62 +1635,45 @@
"dev": true
},
"@patternfly/patternfly": {
- "version": "2.71.6",
- "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-2.71.6.tgz",
- "integrity": "sha512-mqqtuCVa+/FbyyK8hSAcfEIwNX73+zbnzHpmC4NrW0kyMzSszPtBqev/ZO79ZxGqZUpLOyUBTVaH7oKn8cL35Q=="
+ "version": "4.10.31",
+ "resolved": "https://registry.npmjs.org/@patternfly/patternfly/-/patternfly-4.10.31.tgz",
+ "integrity": "sha512-UxdZ/apWRowXYZ5qPz5LPfXwyB4YGpomrCJPX7c36+Zg8jFpYyVqgVYainL8Yf/GrChtC2LKyoHg7UUTtMtp4A=="
},
"@patternfly/react-core": {
- "version": "3.158.1",
- "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-3.158.1.tgz",
- "integrity": "sha512-LUknvaIBoo0ftu7OBZhyGn7Cu3IfhaO4nXx17M99OYc76yKBv1jJMmTTUh7OX3QyWH961gH1K7Z3GlJV7v57ZA==",
+ "version": "4.18.14",
+ "resolved": "https://registry.npmjs.org/@patternfly/react-core/-/react-core-4.18.14.tgz",
+ "integrity": "sha512-aFOBX02ud78eCu7rtbUTr+Rj/J7BertxDssSWFb+uDQrUN268dSH9/tvHcDd3//YZrsCoBbky9ngRa4Jt1fryg==",
"requires": {
- "@patternfly/react-icons": "^3.15.17",
- "@patternfly/react-styles": "^3.7.14",
- "@patternfly/react-tokens": "^2.8.14",
+ "@patternfly/react-icons": "^4.3.6",
+ "@patternfly/react-styles": "^4.3.6",
+ "@patternfly/react-tokens": "^4.4.5",
"focus-trap": "4.0.2",
"react-dropzone": "9.0.0",
- "tippy.js": "5.1.2"
+ "tippy.js": "5.1.2",
+ "tslib": "^1.11.1"
},
"dependencies": {
"@patternfly/react-icons": {
- "version": "3.15.17",
- "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-3.15.17.tgz",
- "integrity": "sha512-Q0JAlxEvSAl5kcMSUMItLiKi9fweO941g5+lS45t3o/Rv4Eg91Ig7AyK1YWw6m1ah+/eHslLfox0Uqw7m7usLg==",
- "requires": {
- "@fortawesome/free-brands-svg-icons": "^5.8.1"
- }
- },
- "@patternfly/react-tokens": {
- "version": "2.8.14",
- "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-2.8.14.tgz",
- "integrity": "sha512-pha0XyZ3ZiXuQoKstuFsiEHARFQKUFsS6WxVuRSEyNbGTToRNJkKR9cW5swzHgXK6Fuw5EA2XFHLuu8osj52KA=="
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.4.0.tgz",
+ "integrity": "sha512-UKQI5luZ6Bd3SLljl4WNFVhtteUiM2lbKz5qjgBZn3zLOW2Zigv6M1zkgII6rMW9Rxql/UEDZkvNmilf84HW+g=="
}
}
},
"@patternfly/react-icons": {
- "version": "3.15.17",
- "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-3.15.17.tgz",
- "integrity": "sha512-Q0JAlxEvSAl5kcMSUMItLiKi9fweO941g5+lS45t3o/Rv4Eg91Ig7AyK1YWw6m1ah+/eHslLfox0Uqw7m7usLg==",
- "requires": {
- "@fortawesome/free-brands-svg-icons": "^5.8.1"
- }
+ "version": "4.3.5",
+ "resolved": "https://registry.npmjs.org/@patternfly/react-icons/-/react-icons-4.3.5.tgz",
+ "integrity": "sha512-+GublxpFXR+y/5zygf9q00/LvIvso8jr0mxZGhVxsKmi2dUu7xAvN+T+5vjS9fiMbXf7WXsSPXST/UTiBIVTdQ=="
},
"@patternfly/react-styles": {
- "version": "3.7.14",
- "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-3.7.14.tgz",
- "integrity": "sha512-NVwbPP9JroulfQgj0LOLWKP4DumArW8RrP1FB1lLOCuw13KkuAcFbLN9MSF8ZBwJ8syxGEdux5mDC3jPjsrQiw==",
- "requires": {
- "camel-case": "^3.0.0",
- "css": "^2.2.3",
- "cssstyle": "^0.3.1",
- "emotion": "^9.2.9",
- "emotion-server": "^9.2.9"
- }
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@patternfly/react-styles/-/react-styles-4.4.0.tgz",
+ "integrity": "sha512-0guVqVVvLgDMKAqLM9Vb3T9sjSPBGm9DzTURuZrIz/gx9gKuckSA42OS1aTTtZLXz6ryYoOn7uQJiIhaJu1F0Q=="
},
"@patternfly/react-tokens": {
- "version": "2.8.14",
- "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-2.8.14.tgz",
- "integrity": "sha512-pha0XyZ3ZiXuQoKstuFsiEHARFQKUFsS6WxVuRSEyNbGTToRNJkKR9cW5swzHgXK6Fuw5EA2XFHLuu8osj52KA=="
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/@patternfly/react-tokens/-/react-tokens-4.5.0.tgz",
+ "integrity": "sha512-cfxWduAIIFuRnuTuTkColGCoGPmdXy2ousabpGd+Yi3vbwWcWYIRlrLuetK1VMmddnt2PW9PnaLDW6bH3+oagQ=="
},
"@sheerun/mutationobserver-shim": {
"version": "0.3.3",
@@ -2565,11 +2479,6 @@
"resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
"integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg=="
},
- "abbrev": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
- "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
- },
"accepts": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
@@ -3180,32 +3089,6 @@
"object.assign": "^4.1.0"
}
},
- "babel-plugin-emotion": {
- "version": "9.2.11",
- "resolved": "https://registry.npmjs.org/babel-plugin-emotion/-/babel-plugin-emotion-9.2.11.tgz",
- "integrity": "sha512-dgCImifnOPPSeXod2znAmgc64NhaaOjGEHROR/M+lmStb3841yK1sgaDYAYMnlvWNz8GnpwIPN0VmNpbWYZ+VQ==",
- "requires": {
- "@babel/helper-module-imports": "^7.0.0",
- "@emotion/babel-utils": "^0.6.4",
- "@emotion/hash": "^0.6.2",
- "@emotion/memoize": "^0.6.1",
- "@emotion/stylis": "^0.7.0",
- "babel-plugin-macros": "^2.0.0",
- "babel-plugin-syntax-jsx": "^6.18.0",
- "convert-source-map": "^1.5.0",
- "find-root": "^1.1.0",
- "mkdirp": "^0.5.1",
- "source-map": "^0.5.7",
- "touch": "^2.0.1"
- },
- "dependencies": {
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
- }
- }
- },
"babel-plugin-istanbul": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz",
@@ -3293,7 +3176,7 @@
},
"babel-plugin-syntax-jsx": {
"version": "6.18.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
},
"babel-plugin-syntax-object-rest-spread": {
@@ -3735,7 +3618,7 @@
},
"browserify-aes": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
"integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
"requires": {
"buffer-xor": "^1.0.3",
@@ -3769,7 +3652,7 @@
},
"browserify-rsa": {
"version": "4.0.1",
- "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+ "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"requires": {
"bn.js": "^4.1.0",
@@ -3867,11 +3750,6 @@
}
}
},
- "buffer-from": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz",
- "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg=="
- },
"buffer-indexof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
@@ -3976,15 +3854,6 @@
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
},
- "camel-case": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz",
- "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=",
- "requires": {
- "no-case": "^2.2.0",
- "upper-case": "^1.1.1"
- }
- },
"camelcase": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
@@ -4633,33 +4502,9 @@
}
}
},
- "create-emotion": {
- "version": "9.2.12",
- "resolved": "https://registry.npmjs.org/create-emotion/-/create-emotion-9.2.12.tgz",
- "integrity": "sha512-P57uOF9NL2y98Xrbl2OuiDQUZ30GVmASsv5fbsjF4Hlraip2kyAvMm+2PoYUvFFw03Fhgtxk3RqZSm2/qHL9hA==",
- "requires": {
- "@emotion/hash": "^0.6.2",
- "@emotion/memoize": "^0.6.1",
- "@emotion/stylis": "^0.7.0",
- "@emotion/unitless": "^0.6.2",
- "csstype": "^2.5.2",
- "stylis": "^3.5.0",
- "stylis-rule-sheet": "^0.0.10"
- }
- },
- "create-emotion-server": {
- "version": "9.2.12",
- "resolved": "https://registry.npmjs.org/create-emotion-server/-/create-emotion-server-9.2.12.tgz",
- "integrity": "sha512-ET+E6A5MkQTEBNDYAnjh6+0cB33qStFXhtflkZNPEaOmvzYlB/xcPnpUk4J7ul3MVa8PCQx2Ei5g2MGY/y1n+g==",
- "requires": {
- "html-tokenize": "^2.0.0",
- "multipipe": "^1.0.2",
- "through": "^2.3.8"
- }
- },
"create-hash": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
"integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"requires": {
"cipher-base": "^1.0.1",
@@ -4671,7 +4516,7 @@
},
"create-hmac": {
"version": "1.1.7",
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
"integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"requires": {
"cipher-base": "^1.0.3",
@@ -5015,14 +4860,6 @@
"resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
},
- "cssstyle": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.3.1.tgz",
- "integrity": "sha512-tNvaxM5blOnxanyxI6panOsnfiyLRj3HV4qjqqS45WPNS1usdYWRUQjqTEEELK73lpeP/1KoIGYUwrBn/VcECA==",
- "requires": {
- "cssom": "0.3.x"
- }
- },
"csstype": {
"version": "2.6.10",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
@@ -5593,7 +5430,7 @@
},
"diffie-hellman": {
"version": "5.0.3",
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
"integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"requires": {
"bn.js": "^4.1.0",
@@ -5792,43 +5629,6 @@
"resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
"integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E="
},
- "duplexer2": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
- "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
- "requires": {
- "readable-stream": "^2.0.2"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.7",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
- "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
- "requires": {
- "core-util-is": "~1.0.0",
- "inherits": "~2.0.3",
- "isarray": "~1.0.0",
- "process-nextick-args": "~2.0.0",
- "safe-buffer": "~5.1.1",
- "string_decoder": "~1.1.1",
- "util-deprecate": "~1.0.1"
- }
- },
- "string_decoder": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
- "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
- "requires": {
- "safe-buffer": "~5.1.0"
- }
- }
- }
- },
"duplexify": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
@@ -5919,23 +5719,6 @@
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q=="
},
- "emotion": {
- "version": "9.2.12",
- "resolved": "https://registry.npmjs.org/emotion/-/emotion-9.2.12.tgz",
- "integrity": "sha512-hcx7jppaI8VoXxIWEhxpDW7I+B4kq9RNzQLmsrF6LY8BGKqe2N+gFAQr0EfuFucFlPs2A9HM4+xNj4NeqEWIOQ==",
- "requires": {
- "babel-plugin-emotion": "^9.2.11",
- "create-emotion": "^9.2.12"
- }
- },
- "emotion-server": {
- "version": "9.2.12",
- "resolved": "https://registry.npmjs.org/emotion-server/-/emotion-server-9.2.12.tgz",
- "integrity": "sha512-Bhjdl7eNoIeiAVa2QPP5d+1nP/31SiO/K1P/qI9cdXCydg91NwGYmteqhhge8u7PF8fLGTEVQfcPwj21815eBw==",
- "requires": {
- "create-emotion-server": "^9.2.12"
- }
- },
"encodeurl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
@@ -6496,7 +6279,7 @@
},
"load-json-file": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"requires": {
"graceful-fs": "^4.1.2",
@@ -7145,7 +6928,8 @@
"find-root": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
- "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng=="
+ "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+ "dev": true
},
"find-up": {
"version": "2.1.0",
@@ -7220,13 +7004,6 @@
"requires": {
"tabbable": "^3.1.2",
"xtend": "^4.0.1"
- },
- "dependencies": {
- "xtend": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
- "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
- }
}
},
"follow-redirects": {
@@ -7812,7 +7589,7 @@
},
"string_decoder": {
"version": "1.1.1",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
"safe-buffer": "~5.1.0"
@@ -7892,18 +7669,6 @@
}
}
},
- "html-tokenize": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/html-tokenize/-/html-tokenize-2.0.1.tgz",
- "integrity": "sha512-QY6S+hZ0f5m1WT8WffYN+Hg+xm/w5I8XeUcAq/ZYP5wVC8xbKi4Whhru3FtrAebD5EhBW8rmFzkDI6eCAuFe2w==",
- "requires": {
- "buffer-from": "~0.1.1",
- "inherits": "~2.0.1",
- "minimist": "~1.2.5",
- "readable-stream": "~1.0.27-1",
- "through2": "~0.4.1"
- }
- },
"html-webpack-plugin": {
"version": "4.0.0-beta.11",
"resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.11.tgz",
@@ -9661,11 +9426,6 @@
"js-tokens": "^3.0.0 || ^4.0.0"
}
},
- "lower-case": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz",
- "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw="
- },
"lru-cache": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
@@ -9767,7 +9527,7 @@
},
"media-typer": {
"version": "0.3.0",
- "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
},
"mem": {
@@ -10171,15 +9931,6 @@
"resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz",
"integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE="
},
- "multipipe": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-1.0.2.tgz",
- "integrity": "sha1-zBPv2DPJzamfIk+GhGG44aP9k50=",
- "requires": {
- "duplexer2": "^0.1.2",
- "object-assign": "^4.1.0"
- }
- },
"mute-stream": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
@@ -10262,17 +10013,9 @@
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
},
- "no-case": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz",
- "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==",
- "requires": {
- "lower-case": "^1.1.1"
- }
- },
"node-fetch": {
"version": "1.6.3",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
+ "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
"integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=",
"dev": true,
"requires": {
@@ -10415,14 +10158,6 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.55.tgz",
"integrity": "sha512-H3R3YR/8TjT5WPin/wOoHOUPHgvj8leuU/Keta/rwelEQN9pA/S2Dx8/se4pZ2LBxSd0nAGzsNzhqwa77v7F1w=="
},
- "nopt": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
- "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
- "requires": {
- "abbrev": "1"
- }
- },
"normalize-package-data": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
@@ -10545,11 +10280,6 @@
"es-abstract": "^1.17.5"
}
},
- "object-keys": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
- "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY="
- },
"object-path": {
"version": "0.11.4",
"resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz",
@@ -10700,7 +10430,7 @@
"dependencies": {
"ansi-escapes": {
"version": "1.4.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
"integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
"dev": true
},
@@ -10746,7 +10476,7 @@
},
"external-editor": {
"version": "2.2.0",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
"integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"dev": true,
"requires": {
@@ -10808,7 +10538,7 @@
},
"minimist": {
"version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
@@ -10829,7 +10559,7 @@
},
"opn": {
"version": "4.0.2",
- "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
+ "resolved": "http://registry.npmjs.org/opn/-/opn-4.0.2.tgz",
"integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=",
"dev": true,
"requires": {
@@ -13284,7 +13014,7 @@
},
"readable-stream": {
"version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
"requires": {
"core-util-is": "~1.0.0",
@@ -13789,7 +13519,7 @@
},
"safe-regex": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
"integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
"requires": {
"ret": "~0.1.10"
@@ -14053,7 +13783,7 @@
},
"sha.js": {
"version": "2.4.11",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
"integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"requires": {
"inherits": "^2.0.1",
@@ -14814,7 +14544,7 @@
},
"strip-eof": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8="
},
"strip-indent": {
@@ -15133,18 +14863,9 @@
},
"through": {
"version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
},
- "through2": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/through2/-/through2-0.4.2.tgz",
- "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=",
- "requires": {
- "readable-stream": "~1.0.17",
- "xtend": "~2.1.1"
- }
- },
"thunky": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz",
@@ -15237,14 +14958,6 @@
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
},
- "touch": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/touch/-/touch-2.0.2.tgz",
- "integrity": "sha512-qjNtvsFXTRq7IuMLweVgFxmEuQ6gLbRs2jQxL80TtZ31dEKWYIxRXquij6w6VimyDek5hD3PytljHmEtAs2u0A==",
- "requires": {
- "nopt": "~1.0.10"
- }
- },
"tough-cookie": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
@@ -15458,11 +15171,6 @@
"resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz",
"integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg=="
},
- "upper-case": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz",
- "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg="
- },
"uri-js": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
@@ -16629,12 +16337,9 @@
}
},
"xtend": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
- "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
- "requires": {
- "object-keys": "~0.4.0"
- }
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
},
"y18n": {
"version": "4.0.0",
diff --git a/awx/ui_next/package.json b/awx/ui_next/package.json
index ce52806302..0dfc6ef79e 100644
--- a/awx/ui_next/package.json
+++ b/awx/ui_next/package.json
@@ -4,10 +4,9 @@
"private": true,
"dependencies": {
"@lingui/react": "^2.9.1",
- "@patternfly/patternfly": "^2.71.6",
- "@patternfly/react-core": "^3.158.1",
- "@patternfly/react-icons": "^3.15.17",
- "@patternfly/react-tokens": "^2.8.14",
+ "@patternfly/patternfly": "^4.10.31",
+ "@patternfly/react-core": "4.18.14",
+ "@patternfly/react-icons": "^4.3.5",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.3.2",
"@testing-library/user-event": "^7.1.2",
diff --git a/awx/ui_next/src/components/AlertModal/AlertModal.jsx b/awx/ui_next/src/components/AlertModal/AlertModal.jsx
index 06b6853220..0c443300be 100644
--- a/awx/ui_next/src/components/AlertModal/AlertModal.jsx
+++ b/awx/ui_next/src/components/AlertModal/AlertModal.jsx
@@ -8,6 +8,8 @@ import {
InfoCircleIcon,
TimesCircleIcon,
} from '@patternfly/react-icons';
+import { withI18n } from '@lingui/react';
+import { t } from '@lingui/macro';
import styled from 'styled-components';
const Header = styled.div`
@@ -17,11 +19,14 @@ const Header = styled.div`
}
`;
-export default function AlertModal({
+function AlertModal({
+ i18n,
isOpen = null,
title,
+ label,
variant,
children,
+ i18nHash,
...props
}) {
const variantIcons = {
@@ -60,16 +65,19 @@ export default function AlertModal({
const customHeader = (
<Header>
{variant ? variantIcons[variant] : null}
- <Title size="2xl">{title}</Title>
+ <Title id="alert-modal-header-label" size="2xl" headingLevel="h2">
+ {title}
+ </Title>
</Header>
);
return (
<Modal
header={customHeader}
- isFooterLeftAligned
+ aria-label={label || i18n._(t`Alert modal`)}
+ aria-labelledby="alert-modal-header-label"
isOpen={Boolean(isOpen)}
- isSmall
+ variant="small"
title={title}
{...props}
>
@@ -77,3 +85,5 @@ export default function AlertModal({
</Modal>
);
}
+
+export default withI18n()(AlertModal);
diff --git a/awx/ui_next/src/components/AlertModal/AlertModal.test.jsx b/awx/ui_next/src/components/AlertModal/AlertModal.test.jsx
index da8b234e5c..0173e5a378 100644
--- a/awx/ui_next/src/components/AlertModal/AlertModal.test.jsx
+++ b/awx/ui_next/src/components/AlertModal/AlertModal.test.jsx
@@ -1,11 +1,11 @@
import React from 'react';
-import { mount } from 'enzyme';
+import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
import AlertModal from './AlertModal';
describe('AlertModal', () => {
test('renders the expected content', () => {
- const wrapper = mount(
+ const wrapper = mountWithContexts(
<AlertModal title="Danger!">Are you sure?</AlertModal>
);
expect(wrapper).toHaveLength(1);
diff --git a/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx b/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx
index bd348998d1..4f49268c0a 100644
--- a/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx
+++ b/awx/ui_next/src/components/AnsibleSelect/AnsibleSelect.jsx
@@ -43,7 +43,7 @@ class AnsibleSelect extends React.Component {
onChange={this.onSelectChange}
onBlur={onBlur}
aria-label={i18n._(t`Select Input`)}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
className={className}
isDisabled={isDisabled}
>
diff --git a/awx/ui_next/src/components/AppContainer/AppContainer.jsx b/awx/ui_next/src/components/AppContainer/AppContainer.jsx
index 690d7fae72..7250bb4352 100644
--- a/awx/ui_next/src/components/AppContainer/AppContainer.jsx
+++ b/awx/ui_next/src/components/AppContainer/AppContainer.jsx
@@ -1,6 +1,5 @@
import React, { useEffect, useState } from 'react';
import { useHistory, useLocation, withRouter } from 'react-router-dom';
-import { global_breakpoint_md } from '@patternfly/react-tokens';
import {
Nav,
NavList,
@@ -41,15 +40,10 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
const [config, setConfig] = useState({});
const [configError, setConfigError] = useState(null);
const [isAboutModalOpen, setIsAboutModalOpen] = useState(false);
- const [isNavOpen, setIsNavOpen] = useState(
- typeof window !== 'undefined' &&
- window.innerWidth >= parseInt(global_breakpoint_md.value, 10)
- );
const handleAboutModalOpen = () => setIsAboutModalOpen(true);
const handleAboutModalClose = () => setIsAboutModalOpen(false);
const handleConfigErrorClose = () => setConfigError(null);
- const handleNavToggle = () => setIsNavOpen(!isNavOpen);
const handleLogout = async () => {
await RootAPI.logout();
@@ -79,10 +73,9 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
const header = (
<PageHeader
showNavToggle
- onNavToggle={handleNavToggle}
logo={<BrandLogo />}
logoProps={{ href: '/' }}
- toolbar={
+ headerTools={
<PageHeaderToolbar
loggedInUser={config?.me}
isAboutDisabled={!config?.version}
@@ -95,7 +88,6 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
const sidebar = (
<PageSidebar
- isNavOpen={isNavOpen}
theme="dark"
nav={
<Nav aria-label={i18n._(t`Navigation`)} theme="dark">
@@ -116,7 +108,7 @@ function AppContainer({ i18n, navRouteConfig = [], children }) {
return (
<>
- <Page usecondensed="True" header={header} sidebar={sidebar}>
+ <Page isManagedSidebar header={header} sidebar={sidebar}>
<ConfigProvider value={config}>{children}</ConfigProvider>
</Page>
<About
diff --git a/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx b/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx
index 229136c23b..8db7305494 100644
--- a/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx
+++ b/awx/ui_next/src/components/AppContainer/PageHeaderToolbar.jsx
@@ -7,9 +7,9 @@ import {
DropdownItem,
DropdownToggle,
DropdownPosition,
- Toolbar,
- ToolbarGroup,
- ToolbarItem,
+ PageHeaderTools,
+ PageHeaderToolsGroup,
+ PageHeaderToolsItem,
Tooltip,
} from '@patternfly/react-core';
import { QuestionCircleIcon, UserIcon } from '@patternfly/react-icons';
@@ -62,10 +62,10 @@ class PageHeaderToolbar extends Component {
} = this.props;
return (
- <Toolbar>
- <ToolbarGroup>
+ <PageHeaderTools>
+ <PageHeaderToolsGroup>
<Tooltip position="left" content={<div>{i18n._(t`Info`)}</div>}>
- <ToolbarItem>
+ <PageHeaderToolsItem>
<Dropdown
isPlain
isOpen={isHelpOpen}
@@ -93,10 +93,10 @@ class PageHeaderToolbar extends Component {
</DropdownItem>,
]}
/>
- </ToolbarItem>
+ </PageHeaderToolsItem>
</Tooltip>
<Tooltip position="left" content={<div>{i18n._(t`User`)}</div>}>
- <ToolbarItem>
+ <PageHeaderToolsItem>
<Dropdown
id="toolbar-user-dropdown"
isPlain
@@ -134,10 +134,10 @@ class PageHeaderToolbar extends Component {
</DropdownItem>,
]}
/>
- </ToolbarItem>
+ </PageHeaderToolsItem>
</Tooltip>
- </ToolbarGroup>
- </Toolbar>
+ </PageHeaderToolsGroup>
+ </PageHeaderTools>
);
}
}
diff --git a/awx/ui_next/src/components/AssociateModal/AssociateModal.jsx b/awx/ui_next/src/components/AssociateModal/AssociateModal.jsx
index 86aa534f12..e813e1f70b 100644
--- a/awx/ui_next/src/components/AssociateModal/AssociateModal.jsx
+++ b/awx/ui_next/src/components/AssociateModal/AssociateModal.jsx
@@ -74,9 +74,9 @@ function AssociateModal({
return (
<Fragment>
<Modal
- isFooterLeftAligned
- isLarge
+ variant="large"
title={title}
+ aria-label={i18n._(t`Association modal`)}
isOpen={isModalOpen}
onClose={handleClose}
actions={[
diff --git a/awx/ui_next/src/components/Background/Background.jsx b/awx/ui_next/src/components/Background/Background.jsx
index 7857a1ed54..755393712c 100644
--- a/awx/ui_next/src/components/Background/Background.jsx
+++ b/awx/ui_next/src/components/Background/Background.jsx
@@ -1,18 +1,10 @@
import React, { Fragment } from 'react';
-import { BackgroundImage, BackgroundImageSrc } from '@patternfly/react-core';
-
-const backgroundImageConfig = {
- [BackgroundImageSrc.xs]: './images/pfbg_576.jpg',
- [BackgroundImageSrc.xs2x]: './images/pfbg_576@2x.jpg',
- [BackgroundImageSrc.sm]: './images/pfbg_768.jpg',
- [BackgroundImageSrc.sm2x]: './images/pfbg_768@2x.jpg',
- [BackgroundImageSrc.lg]: './images/pfbg_2000.jpg',
-};
+import { BackgroundImage } from '@patternfly/react-core';
export default ({ children }) => (
<Fragment>
- <BackgroundImage src={backgroundImageConfig} />
+ <BackgroundImage />
{children}
</Fragment>
);
diff --git a/awx/ui_next/src/components/Background/Background.test.jsx b/awx/ui_next/src/components/Background/Background.test.jsx
index 382bdba66c..4d306f79a5 100644
--- a/awx/ui_next/src/components/Background/Background.test.jsx
+++ b/awx/ui_next/src/components/Background/Background.test.jsx
@@ -11,7 +11,7 @@ describe('Background', () => {
</Background>
);
expect(wrapper).toHaveLength(1);
- expect(wrapper.find('BackgroundImage')).toHaveLength(1);
+ expect(wrapper.find('.pf-c-background-image')).toHaveLength(1);
expect(wrapper.find('#test')).toHaveLength(1);
});
});
diff --git a/awx/ui_next/src/components/Breadcrumbs/Breadcrumbs.jsx b/awx/ui_next/src/components/Breadcrumbs/Breadcrumbs.jsx
index 670a4d01a3..93a9b3d7f4 100644
--- a/awx/ui_next/src/components/Breadcrumbs/Breadcrumbs.jsx
+++ b/awx/ui_next/src/components/Breadcrumbs/Breadcrumbs.jsx
@@ -30,19 +30,21 @@ const Breadcrumbs = ({ breadcrumbConfig }) => {
);
};
-const Crumb = ({ breadcrumbConfig }) => {
+const Crumb = ({ breadcrumbConfig, showDivider }) => {
const match = useRouteMatch();
const crumb = breadcrumbConfig[match.url];
let crumbElement = (
- <BreadcrumbItem key={match.url}>
+ <BreadcrumbItem key={match.url} showDivider={showDivider}>
<Link to={match.url}>{crumb}</Link>
</BreadcrumbItem>
);
if (match.isExact) {
crumbElement = (
- <BreadcrumbHeading key="breadcrumb-heading">{crumb}</BreadcrumbHeading>
+ <BreadcrumbHeading key="breadcrumb-heading" showDivider={showDivider}>
+ {crumb}
+ </BreadcrumbHeading>
);
}
@@ -54,7 +56,7 @@ const Crumb = ({ breadcrumbConfig }) => {
<Fragment>
{crumbElement}
<Route path={`${match.url}/:path`}>
- <Crumb breadcrumbConfig={breadcrumbConfig} />
+ <Crumb breadcrumbConfig={breadcrumbConfig} showDivider />
</Route>
</Fragment>
);
diff --git a/awx/ui_next/src/components/Card/TabbedCardHeader.js b/awx/ui_next/src/components/Card/TabbedCardHeader.js
deleted file mode 100644
index b73ea8d6c8..0000000000
--- a/awx/ui_next/src/components/Card/TabbedCardHeader.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import styled from 'styled-components';
-import { CardHeader } from '@patternfly/react-core';
-
-const TabbedCardHeader = styled(CardHeader)`
- --pf-c-card--first-child--PaddingTop: 0;
- --pf-c-card--child--PaddingLeft: 0;
- --pf-c-card--child--PaddingRight: 0;
- --pf-c-card__header--not-last-child--PaddingBottom: 24px;
- --pf-c-card__header--not-last-child--PaddingBottom: 0;
- display: flex;
-`;
-
-export default TabbedCardHeader;
diff --git a/awx/ui_next/src/components/Card/index.js b/awx/ui_next/src/components/Card/index.js
index 860e50a051..93de96efca 100644
--- a/awx/ui_next/src/components/Card/index.js
+++ b/awx/ui_next/src/components/Card/index.js
@@ -1,3 +1,2 @@
-export { default as TabbedCardHeader } from './TabbedCardHeader';
export { default as CardBody } from './CardBody';
export { default as CardActionsRow } from './CardActionsRow';
diff --git a/awx/ui_next/src/components/CardCloseButton/CardCloseButton.jsx b/awx/ui_next/src/components/CardCloseButton/CardCloseButton.jsx
deleted file mode 100644
index 987908c316..0000000000
--- a/awx/ui_next/src/components/CardCloseButton/CardCloseButton.jsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import React from 'react';
-import { string } from 'prop-types';
-import { Link } from 'react-router-dom';
-import { Button } from '@patternfly/react-core';
-import { TimesIcon } from '@patternfly/react-icons';
-import { withI18n } from '@lingui/react';
-import { t } from '@lingui/macro';
-
-function CardCloseButton({ linkTo, i18n, i18nHash, ...props }) {
- if (linkTo) {
- return (
- <Link
- className="pf-c-button pf-m-plain"
- aria-label={i18n._(t`Close`)}
- title={i18n._(t`Close`)}
- to={linkTo}
- {...props}
- >
- <TimesIcon />
- </Link>
- );
- }
- return (
- <Button variant="plain" aria-label={i18n._(t`Close`)} {...props}>
- <TimesIcon />
- </Button>
- );
-}
-CardCloseButton.propTypes = {
- linkTo: string,
-};
-CardCloseButton.defaultProps = {
- linkTo: null,
-};
-
-export default withI18n()(CardCloseButton);
diff --git a/awx/ui_next/src/components/CardCloseButton/CardCloseButton.test.jsx b/awx/ui_next/src/components/CardCloseButton/CardCloseButton.test.jsx
deleted file mode 100644
index 3564971c72..0000000000
--- a/awx/ui_next/src/components/CardCloseButton/CardCloseButton.test.jsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import React from 'react';
-import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
-import CardCloseButton from './CardCloseButton';
-
-describe('<CardCloseButton>', () => {
- test('should render close button', () => {
- const wrapper = mountWithContexts(<CardCloseButton />);
- const button = wrapper.find('Button');
- expect(button).toHaveLength(1);
- expect(button.prop('variant')).toBe('plain');
- expect(button.prop('aria-label')).toBe('Close');
- expect(wrapper.find('Link')).toHaveLength(0);
- });
-
- test('should render close link when `linkTo` prop provided', () => {
- const wrapper = mountWithContexts(<CardCloseButton linkTo="/foo" />);
- expect(wrapper.find('Button')).toHaveLength(0);
- const link = wrapper.find('Link');
- expect(link).toHaveLength(1);
- expect(link.prop('to')).toEqual('/foo');
- expect(link.prop('aria-label')).toEqual('Close');
- });
-});
diff --git a/awx/ui_next/src/components/CardCloseButton/index.js b/awx/ui_next/src/components/CardCloseButton/index.js
deleted file mode 100644
index 5f2d2157be..0000000000
--- a/awx/ui_next/src/components/CardCloseButton/index.js
+++ /dev/null
@@ -1 +0,0 @@
-export { default } from './CardCloseButton';
diff --git a/awx/ui_next/src/components/ChipGroup/ChipGroup.jsx b/awx/ui_next/src/components/ChipGroup/ChipGroup.jsx
index 972efbe5a7..c16ee052fe 100644
--- a/awx/ui_next/src/components/ChipGroup/ChipGroup.jsx
+++ b/awx/ui_next/src/components/ChipGroup/ChipGroup.jsx
@@ -4,7 +4,7 @@ import { t } from '@lingui/macro';
import { ChipGroup as PFChipGroup } from '@patternfly/react-core';
import { number, shape } from 'prop-types';
-function ChipGroup({ i18n, numChips, totalChips, ...props }) {
+function ChipGroup({ i18n, numChips, totalChips, i18nHash, ...props }) {
return (
<PFChipGroup
{...props}
diff --git a/awx/ui_next/src/components/CodeMirrorInput/VariablesDetail.jsx b/awx/ui_next/src/components/CodeMirrorInput/VariablesDetail.jsx
index 2db4da49bd..7fbcd63cfa 100644
--- a/awx/ui_next/src/components/CodeMirrorInput/VariablesDetail.jsx
+++ b/awx/ui_next/src/components/CodeMirrorInput/VariablesDetail.jsx
@@ -39,7 +39,7 @@ function VariablesDetail({ value, label, rows, fullHeight }) {
fullWidth
css="grid-column: 1 / -1"
>
- <Split gutter="sm">
+ <Split hasGutter>
<SplitItem>
<div className="pf-c-form__label">
<span
diff --git a/awx/ui_next/src/components/CodeMirrorInput/VariablesField.jsx b/awx/ui_next/src/components/CodeMirrorInput/VariablesField.jsx
index 72b4e57f17..f39d413fac 100644
--- a/awx/ui_next/src/components/CodeMirrorInput/VariablesField.jsx
+++ b/awx/ui_next/src/components/CodeMirrorInput/VariablesField.jsx
@@ -35,7 +35,7 @@ function VariablesField({
return (
<div className="pf-c-form__group">
<FieldHeader>
- <Split gutter="sm">
+ <Split hasGutter>
<SplitItem>
<label htmlFor={id} className="pf-c-form__label">
<span className="pf-c-form__label-text">{label}</span>
diff --git a/awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx b/awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx
index 4b2deab789..5f3886e20b 100644
--- a/awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx
+++ b/awx/ui_next/src/components/CodeMirrorInput/VariablesInput.jsx
@@ -35,7 +35,7 @@ function VariablesInput(props) {
return (
<div className={`pf-c-form__group ${className || ''}`}>
- <Split gutter="sm">
+ <Split hasGutter>
<SplitItem>
<label htmlFor={id} className="pf-c-form__label">
{label}
diff --git a/awx/ui_next/src/components/ContentEmpty/ContentEmpty.jsx b/awx/ui_next/src/components/ContentEmpty/ContentEmpty.jsx
index f01c8468ec..58b34e0dcd 100644
--- a/awx/ui_next/src/components/ContentEmpty/ContentEmpty.jsx
+++ b/awx/ui_next/src/components/ContentEmpty/ContentEmpty.jsx
@@ -12,7 +12,9 @@ import { CubesIcon } from '@patternfly/react-icons';
const ContentEmpty = ({ i18n, title = '', message = '' }) => (
<EmptyState variant="full">
<EmptyStateIcon icon={CubesIcon} />
- <Title size="lg">{title || i18n._(t`No items found.`)}</Title>
+ <Title size="lg" headingLevel="h3">
+ {title || i18n._(t`No items found.`)}
+ </Title>
<EmptyStateBody>{message}</EmptyStateBody>
</EmptyState>
);
diff --git a/awx/ui_next/src/components/ContentError/ContentError.jsx b/awx/ui_next/src/components/ContentError/ContentError.jsx
index f0d4f80a1d..3c56a2630d 100644
--- a/awx/ui_next/src/components/ContentError/ContentError.jsx
+++ b/awx/ui_next/src/components/ContentError/ContentError.jsx
@@ -35,7 +35,7 @@ function ContentError({ error, children, isNotFound, i18n }) {
) : (
<EmptyState variant="full">
<EmptyStateIcon icon={ExclamationTriangleIcon} />
- <Title size="lg">
+ <Title size="lg" headingLevel="h3">
{is404 ? i18n._(t`Not Found`) : i18n._(t`Something went wrong...`)}
</Title>
<EmptyStateBody>
diff --git a/awx/ui_next/src/components/CredentialChip/CredentialChip.jsx b/awx/ui_next/src/components/CredentialChip/CredentialChip.jsx
index 13576fa750..11e00ee7ed 100644
--- a/awx/ui_next/src/components/CredentialChip/CredentialChip.jsx
+++ b/awx/ui_next/src/components/CredentialChip/CredentialChip.jsx
@@ -6,7 +6,7 @@ import { Chip } from '@patternfly/react-core';
import { Credential } from '../../types';
import { toTitleCase } from '../../util/strings';
-function CredentialChip({ credential, i18n, ...props }) {
+function CredentialChip({ credential, i18n, i18nHash, ...props }) {
let type;
if (credential.cloud) {
type = i18n._(t`Cloud`);
diff --git a/awx/ui_next/src/components/DataListToolbar/DataListToolbar.jsx b/awx/ui_next/src/components/DataListToolbar/DataListToolbar.jsx
index f8b7adfa8a..7db0bae778 100644
--- a/awx/ui_next/src/components/DataListToolbar/DataListToolbar.jsx
+++ b/awx/ui_next/src/components/DataListToolbar/DataListToolbar.jsx
@@ -2,30 +2,21 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
-import { Checkbox } from '@patternfly/react-core';
-import styled from 'styled-components';
-import { SearchIcon } from '@patternfly/react-icons';
import {
- DataToolbar,
- DataToolbarContent as _DataToolbarContent,
- DataToolbarGroup as _DataToolbarGroup,
- DataToolbarItem,
- DataToolbarToggleGroup,
-} from '@patternfly/react-core/dist/umd/experimental';
+ Checkbox,
+ Toolbar,
+ ToolbarContent,
+ ToolbarGroup,
+ ToolbarItem,
+ ToolbarToggleGroup,
+} from '@patternfly/react-core';
+import { SearchIcon } from '@patternfly/react-icons';
import ExpandCollapse from '../ExpandCollapse';
import Search from '../Search';
import Sort from '../Sort';
import { SearchColumns, SortColumns, QSConfig } from '../../types';
-const DataToolbarContent = styled(_DataToolbarContent)`
- --pf-c-data-toolbar__content--PaddingLeft: 24px;
- --pf-c-data-toolbar__content--PaddingRight: 8px;
-`;
-const DataToolbarGroup = styled(_DataToolbarGroup)`
- --pf-c-data-toolbar__group--spacer: 24px;
-`;
-
class DataListToolbar extends React.Component {
render() {
const {
@@ -49,26 +40,26 @@ class DataListToolbar extends React.Component {
const showExpandCollapse = onCompact && onExpand;
return (
- <DataToolbar
+ <Toolbar
id={`${qsConfig.namespace}-list-toolbar`}
clearAllFilters={clearAllFilters}
collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
{showSelectAll && (
- <DataToolbarGroup>
- <DataToolbarItem>
+ <ToolbarGroup>
+ <ToolbarItem>
<Checkbox
isChecked={isAllSelected}
onChange={onSelectAll}
aria-label={i18n._(t`Select all`)}
id="select-all"
/>
- </DataToolbarItem>
- </DataToolbarGroup>
+ </ToolbarItem>
+ </ToolbarGroup>
)}
- <DataToolbarToggleGroup toggleIcon={<SearchIcon />} breakpoint="lg">
- <DataToolbarItem>
+ <ToolbarToggleGroup toggleIcon={<SearchIcon />} breakpoint="lg">
+ <ToolbarItem>
<Search
qsConfig={qsConfig}
columns={searchColumns}
@@ -76,31 +67,31 @@ class DataListToolbar extends React.Component {
onReplaceSearch={onReplaceSearch}
onRemove={onRemove}
/>
- </DataToolbarItem>
- <DataToolbarItem>
+ </ToolbarItem>
+ <ToolbarItem>
<Sort qsConfig={qsConfig} columns={sortColumns} onSort={onSort} />
- </DataToolbarItem>
- </DataToolbarToggleGroup>
+ </ToolbarItem>
+ </ToolbarToggleGroup>
{showExpandCollapse && (
- <DataToolbarGroup>
+ <ToolbarGroup>
<Fragment>
- <DataToolbarItem>
+ <ToolbarItem>
<ExpandCollapse
isCompact={isCompact}
onCompact={onCompact}
onExpand={onExpand}
/>
- </DataToolbarItem>
+ </ToolbarItem>
</Fragment>
- </DataToolbarGroup>
+ </ToolbarGroup>
)}
- <DataToolbarGroup>
+ <ToolbarGroup>
{additionalControls.map(control => (
- <DataToolbarItem key={control.key}>{control}</DataToolbarItem>
+ <ToolbarItem key={control.key}>{control}</ToolbarItem>
))}
- </DataToolbarGroup>
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarGroup>
+ </ToolbarContent>
+ </Toolbar>
);
}
}
diff --git a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx
index 898eef3609..cef7bf885a 100644
--- a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx
+++ b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.jsx
@@ -7,7 +7,7 @@ import { t } from '@lingui/macro';
import {
Card as PFCard,
CardBody as PFCardBody,
- Expandable as PFExpandable,
+ ExpandableSection as PFExpandable,
} from '@patternfly/react-core';
import getErrorMessage from './getErrorMessage';
diff --git a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx
index 8accea199c..f2d87cc515 100644
--- a/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx
+++ b/awx/ui_next/src/components/ErrorDetail/ErrorDetail.test.jsx
@@ -39,7 +39,7 @@ describe('ErrorDetail', () => {
}
/>
);
- wrapper.find('Expandable').prop('onToggle')();
+ wrapper.find('ExpandableSection').prop('onToggle')();
wrapper.update();
});
});
diff --git a/awx/ui_next/src/components/FormField/FormField.jsx b/awx/ui_next/src/components/FormField/FormField.jsx
index 096960ef39..0efa21887a 100644
--- a/awx/ui_next/src/components/FormField/FormField.jsx
+++ b/awx/ui_next/src/components/FormField/FormField.jsx
@@ -29,14 +29,14 @@ function FormField(props) {
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={label}
>
<FieldTooltip content={tooltip} maxWidth={tooltipMaxWidth} />
<TextArea
id={id}
isRequired={isRequired}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
resizeOrientation="vertical"
{...rest}
{...field}
@@ -51,14 +51,14 @@ function FormField(props) {
helperText={helperText}
helperTextInvalid={meta.error}
isRequired={isRequired}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={label}
>
<FieldTooltip content={tooltip} maxWidth={tooltipMaxWidth} />
<TextInput
id={id}
isRequired={isRequired}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
{...rest}
{...field}
type={type}
diff --git a/awx/ui_next/src/components/FormField/PasswordField.jsx b/awx/ui_next/src/components/FormField/PasswordField.jsx
index f65aa6d3c4..7f4954cb5b 100644
--- a/awx/ui_next/src/components/FormField/PasswordField.jsx
+++ b/awx/ui_next/src/components/FormField/PasswordField.jsx
@@ -14,7 +14,7 @@ function PasswordField(props) {
fieldId={id}
helperTextInvalid={meta.error}
isRequired={isRequired}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={label}
>
<InputGroup>
diff --git a/awx/ui_next/src/components/FormField/PasswordInput.jsx b/awx/ui_next/src/components/FormField/PasswordInput.jsx
index 993ee9a523..8fa0977f48 100644
--- a/awx/ui_next/src/components/FormField/PasswordInput.jsx
+++ b/awx/ui_next/src/components/FormField/PasswordInput.jsx
@@ -44,7 +44,7 @@ function PasswordInput(props) {
value={field.value === '$encrypted$' ? '' : field.value}
isDisabled={isDisabled}
isRequired={isRequired}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
type={inputType}
onChange={(_, event) => {
field.onChange(event);
diff --git a/awx/ui_next/src/components/HostForm/HostForm.jsx b/awx/ui_next/src/components/HostForm/HostForm.jsx
index 8fa1c63bb2..f7bf4d70c3 100644
--- a/awx/ui_next/src/components/HostForm/HostForm.jsx
+++ b/awx/ui_next/src/components/HostForm/HostForm.jsx
@@ -27,7 +27,9 @@ const InventoryLookupField = withI18n()(({ i18n, host }) => {
label={i18n._(t`Inventory`)}
isRequired
fieldId="inventory-lookup"
- isValid={!inventoryMeta.touched || !inventoryMeta.error}
+ validated={
+ !inventoryMeta.touched || !inventoryMeta.error ? 'default' : 'error'
+ }
helperTextInvalid={inventoryMeta.error}
>
<FieldTooltip
diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.jsx
index 61151e5c2e..02dc8c54b4 100644
--- a/awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.jsx
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/OtherPromptsStep.jsx
@@ -101,7 +101,7 @@ function JobTypeField({ i18n }) {
<FormGroup
fieldId="propmt-job-type"
label={i18n._(t`Job Type`)}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
>
<FieldTooltip
content={i18n._(t`For job templates, select run to execute the playbook.
@@ -132,7 +132,7 @@ function VerbosityField({ i18n }) {
return (
<FormGroup
fieldId="prompt-verbosity"
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={i18n._(t`Verbosity`)}
>
<FieldTooltip
diff --git a/awx/ui_next/src/components/LaunchPrompt/steps/SurveyStep.jsx b/awx/ui_next/src/components/LaunchPrompt/steps/SurveyStep.jsx
index 73da31f76f..aaaf0bbbee 100644
--- a/awx/ui_next/src/components/LaunchPrompt/steps/SurveyStep.jsx
+++ b/awx/ui_next/src/components/LaunchPrompt/steps/SurveyStep.jsx
@@ -96,7 +96,7 @@ function MultipleChoiceField({ question }) {
fieldId={id}
helperTextInvalid={meta.error}
isRequired={question.required}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={question.question_name}
>
<FieldTooltip content={question.question_description} />
@@ -124,7 +124,7 @@ function MultiSelectField({ question }) {
fieldId={id}
helperTextInvalid={meta.error}
isRequired={question.required}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={question.question_name}
>
<FieldTooltip content={question.question_description} />
@@ -139,7 +139,7 @@ function MultiSelectField({ question }) {
helpers.setValue(field.value.concat(option));
}
}}
- isExpanded={isOpen}
+ isOpen={isOpen}
selections={field.value}
>
{question.choices.split('\n').map(opt => (
diff --git a/awx/ui_next/src/components/ListHeader/ListHeader.jsx b/awx/ui_next/src/components/ListHeader/ListHeader.jsx
index ebc745174d..f1ac2a5ae8 100644
--- a/awx/ui_next/src/components/ListHeader/ListHeader.jsx
+++ b/awx/ui_next/src/components/ListHeader/ListHeader.jsx
@@ -2,10 +2,7 @@ import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { withRouter } from 'react-router-dom';
import styled from 'styled-components';
-import {
- DataToolbar,
- DataToolbarContent,
-} from '@patternfly/react-core/dist/umd/experimental';
+import { Toolbar, ToolbarContent } from '@patternfly/react-core';
import DataListToolbar from '../DataListToolbar';
import {
@@ -107,17 +104,17 @@ class ListHeader extends React.Component {
return (
<Fragment>
{isEmpty ? (
- <DataToolbar
+ <Toolbar
id={`${qsConfig.namespace}-list-toolbar`}
clearAllFilters={this.handleRemoveAll}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<EmptyStateControlsWrapper>
{emptyStateControls}
</EmptyStateControlsWrapper>
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarContent>
+ </Toolbar>
) : (
<Fragment>
{renderToolbar({
diff --git a/awx/ui_next/src/components/Lookup/CredentialLookup.jsx b/awx/ui_next/src/components/Lookup/CredentialLookup.jsx
index 07c85e453f..bea2317f41 100644
--- a/awx/ui_next/src/components/Lookup/CredentialLookup.jsx
+++ b/awx/ui_next/src/components/Lookup/CredentialLookup.jsx
@@ -84,7 +84,7 @@ function CredentialLookup({
<FormGroup
fieldId="credential"
isRequired={required}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={label}
helperTextInvalid={helperTextInvalid}
>
diff --git a/awx/ui_next/src/components/Lookup/Lookup.jsx b/awx/ui_next/src/components/Lookup/Lookup.jsx
index 9c0b761bb7..2662e5ab7d 100644
--- a/awx/ui_next/src/components/Lookup/Lookup.jsx
+++ b/awx/ui_next/src/components/Lookup/Lookup.jsx
@@ -142,9 +142,9 @@ function Lookup(props) {
</ChipHolder>
</InputGroup>
<Modal
- isFooterLeftAligned
- isLarge
+ variant="large"
title={i18n._(t`Select ${header || i18n._(t`Items`)}`)}
+ aria-label={i18n._(t`Lookup modal`)}
isOpen={isModalOpen}
onClose={closeModal}
actions={[
diff --git a/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx b/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx
index dedd7bc7c7..e19ea8170f 100644
--- a/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx
+++ b/awx/ui_next/src/components/Lookup/MultiCredentialsLookup.test.jsx
@@ -81,7 +81,7 @@ describe('<MultiCredentialsLookup />', () => {
});
const chip = wrapper.find('CredentialChip');
expect(chip).toHaveLength(5);
- const button = chip.at(1).find('ChipButton');
+ const button = chip.at(1).find('Chip Button');
await act(async () => {
button.invoke('onClick')();
});
diff --git a/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx b/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx
index 1290bca495..b8675b134a 100644
--- a/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx
+++ b/awx/ui_next/src/components/Lookup/OrganizationLookup.jsx
@@ -49,7 +49,7 @@ function OrganizationLookup({
fieldId="organization"
helperTextInvalid={helperTextInvalid}
isRequired={required}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={i18n._(t`Organization`)}
>
<Lookup
diff --git a/awx/ui_next/src/components/Lookup/ProjectLookup.jsx b/awx/ui_next/src/components/Lookup/ProjectLookup.jsx
index 03c6dbbbe3..b05931c151 100644
--- a/awx/ui_next/src/components/Lookup/ProjectLookup.jsx
+++ b/awx/ui_next/src/components/Lookup/ProjectLookup.jsx
@@ -63,7 +63,7 @@ function ProjectLookup({
fieldId="project"
helperTextInvalid={helperTextInvalid}
isRequired={required}
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={i18n._(t`Project`)}
>
{tooltip && <FieldTooltip content={tooltip} />}
diff --git a/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx b/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx
index 43a4b11c77..473db38932 100644
--- a/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx
+++ b/awx/ui_next/src/components/MultiSelect/TagMultiSelect.jsx
@@ -50,8 +50,8 @@ function TagMultiSelect({ onChange, value }) {
return name;
}}
selections={selections}
- isExpanded={isExpanded}
- ariaLabelledBy="tag-select"
+ isOpen={isExpanded}
+ aria-labelledby="tag-select"
>
{renderOptions(options)}
</Select>
diff --git a/awx/ui_next/src/components/MultiSelect/TagMultiSelect.test.jsx b/awx/ui_next/src/components/MultiSelect/TagMultiSelect.test.jsx
index 0e19d31c5d..a4c0a2308c 100644
--- a/awx/ui_next/src/components/MultiSelect/TagMultiSelect.test.jsx
+++ b/awx/ui_next/src/components/MultiSelect/TagMultiSelect.test.jsx
@@ -17,7 +17,7 @@ describe('<TagMultiSelect />', () => {
it('should not treat empty string as an option', () => {
const wrapper = mount(<TagMultiSelect value="" onChange={jest.fn()} />);
wrapper.find('input').simulate('focus');
- expect(wrapper.find('Select').prop('isExpanded')).toEqual(true);
+ expect(wrapper.find('Select').prop('isOpen')).toEqual(true);
expect(wrapper.find('SelectOption')).toHaveLength(0);
});
diff --git a/awx/ui_next/src/components/NotificationList/__snapshots__/NotificationListItem.test.jsx.snap b/awx/ui_next/src/components/NotificationList/__snapshots__/NotificationListItem.test.jsx.snap
index 841f4d2060..87e881c3bd 100644
--- a/awx/ui_next/src/components/NotificationList/__snapshots__/NotificationListItem.test.jsx.snap
+++ b/awx/ui_next/src/components/NotificationList/__snapshots__/NotificationListItem.test.jsx.snap
@@ -264,7 +264,7 @@ exports[`<NotificationListItem canToggleNotifications /> initially renders succe
className="pf-c-data-list__item-action sc-bwzfXH llKtln"
rowid="items-list-item-9000"
>
- <Component
+ <Switch
aria-label="Toggle notification start"
id="notification-9000-started-toggle"
isChecked={false}
@@ -273,73 +273,43 @@ exports[`<NotificationListItem canToggleNotifications /> initially renders succe
labelOff="Start"
onChange={[Function]}
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "aria-label": "Toggle notification start",
- "id": "notification-9000-started-toggle",
- "isChecked": false,
- "isDisabled": false,
- "label": "Start",
- "labelOff": "Start",
- "onChange": [Function],
- }
- }
- consumerContext={null}
+ <label
+ className="pf-c-switch"
+ data-ouia-component-id={0}
+ data-ouia-component-type="PF4/Switch"
+ data-ouia-safe={true}
+ htmlFor="notification-9000-started-toggle"
>
- <Switch
+ <input
aria-label="Toggle notification start"
- className=""
+ aria-labelledby={null}
+ checked={false}
+ className="pf-c-switch__input"
+ disabled={false}
id="notification-9000-started-toggle"
- isChecked={false}
- isDisabled={false}
- label="Start"
- labelOff="Start"
onChange={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
+ type="checkbox"
+ />
+ <span
+ className="pf-c-switch__toggle"
+ />
+ <span
+ aria-hidden="true"
+ className="pf-c-switch__label pf-m-on"
+ id={null}
>
- <label
- className="pf-c-switch"
- htmlFor="notification-9000-started-toggle"
- >
- <input
- aria-label="Toggle notification start"
- aria-labelledby={null}
- checked={false}
- className="pf-c-switch__input"
- disabled={false}
- id="notification-9000-started-toggle"
- onChange={[Function]}
- type="checkbox"
- />
- <span
- className="pf-c-switch__toggle"
- />
- <span
- aria-hidden="true"
- className="pf-c-switch__label pf-m-on"
- id={null}
- >
- Start
- </span>
- <span
- aria-hidden="true"
- className="pf-c-switch__label pf-m-off"
- id={null}
- >
- Start
- </span>
- </label>
- </Switch>
- </ComponentWithOuia>
- </Component>
- <Component
+ Start
+ </span>
+ <span
+ aria-hidden="true"
+ className="pf-c-switch__label pf-m-off"
+ id={null}
+ >
+ Start
+ </span>
+ </label>
+ </Switch>
+ <Switch
aria-label="Toggle notification success"
id="notification-9000-success-toggle"
isChecked={false}
@@ -348,73 +318,43 @@ exports[`<NotificationListItem canToggleNotifications /> initially renders succe
labelOff="Success"
onChange={[Function]}
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "aria-label": "Toggle notification success",
- "id": "notification-9000-success-toggle",
- "isChecked": false,
- "isDisabled": false,
- "label": "Success",
- "labelOff": "Success",
- "onChange": [Function],
- }
- }
- consumerContext={null}
+ <label
+ className="pf-c-switch"
+ data-ouia-component-id={1}
+ data-ouia-component-type="PF4/Switch"
+ data-ouia-safe={true}
+ htmlFor="notification-9000-success-toggle"
>
- <Switch
+ <input
aria-label="Toggle notification success"
- className=""
+ aria-labelledby={null}
+ checked={false}
+ className="pf-c-switch__input"
+ disabled={false}
id="notification-9000-success-toggle"
- isChecked={false}
- isDisabled={false}
- label="Success"
- labelOff="Success"
onChange={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
+ type="checkbox"
+ />
+ <span
+ className="pf-c-switch__toggle"
+ />
+ <span
+ aria-hidden="true"
+ className="pf-c-switch__label pf-m-on"
+ id={null}
>
- <label
- className="pf-c-switch"
- htmlFor="notification-9000-success-toggle"
- >
- <input
- aria-label="Toggle notification success"
- aria-labelledby={null}
- checked={false}
- className="pf-c-switch__input"
- disabled={false}
- id="notification-9000-success-toggle"
- onChange={[Function]}
- type="checkbox"
- />
- <span
- className="pf-c-switch__toggle"
- />
- <span
- aria-hidden="true"
- className="pf-c-switch__label pf-m-on"
- id={null}
- >
- Success
- </span>
- <span
- aria-hidden="true"
- className="pf-c-switch__label pf-m-off"
- id={null}
- >
- Success
- </span>
- </label>
- </Switch>
- </ComponentWithOuia>
- </Component>
- <Component
+ Success
+ </span>
+ <span
+ aria-hidden="true"
+ className="pf-c-switch__label pf-m-off"
+ id={null}
+ >
+ Success
+ </span>
+ </label>
+ </Switch>
+ <Switch
aria-label="Toggle notification failure"
id="notification-9000-error-toggle"
isChecked={false}
@@ -423,72 +363,42 @@ exports[`<NotificationListItem canToggleNotifications /> initially renders succe
labelOff="Failure"
onChange={[Function]}
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "aria-label": "Toggle notification failure",
- "id": "notification-9000-error-toggle",
- "isChecked": false,
- "isDisabled": false,
- "label": "Failure",
- "labelOff": "Failure",
- "onChange": [Function],
- }
- }
- consumerContext={null}
+ <label
+ className="pf-c-switch"
+ data-ouia-component-id={2}
+ data-ouia-component-type="PF4/Switch"
+ data-ouia-safe={true}
+ htmlFor="notification-9000-error-toggle"
>
- <Switch
+ <input
aria-label="Toggle notification failure"
- className=""
+ aria-labelledby={null}
+ checked={false}
+ className="pf-c-switch__input"
+ disabled={false}
id="notification-9000-error-toggle"
- isChecked={false}
- isDisabled={false}
- label="Failure"
- labelOff="Failure"
onChange={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
+ type="checkbox"
+ />
+ <span
+ className="pf-c-switch__toggle"
+ />
+ <span
+ aria-hidden="true"
+ className="pf-c-switch__label pf-m-on"
+ id={null}
>
- <label
- className="pf-c-switch"
- htmlFor="notification-9000-error-toggle"
- >
- <input
- aria-label="Toggle notification failure"
- aria-labelledby={null}
- checked={false}
- className="pf-c-switch__input"
- disabled={false}
- id="notification-9000-error-toggle"
- onChange={[Function]}
- type="checkbox"
- />
- <span
- className="pf-c-switch__toggle"
- />
- <span
- aria-hidden="true"
- className="pf-c-switch__label pf-m-on"
- id={null}
- >
- Failure
- </span>
- <span
- aria-hidden="true"
- className="pf-c-switch__label pf-m-off"
- id={null}
- >
- Failure
- </span>
- </label>
- </Switch>
- </ComponentWithOuia>
- </Component>
+ Failure
+ </span>
+ <span
+ aria-hidden="true"
+ className="pf-c-switch__label pf-m-off"
+ id={null}
+ >
+ Failure
+ </span>
+ </label>
+ </Switch>
</div>
</DataListAction>
</StyledComponent>
diff --git a/awx/ui_next/src/components/OptionsList/OptionsList.jsx b/awx/ui_next/src/components/OptionsList/OptionsList.jsx
index ea106acbf8..3ff42f9f71 100644
--- a/awx/ui_next/src/components/OptionsList/OptionsList.jsx
+++ b/awx/ui_next/src/components/OptionsList/OptionsList.jsx
@@ -18,7 +18,7 @@ import DataListToolbar from '../DataListToolbar';
import { QSConfig, SearchColumns, SortColumns } from '../../types';
const ModalList = styled.div`
- .pf-c-data-toolbar__content {
+ .pf-c-toolbar__content {
padding: 0 !important;
}
`;
diff --git a/awx/ui_next/src/components/PaginatedDataList/__snapshots__/ToolbarDeleteButton.test.jsx.snap b/awx/ui_next/src/components/PaginatedDataList/__snapshots__/ToolbarDeleteButton.test.jsx.snap
index 4894060b1a..e837c39658 100644
--- a/awx/ui_next/src/components/PaginatedDataList/__snapshots__/ToolbarDeleteButton.test.jsx.snap
+++ b/awx/ui_next/src/components/PaginatedDataList/__snapshots__/ToolbarDeleteButton.test.jsx.snap
@@ -97,51 +97,27 @@ exports[`<ToolbarDeleteButton /> should render button 1`] = `
zIndex={9999}
>
<div>
- <Component
+ <Button
aria-label="Delete"
isDisabled={true}
onClick={[Function]}
variant="danger"
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "aria-label": "Delete",
- "children": "Delete",
- "isDisabled": true,
- "onClick": [Function],
- "variant": "danger",
- }
- }
- consumerContext={null}
+ <button
+ aria-disabled={null}
+ aria-label="Delete"
+ className="pf-c-button pf-m-danger"
+ data-ouia-component-id={null}
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe={true}
+ disabled={true}
+ onClick={[Function]}
+ tabIndex={null}
+ type="button"
>
- <Button
- aria-label="Delete"
- isDisabled={true}
- onClick={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
- variant="danger"
- >
- <button
- aria-disabled={null}
- aria-label="Delete"
- className="pf-c-button pf-m-danger"
- disabled={true}
- onClick={[Function]}
- tabIndex={null}
- type="button"
- >
- Delete
- </button>
- </Button>
- </ComponentWithOuia>
- </Component>
+ Delete
+ </button>
+ </Button>
</div>
<Portal
containerInfo={
diff --git a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx
index be126a7ecc..c4f88e825a 100644
--- a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx
+++ b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessList.test.jsx
@@ -117,7 +117,7 @@ describe('<ResourceAccessList />', () => {
await sleep(0);
wrapper.update();
- const button = wrapper.find('ChipButton').at(0);
+ const button = wrapper.find('Chip Button').at(0);
button.prop('onClick')();
wrapper.update();
@@ -136,7 +136,7 @@ describe('<ResourceAccessList />', () => {
);
await sleep(0);
wrapper.update();
- const button = wrapper.find('ChipButton').at(0);
+ const button = wrapper.find('Chip Button').at(0);
button.prop('onClick')();
wrapper.update();
@@ -155,7 +155,7 @@ describe('<ResourceAccessList />', () => {
);
const button = await waitForElement(
wrapper,
- 'ChipButton',
+ 'Chip Button',
el => el.length === 2
);
button.at(0).prop('onClick')();
@@ -188,7 +188,7 @@ describe('<ResourceAccessList />', () => {
);
const button = await waitForElement(
wrapper,
- 'ChipButton',
+ 'Chip Button',
el => el.length === 2
);
button.at(1).prop('onClick')();
diff --git a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessListItem.jsx b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessListItem.jsx
index 764ca642d3..3fe656a3fb 100644
--- a/awx/ui_next/src/components/ResourceAccessList/ResourceAccessListItem.jsx
+++ b/awx/ui_next/src/components/ResourceAccessList/ResourceAccessListItem.jsx
@@ -59,10 +59,10 @@ class ResourceAccessListItem extends React.Component {
return (
<Chip
key={role.id}
- isReadOnly={!role.user_capabilities.unattach}
onClick={() => {
onRoleDelete(role, accessRecord);
}}
+ isReadOnly={!role.user_capabilities.unattach}
>
{role.name}
</Chip>
diff --git a/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap b/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap
index 64130d46bd..130f418117 100644
--- a/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap
+++ b/awx/ui_next/src/components/ResourceAccessList/__snapshots__/DeleteRoleConfirmationModal.test.jsx.snap
@@ -17,22 +17,22 @@ exports[`<DeleteRoleConfirmationModal /> should render initially 1`] = `
}
username="jane"
>
- <AlertModal
+ <WithI18n
actions={
Array [
- <Unknown
+ <Button
aria-label="Confirm delete"
onClick={[Function]}
variant="danger"
>
Delete
- </Unknown>,
- <Unknown
+ </Button>,
+ <Button
onClick={[Function]}
variant="secondary"
>
Cancel
- </Unknown>,
+ </Button>,
]
}
isOpen={true}
@@ -40,359 +40,387 @@ exports[`<DeleteRoleConfirmationModal /> should render initially 1`] = `
title="Remove Team Access"
variant="danger"
>
- <Modal
- actions={
- Array [
- <Unknown
- aria-label="Confirm delete"
- onClick={[Function]}
- variant="danger"
- >
- Delete
- </Unknown>,
- <Unknown
- onClick={[Function]}
- variant="secondary"
- >
- Cancel
- </Unknown>,
- ]
- }
- appendTo={
- <body
- class="pf-c-backdrop__open"
- >
- <div>
- <div
- class="pf-c-backdrop"
- >
- <div
- class="pf-l-bullseye"
- >
- <div
- aria-describedby="pf-modal-0"
- aria-label="Remove Team Access"
- aria-modal="true"
- class="pf-c-modal-box pf-m-sm"
- role="dialog"
- >
- <button
- aria-label="Close"
- class="pf-c-button pf-m-plain"
- type="button"
- >
- <svg
- aria-hidden="true"
- fill="currentColor"
- height="1em"
- role="img"
- style="vertical-align: -0.125em;"
- viewBox="0 0 352 512"
- width="1em"
- >
- <path
- d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
- transform=""
- />
- </svg>
- </button>
- <div
- class="pf-c-title"
- >
- <div
- class="AlertModal__Header-l9z1bu-0 hQFWHX"
- >
- <svg
- aria-hidden="true"
- class="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
- fill="currentColor"
- height="2em"
- role="img"
- style="vertical-align: -0.25em;"
- viewBox="0 0 512 512"
- width="2em"
- >
- <path
- d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
- transform=""
- />
- </svg>
- <h1
- class="pf-c-title pf-m-2xl"
- >
- Remove Team Access
- </h1>
- </div>
- </div>
- <div
- class="pf-c-modal-box__body"
- id="pf-modal-0"
- >
- Are you sure you want to remove Member access from The Team? Doing so affects all members of the team.
- <br />
- <br />
- If you only want to remove access for this particular user, please remove them from the team.
- </div>
- <div
- class="pf-c-modal-box__footer pf-m-align-left"
- >
- <button
- aria-label="Confirm delete"
- class="pf-c-button pf-m-danger"
- type="button"
- >
- Delete
- </button>
- <button
- class="pf-c-button pf-m-secondary"
- type="button"
- >
- Cancel
- </button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </body>
- }
- ariaDescribedById=""
- className=""
- header={
- <ForwardRef(AlertModal__Header)>
- <ForwardRef(AlertModal___StyledExclamationCircleIcon)
- size="lg"
- />
- <Title
- size="2xl"
- >
- Remove Team Access
- </Title>
- </ForwardRef(AlertModal__Header)>
- }
- hideTitle={false}
- isFooterLeftAligned={true}
- isLarge={false}
- isOpen={true}
- isSmall={true}
- onClose={[Function]}
- showClose={true}
- title="Remove Team Access"
+ <I18n
+ update={true}
+ withHash={true}
>
- <Portal
- containerInfo={
- <div>
- <div
- class="pf-c-backdrop"
+ <AlertModal
+ actions={
+ Array [
+ <Button
+ aria-label="Confirm delete"
+ onClick={[Function]}
+ variant="danger"
>
- <div
- class="pf-l-bullseye"
- >
- <div
- aria-describedby="pf-modal-0"
- aria-label="Remove Team Access"
- aria-modal="true"
- class="pf-c-modal-box pf-m-sm"
- role="dialog"
- >
- <button
- aria-label="Close"
- class="pf-c-button pf-m-plain"
- type="button"
- >
- <svg
- aria-hidden="true"
- fill="currentColor"
- height="1em"
- role="img"
- style="vertical-align: -0.125em;"
- viewBox="0 0 352 512"
- width="1em"
- >
- <path
- d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
- transform=""
- />
- </svg>
- </button>
- <div
- class="pf-c-title"
- >
- <div
- class="AlertModal__Header-l9z1bu-0 hQFWHX"
- >
- <svg
- aria-hidden="true"
- class="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
- fill="currentColor"
- height="2em"
- role="img"
- style="vertical-align: -0.25em;"
- viewBox="0 0 512 512"
- width="2em"
- >
- <path
- d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
- transform=""
- />
- </svg>
- <h1
- class="pf-c-title pf-m-2xl"
- >
- Remove Team Access
- </h1>
- </div>
- </div>
- <div
- class="pf-c-modal-box__body"
- id="pf-modal-0"
- >
- Are you sure you want to remove Member access from The Team? Doing so affects all members of the team.
- <br />
- <br />
- If you only want to remove access for this particular user, please remove them from the team.
- </div>
- <div
- class="pf-c-modal-box__footer pf-m-align-left"
- >
- <button
- aria-label="Confirm delete"
- class="pf-c-button pf-m-danger"
- type="button"
- >
- Delete
- </button>
- <button
- class="pf-c-button pf-m-secondary"
- type="button"
- >
- Cancel
- </button>
- </div>
- </div>
- </div>
- </div>
- </div>
+ Delete
+ </Button>,
+ <Button
+ onClick={[Function]}
+ variant="secondary"
+ >
+ Cancel
+ </Button>,
+ ]
}
+ i18n={"/i18n/"}
+ isOpen={true}
+ onClose={[Function]}
+ title="Remove Team Access"
+ variant="danger"
>
- <ModalContent
+ <Modal
actions={
Array [
- <Unknown
+ <Button
aria-label="Confirm delete"
onClick={[Function]}
variant="danger"
>
Delete
- </Unknown>,
- <Unknown
+ </Button>,
+ <Button
onClick={[Function]}
variant="secondary"
>
Cancel
- </Unknown>,
+ </Button>,
]
}
- ariaDescribedById=""
+ appendTo={
+ <body
+ class="pf-c-backdrop__open"
+ >
+ <div>
+ <div
+ class="pf-c-backdrop"
+ >
+ <div
+ class="pf-l-bullseye"
+ >
+ <div
+ aria-describedby="pf-modal-part-2"
+ aria-label="Alert modal"
+ aria-labelledby="pf-modal-part-0 alert-modal-header-label pf-modal-part-1"
+ aria-modal="true"
+ class="pf-c-modal-box pf-m-sm"
+ id="pf-modal-part-0"
+ role="dialog"
+ >
+ <button
+ aria-label="Close"
+ class="pf-c-button pf-m-plain"
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe="true"
+ type="button"
+ >
+ <svg
+ aria-hidden="true"
+ fill="currentColor"
+ height="1em"
+ role="img"
+ style="vertical-align: -0.125em;"
+ viewBox="0 0 352 512"
+ width="1em"
+ >
+ <path
+ d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
+ transform=""
+ />
+ </svg>
+ </button>
+ <header
+ class="pf-c-modal-box__header"
+ >
+ <div
+ class="AlertModal__Header-l9z1bu-0 hQFWHX"
+ >
+ <svg
+ aria-hidden="true"
+ class="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
+ fill="currentColor"
+ height="2em"
+ role="img"
+ style="vertical-align: -0.25em;"
+ viewBox="0 0 512 512"
+ width="2em"
+ >
+ <path
+ d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
+ transform=""
+ />
+ </svg>
+ <h2
+ class="pf-c-title pf-m-2xl"
+ id="alert-modal-header-label"
+ >
+ Remove Team Access
+ </h2>
+ </div>
+ </header>
+ <div
+ class="pf-c-modal-box__body"
+ id="pf-modal-part-2"
+ >
+ Are you sure you want to remove Member access from The Team? Doing so affects all members of the team.
+ <br />
+ <br />
+ If you only want to remove access for this particular user, please remove them from the team.
+ </div>
+ <footer
+ class="pf-c-modal-box__footer"
+ >
+ <button
+ aria-label="Confirm delete"
+ class="pf-c-button pf-m-danger"
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe="true"
+ type="button"
+ >
+ Delete
+ </button>
+ <button
+ class="pf-c-button pf-m-secondary"
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe="true"
+ type="button"
+ >
+ Cancel
+ </button>
+ </footer>
+ </div>
+ </div>
+ </div>
+ </div>
+ </body>
+ }
+ aria-describedby=""
+ aria-label="Alert modal"
+ aria-labelledby="alert-modal-header-label"
className=""
+ hasNoBodyWrapper={false}
header={
<ForwardRef(AlertModal__Header)>
<ForwardRef(AlertModal___StyledExclamationCircleIcon)
size="lg"
/>
<Title
+ headingLevel="h2"
+ id="alert-modal-header-label"
size="2xl"
>
Remove Team Access
</Title>
</ForwardRef(AlertModal__Header)>
}
- hideTitle={false}
- id="pf-modal-0"
- isFooterLeftAligned={true}
- isLarge={false}
isOpen={true}
- isSmall={true}
onClose={[Function]}
showClose={true}
title="Remove Team Access"
+ variant="small"
>
- <Backdrop>
- <div
- className="pf-c-backdrop"
- >
- <FocusTrap
- active={true}
- className="pf-l-bullseye"
- focusTrapOptions={
- Object {
- "clickOutsideDeactivates": true,
- }
- }
- paused={false}
- >
+ <Portal
+ containerInfo={
+ <div>
<div
- className="pf-l-bullseye"
+ class="pf-c-backdrop"
>
- <ModalBox
- className=""
- id="pf-modal-0"
- isLarge={false}
- isSmall={true}
- style={Object {}}
- title="Remove Team Access"
+ <div
+ class="pf-l-bullseye"
>
<div
- aria-describedby="pf-modal-0"
- aria-label="Remove Team Access"
+ aria-describedby="pf-modal-part-2"
+ aria-label="Alert modal"
+ aria-labelledby="pf-modal-part-0 alert-modal-header-label pf-modal-part-1"
aria-modal="true"
- className="pf-c-modal-box pf-m-sm"
+ class="pf-c-modal-box pf-m-sm"
+ id="pf-modal-part-0"
role="dialog"
- style={Object {}}
>
- <ModalBoxCloseButton
- onClose={[Function]}
+ <button
+ aria-label="Close"
+ class="pf-c-button pf-m-plain"
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe="true"
+ type="button"
>
- <Component
- aria-label="Close"
- className=""
- onClick={[Function]}
- variant="plain"
+ <svg
+ aria-hidden="true"
+ fill="currentColor"
+ height="1em"
+ role="img"
+ style="vertical-align: -0.125em;"
+ viewBox="0 0 352 512"
+ width="1em"
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "aria-label": "Close",
- "children": <TimesIcon
- color="currentColor"
- noVerticalAlign={false}
- size="sm"
- title={null}
- />,
- "className": "",
- "onClick": [Function],
- "variant": "plain",
- }
- }
- consumerContext={null}
+ <path
+ d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
+ transform=""
+ />
+ </svg>
+ </button>
+ <header
+ class="pf-c-modal-box__header"
+ >
+ <div
+ class="AlertModal__Header-l9z1bu-0 hQFWHX"
+ >
+ <svg
+ aria-hidden="true"
+ class="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
+ fill="currentColor"
+ height="2em"
+ role="img"
+ style="vertical-align: -0.25em;"
+ viewBox="0 0 512 512"
+ width="2em"
+ >
+ <path
+ d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
+ transform=""
+ />
+ </svg>
+ <h2
+ class="pf-c-title pf-m-2xl"
+ id="alert-modal-header-label"
+ >
+ Remove Team Access
+ </h2>
+ </div>
+ </header>
+ <div
+ class="pf-c-modal-box__body"
+ id="pf-modal-part-2"
+ >
+ Are you sure you want to remove Member access from The Team? Doing so affects all members of the team.
+ <br />
+ <br />
+ If you only want to remove access for this particular user, please remove them from the team.
+ </div>
+ <footer
+ class="pf-c-modal-box__footer"
+ >
+ <button
+ aria-label="Confirm delete"
+ class="pf-c-button pf-m-danger"
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe="true"
+ type="button"
+ >
+ Delete
+ </button>
+ <button
+ class="pf-c-button pf-m-secondary"
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe="true"
+ type="button"
+ >
+ Cancel
+ </button>
+ </footer>
+ </div>
+ </div>
+ </div>
+ </div>
+ }
+ >
+ <ModalContent
+ actions={
+ Array [
+ <Button
+ aria-label="Confirm delete"
+ onClick={[Function]}
+ variant="danger"
+ >
+ Delete
+ </Button>,
+ <Button
+ onClick={[Function]}
+ variant="secondary"
+ >
+ Cancel
+ </Button>,
+ ]
+ }
+ aria-describedby=""
+ aria-label="Alert modal"
+ aria-labelledby="alert-modal-header-label"
+ boxId="pf-modal-part-0"
+ className=""
+ descriptorId="pf-modal-part-2"
+ hasNoBodyWrapper={false}
+ header={
+ <ForwardRef(AlertModal__Header)>
+ <ForwardRef(AlertModal___StyledExclamationCircleIcon)
+ size="lg"
+ />
+ <Title
+ headingLevel="h2"
+ id="alert-modal-header-label"
+ size="2xl"
+ >
+ Remove Team Access
+ </Title>
+ </ForwardRef(AlertModal__Header)>
+ }
+ isOpen={true}
+ labelId="pf-modal-part-1"
+ onClose={[Function]}
+ showClose={true}
+ title="Remove Team Access"
+ variant="small"
+ >
+ <Backdrop>
+ <div
+ className="pf-c-backdrop"
+ >
+ <FocusTrap
+ active={true}
+ className="pf-l-bullseye"
+ focusTrapOptions={
+ Object {
+ "clickOutsideDeactivates": true,
+ }
+ }
+ paused={false}
+ >
+ <div
+ className="pf-l-bullseye"
+ >
+ <ModalBox
+ aria-describedby="pf-modal-part-2"
+ aria-label="Alert modal"
+ aria-labelledby="pf-modal-part-0 alert-modal-header-label pf-modal-part-1"
+ className=""
+ id="pf-modal-part-0"
+ style={Object {}}
+ variant="small"
+ >
+ <div
+ aria-describedby="pf-modal-part-2"
+ aria-label="Alert modal"
+ aria-labelledby="pf-modal-part-0 alert-modal-header-label pf-modal-part-1"
+ aria-modal="true"
+ className="pf-c-modal-box pf-m-sm"
+ id="pf-modal-part-0"
+ role="dialog"
+ style={Object {}}
+ >
+ <ModalBoxCloseButton
+ onClose={[Function]}
>
<Button
aria-label="Close"
className=""
onClick={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
variant="plain"
>
<button
aria-disabled={null}
aria-label="Close"
className="pf-c-button pf-m-plain"
+ data-ouia-component-id={null}
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe={true}
disabled={false}
onClick={[Function]}
tabIndex={null}
@@ -402,7 +430,6 @@ exports[`<DeleteRoleConfirmationModal /> should render initially 1`] = `
color="currentColor"
noVerticalAlign={false}
size="sm"
- title={null}
>
<svg
aria-hidden={true}
@@ -426,165 +453,145 @@ exports[`<DeleteRoleConfirmationModal /> should render initially 1`] = `
</TimesIcon>
</button>
</Button>
- </ComponentWithOuia>
- </Component>
- </ModalBoxCloseButton>
- <div
- className="pf-c-title"
- >
- <AlertModal__Header>
- <StyledComponent
- forwardedComponent={
- Object {
- "$$typeof": Symbol(react.forward_ref),
- "attrs": Array [],
- "componentStyle": ComponentStyle {
- "componentId": "AlertModal__Header-l9z1bu-0",
- "isStatic": false,
- "lastClassName": "hQFWHX",
- "rules": Array [
- "display:flex;svg{margin-right:16px;}",
- ],
- },
- "displayName": "AlertModal__Header",
- "foldedComponentIds": Array [],
- "render": [Function],
- "styledComponentId": "AlertModal__Header-l9z1bu-0",
- "target": "div",
- "toString": [Function],
- "warnTooManyClasses": [Function],
- "withComponent": [Function],
- }
- }
- forwardedRef={null}
- >
- <div
- className="AlertModal__Header-l9z1bu-0 hQFWHX"
+ </ModalBoxCloseButton>
+ <ModalBoxHeader>
+ <header
+ className="pf-c-modal-box__header"
>
- <AlertModal___StyledExclamationCircleIcon
- size="lg"
- >
+ <AlertModal__Header>
<StyledComponent
forwardedComponent={
Object {
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
- "componentId": "AlertModal___StyledExclamationCircleIcon-l9z1bu-1",
+ "componentId": "AlertModal__Header-l9z1bu-0",
"isStatic": false,
- "lastClassName": "jOhcwt",
+ "lastClassName": "hQFWHX",
"rules": Array [
- "color:var(--pf-global--danger-color--100)",
+ "display:flex;svg{margin-right:16px;}",
],
},
- "displayName": "AlertModal___StyledExclamationCircleIcon",
+ "displayName": "AlertModal__Header",
"foldedComponentIds": Array [],
"render": [Function],
- "styledComponentId": "AlertModal___StyledExclamationCircleIcon-l9z1bu-1",
- "target": [Function],
+ "styledComponentId": "AlertModal__Header-l9z1bu-0",
+ "target": "div",
"toString": [Function],
"warnTooManyClasses": [Function],
"withComponent": [Function],
}
}
forwardedRef={null}
- size="lg"
>
- <ExclamationCircleIcon
- className="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
- color="currentColor"
- noVerticalAlign={false}
- size="lg"
- title={null}
+ <div
+ className="AlertModal__Header-l9z1bu-0 hQFWHX"
>
- <svg
- aria-hidden={true}
- aria-labelledby={null}
- className="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
- fill="currentColor"
- height="2em"
- role="img"
- style={
- Object {
- "verticalAlign": "-0.25em",
+ <AlertModal___StyledExclamationCircleIcon
+ size="lg"
+ >
+ <StyledComponent
+ forwardedComponent={
+ Object {
+ "$$typeof": Symbol(react.forward_ref),
+ "attrs": Array [],
+ "componentStyle": ComponentStyle {
+ "componentId": "AlertModal___StyledExclamationCircleIcon-l9z1bu-1",
+ "isStatic": false,
+ "lastClassName": "jOhcwt",
+ "rules": Array [
+ "color:var(--pf-global--danger-color--100)",
+ ],
+ },
+ "displayName": "AlertModal___StyledExclamationCircleIcon",
+ "foldedComponentIds": Array [],
+ "render": [Function],
+ "styledComponentId": "AlertModal___StyledExclamationCircleIcon-l9z1bu-1",
+ "target": [Function],
+ "toString": [Function],
+ "warnTooManyClasses": [Function],
+ "withComponent": [Function],
+ }
}
- }
- viewBox="0 0 512 512"
- width="2em"
+ forwardedRef={null}
+ size="lg"
+ >
+ <ExclamationCircleIcon
+ className="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
+ color="currentColor"
+ noVerticalAlign={false}
+ size="lg"
+ >
+ <svg
+ aria-hidden={true}
+ aria-labelledby={null}
+ className="AlertModal___StyledExclamationCircleIcon-l9z1bu-1 jOhcwt"
+ fill="currentColor"
+ height="2em"
+ role="img"
+ style={
+ Object {
+ "verticalAlign": "-0.25em",
+ }
+ }
+ viewBox="0 0 512 512"
+ width="2em"
+ >
+ <path
+ d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
+ transform=""
+ />
+ </svg>
+ </ExclamationCircleIcon>
+ </StyledComponent>
+ </AlertModal___StyledExclamationCircleIcon>
+ <Title
+ headingLevel="h2"
+ id="alert-modal-header-label"
+ size="2xl"
>
- <path
- d="M504 256c0 136.997-111.043 248-248 248S8 392.997 8 256C8 119.083 119.043 8 256 8s248 111.083 248 248zm-248 50c-25.405 0-46 20.595-46 46s20.595 46 46 46 46-20.595 46-46-20.595-46-46-46zm-43.673-165.346l7.418 136c.347 6.364 5.609 11.346 11.982 11.346h48.546c6.373 0 11.635-4.982 11.982-11.346l7.418-136c.375-6.874-5.098-12.654-11.982-12.654h-63.383c-6.884 0-12.356 5.78-11.981 12.654z"
- transform=""
- />
- </svg>
- </ExclamationCircleIcon>
+ <h2
+ className="pf-c-title pf-m-2xl"
+ id="alert-modal-header-label"
+ >
+ Remove Team Access
+ </h2>
+ </Title>
+ </div>
</StyledComponent>
- </AlertModal___StyledExclamationCircleIcon>
- <Title
- size="2xl"
- >
- <h1
- className="pf-c-title pf-m-2xl"
- >
- Remove Team Access
- </h1>
- </Title>
- </div>
- </StyledComponent>
- </AlertModal__Header>
- </div>
- <ModalBoxBody
- id="pf-modal-0"
- >
- <div
- className="pf-c-modal-box__body"
- id="pf-modal-0"
- >
- Are you sure you want to remove Member access from The Team? Doing so affects all members of the team.
- <br />
- <br />
- If you only want to remove access for this particular user, please remove them from the team.
- </div>
- </ModalBoxBody>
- <ModalBoxFooter
- isLeftAligned={true}
- >
- <div
- className="pf-c-modal-box__footer pf-m-align-left"
- >
- <Component
- aria-label="Confirm delete"
- key="delete"
- onClick={[Function]}
- variant="danger"
+ </AlertModal__Header>
+ </header>
+ </ModalBoxHeader>
+ <ModalBoxBody
+ id="pf-modal-part-2"
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "aria-label": "Confirm delete",
- "children": "Delete",
- "onClick": [Function],
- "variant": "danger",
- }
- }
- consumerContext={null}
+ <div
+ className="pf-c-modal-box__body"
+ id="pf-modal-part-2"
+ >
+ Are you sure you want to remove Member access from The Team? Doing so affects all members of the team.
+ <br />
+ <br />
+ If you only want to remove access for this particular user, please remove them from the team.
+ </div>
+ </ModalBoxBody>
+ <ModalBoxFooter>
+ <footer
+ className="pf-c-modal-box__footer"
>
<Button
aria-label="Confirm delete"
+ key="delete"
onClick={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
variant="danger"
>
<button
aria-disabled={null}
aria-label="Confirm delete"
className="pf-c-button pf-m-danger"
+ data-ouia-component-id={null}
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe={true}
disabled={false}
onClick={[Function]}
tabIndex={null}
@@ -593,38 +600,18 @@ exports[`<DeleteRoleConfirmationModal /> should render initially 1`] = `
Delete
</button>
</Button>
- </ComponentWithOuia>
- </Component>
- <Component
- key="cancel"
- onClick={[Function]}
- variant="secondary"
- >
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "children": "Cancel",
- "onClick": [Function],
- "variant": "secondary",
- }
- }
- consumerContext={null}
- >
<Button
+ key="cancel"
onClick={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
variant="secondary"
>
<button
aria-disabled={null}
aria-label={null}
className="pf-c-button pf-m-secondary"
+ data-ouia-component-id={null}
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe={true}
disabled={false}
onClick={[Function]}
tabIndex={null}
@@ -633,19 +620,19 @@ exports[`<DeleteRoleConfirmationModal /> should render initially 1`] = `
Cancel
</button>
</Button>
- </ComponentWithOuia>
- </Component>
+ </footer>
+ </ModalBoxFooter>
</div>
- </ModalBoxFooter>
+ </ModalBox>
</div>
- </ModalBox>
+ </FocusTrap>
</div>
- </FocusTrap>
- </div>
- </Backdrop>
- </ModalContent>
- </Portal>
- </Modal>
- </AlertModal>
+ </Backdrop>
+ </ModalContent>
+ </Portal>
+ </Modal>
+ </AlertModal>
+ </I18n>
+ </WithI18n>
</DeleteRoleConfirmationModal>
`;
diff --git a/awx/ui_next/src/components/ResourceAccessList/__snapshots__/ResourceAccessListItem.test.jsx.snap b/awx/ui_next/src/components/ResourceAccessList/__snapshots__/ResourceAccessListItem.test.jsx.snap
index bfe1711fe8..f26a2377cb 100644
--- a/awx/ui_next/src/components/ResourceAccessList/__snapshots__/ResourceAccessListItem.test.jsx.snap
+++ b/awx/ui_next/src/components/ResourceAccessList/__snapshots__/ResourceAccessListItem.test.jsx.snap
@@ -92,12 +92,17 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
numChips={5}
totalChips={1}
>
- <Unknown
+ <Chip
+ className=""
+ closeBtnAriaLabel="close"
+ component="div"
+ isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
+ tooltipPosition="top"
>
Member
- </Unknown>
+ </Chip>
</WithI18n>
}
/>
@@ -151,12 +156,17 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
numChips={5}
totalChips={1}
>
- <Unknown
+ <Chip
+ className=""
+ closeBtnAriaLabel="close"
+ component="div"
+ isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
+ tooltipPosition="top"
>
Member
- </Unknown>
+ </Chip>
</WithI18n>
}
/>
@@ -233,12 +243,17 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
numChips={5}
totalChips={1}
>
- <Unknown
+ <Chip
+ className=""
+ closeBtnAriaLabel="close"
+ component="div"
+ isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
+ tooltipPosition="top"
>
Member
- </Unknown>
+ </Chip>
</WithI18n>
}
/>
@@ -661,12 +676,17 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
numChips={5}
totalChips={1}
>
- <Unknown
+ <Chip
+ className=""
+ closeBtnAriaLabel="close"
+ component="div"
+ isOverflowChip={false}
isReadOnly={false}
onClick={[Function]}
+ tooltipPosition="top"
>
Member
- </Unknown>
+ </Chip>
</WithI18n>
}
>
@@ -801,175 +821,113 @@ exports[`<ResourceAccessListItem /> initially renders succesfully 1`] = `
totalChips={1}
>
<ChipGroup
- className=""
+ aria-label="Chip group category"
+ categoryName=""
+ closeBtnAriaLabel="Close chip group"
collapsedText="-4 more"
defaultIsOpen={false}
expandedText="Show less"
+ isClosable={false}
numChips={5}
- withToolbar={false}
+ onClick={[Function]}
+ tooltipPosition="top"
>
- <ul
- className="pf-c-chip-group"
+ <GenerateId
+ prefix="pf-random-id-"
>
- <InnerChipGroup
- className=""
- collapsedText="-4 more"
- defaultIsOpen={false}
- expandedText="Show less"
- isOpen={false}
- numChips={5}
- onToggleCollapse={[Function]}
- withToolbar={false}
+ <div
+ className="pf-c-chip-group"
>
- <Component
- component="li"
- isReadOnly={false}
- key=".$3"
- onClick={[Function]}
+ <ul
+ aria-label="Chip group category"
+ className="pf-c-chip-group__list"
+ role="list"
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "children": "Member",
- "component": "li",
- "isReadOnly": false,
- "onClick": [Function],
- }
- }
- consumerContext={null}
+ <li
+ className="pf-c-chip-group__list-item"
+ key="0"
>
<Chip
className=""
closeBtnAriaLabel="close"
- component="li"
+ component="div"
isOverflowChip={false}
isReadOnly={false}
+ key=".$3"
onClick={[Function]}
- ouiaContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
tooltipPosition="top"
>
<GenerateId
prefix="pf-random-id-"
>
- <li
+ <div
className="pf-c-chip"
+ data-ouia-component-id={1}
+ data-ouia-component-type="PF4/Chip"
+ data-ouia-safe={true}
>
<span
className="pf-c-chip__text"
- id="pf-random-id-0"
+ id="pf-random-id-1"
>
Member
</span>
- <ChipButton
- aria-labelledby="remove_pf-random-id-0 pf-random-id-0"
- ariaLabel="close"
- id="remove_pf-random-id-0"
+ <Button
+ aria-label="close"
+ aria-labelledby="remove_pf-random-id-1 pf-random-id-1"
+ id="remove_pf-random-id-1"
onClick={[Function]}
+ variant="plain"
>
- <Component
+ <button
+ aria-disabled={null}
aria-label="close"
- aria-labelledby="remove_pf-random-id-0 pf-random-id-0"
- className=""
- id="remove_pf-random-id-0"
+ aria-labelledby="remove_pf-random-id-1 pf-random-id-1"
+ className="pf-c-button pf-m-plain"
+ data-ouia-component-id={null}
+ data-ouia-component-type="PF4/Button"
+ data-ouia-safe={true}
+ disabled={false}
+ id="remove_pf-random-id-1"
onClick={[Function]}
- variant="plain"
+ tabIndex={null}
+ type="button"
>
- <ComponentWithOuia
- component={[Function]}
- componentProps={
- Object {
- "aria-label": "close",
- "aria-labelledby": "remove_pf-random-id-0 pf-random-id-0",
- "children": <TimesCircleIcon
- aria-hidden="true"
- color="currentColor"
- noVerticalAlign={false}
- size="sm"
- title={null}
- />,
- "className": "",
- "id": "remove_pf-random-id-0",
- "onClick": [Function],
- "variant": "plain",
- }
- }
- consumerContext={
- Object {
- "isOuia": false,
- "ouiaId": null,
- }
- }
+ <TimesIcon
+ aria-hidden="true"
+ color="currentColor"
+ noVerticalAlign={false}
+ size="sm"
>
- <Button
- aria-label="close"
- aria-labelledby="remove_pf-random-id-0 pf-random-id-0"
- className=""
- id="remove_pf-random-id-0"
- onClick={[Function]}
- ouiaContext={
+ <svg
+ aria-hidden="true"
+ aria-labelledby={null}
+ fill="currentColor"
+ height="1em"
+ role="img"
+ style={
Object {
- "isOuia": false,
- "ouiaId": null,
+ "verticalAlign": "-0.125em",
}
}
- variant="plain"
+ viewBox="0 0 352 512"
+ width="1em"
>
- <button
- aria-disabled={null}
- aria-label="close"
- aria-labelledby="remove_pf-random-id-0 pf-random-id-0"
- className="pf-c-button pf-m-plain"
- disabled={false}
- id="remove_pf-random-id-0"
- onClick={[Function]}
- tabIndex={null}
- type="button"
- >
- <TimesCircleIcon
- aria-hidden="true"
- color="currentColor"
- noVerticalAlign={false}
- size="sm"
- title={null}
- >
- <svg
- aria-hidden="true"
- aria-labelledby={null}
- fill="currentColor"
- height="1em"
- role="img"
- style={
- Object {
- "verticalAlign": "-0.125em",
- }
- }
- viewBox="0 0 512 512"
- width="1em"
- >
- <path
- d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm121.6 313.1c4.7 4.7 4.7 12.3 0 17L338 377.6c-4.7 4.7-12.3 4.7-17 0L256 312l-65.1 65.6c-4.7 4.7-12.3 4.7-17 0L134.4 338c-4.7-4.7-4.7-12.3 0-17l65.6-65-65.6-65.1c-4.7-4.7-4.7-12.3 0-17l39.6-39.6c4.7-4.7 12.3-4.7 17 0l65 65.7 65.1-65.6c4.7-4.7 12.3-4.7 17 0l39.6 39.6c4.7 4.7 4.7 12.3 0 17L312 256l65.6 65.1z"
- transform=""
- />
- </svg>
- </TimesCircleIcon>
- </button>
- </Button>
- </ComponentWithOuia>
- </Component>
- </ChipButton>
- </li>
+ <path
+ d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
+ transform=""
+ />
+ </svg>
+ </TimesIcon>
+ </button>
+ </Button>
+ </div>
</GenerateId>
</Chip>
- </ComponentWithOuia>
- </Component>
- </InnerChipGroup>
- </ul>
+ </li>
+ </ul>
+ </div>
+ </GenerateId>
</ChipGroup>
</ChipGroup>
</I18n>
diff --git a/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx b/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx
index a41ac3ea0a..700077e88c 100644
--- a/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx
+++ b/awx/ui_next/src/components/RoutedTabs/RoutedTabs.jsx
@@ -1,6 +1,6 @@
import React from 'react';
import { shape, string, number, arrayOf, node, oneOfType } from 'prop-types';
-import { Tab, Tabs } from '@patternfly/react-core';
+import { Tab, Tabs, TabTitleText } from '@patternfly/react-core';
import { useHistory } from 'react-router-dom';
function RoutedTabs(props) {
@@ -36,7 +36,7 @@ function RoutedTabs(props) {
eventKey={tab.id}
key={tab.id}
link={tab.link}
- title={tab.name}
+ title={<TabTitleText>{tab.name}</TabTitleText>}
/>
))}
</Tabs>
diff --git a/awx/ui_next/src/components/Schedule/Schedule.jsx b/awx/ui_next/src/components/Schedule/Schedule.jsx
index 260655f27c..ffa28dd35f 100644
--- a/awx/ui_next/src/components/Schedule/Schedule.jsx
+++ b/awx/ui_next/src/components/Schedule/Schedule.jsx
@@ -10,13 +10,10 @@ import {
useLocation,
useParams,
} from 'react-router-dom';
-import { CardActions } from '@patternfly/react-core';
import { CaretLeftIcon } from '@patternfly/react-icons';
-import CardCloseButton from '../CardCloseButton';
import RoutedTabs from '../RoutedTabs';
import ContentError from '../ContentError';
import ContentLoading from '../ContentLoading';
-import { TabbedCardHeader } from '../Card';
import ScheduleDetail from './ScheduleDetail';
import ScheduleEdit from './ScheduleEdit';
import { SchedulesAPI } from '../../api';
@@ -90,23 +87,17 @@ function Schedule({ i18n, setBreadcrumb, unifiedJobTemplate }) {
return <ContentError error={contentError} />;
}
- let cardHeader = null;
+ let showCardHeader = true;
+
if (
- location.pathname.includes('schedules/') &&
- !location.pathname.endsWith('edit')
+ !location.pathname.includes('schedules/') ||
+ location.pathname.endsWith('edit')
) {
- cardHeader = (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo={`${pathRoot}schedules`} />
- </CardActions>
- </TabbedCardHeader>
- );
+ showCardHeader = false;
}
return (
<>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from={`${pathRoot}schedules/:scheduleId`}
diff --git a/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx b/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx
index 354a283b09..64b8863fe6 100644
--- a/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx
+++ b/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.jsx
@@ -24,6 +24,7 @@ import ChipGroup from '../../ChipGroup';
const PromptTitle = styled(Title)`
--pf-c-title--m-md--FontWeight: 700;
+ grid-column: 1 / -1;
`;
function ScheduleDetail({ schedule, i18n }) {
@@ -140,7 +141,7 @@ function ScheduleDetail({ schedule, i18n }) {
/>
{showPromptedFields && (
<>
- <PromptTitle size="md" css="grid-column: 1 / -1;">
+ <PromptTitle headingLevel="h2">
{i18n._(t`Prompted Fields`)}
</PromptTitle>
<Detail label={i18n._(t`Job Type`)} value={job_type} />
diff --git a/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.test.jsx b/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.test.jsx
index a1739e8c3a..fe9175c6de 100644
--- a/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.test.jsx
+++ b/awx/ui_next/src/components/Schedule/ScheduleDetail/ScheduleDetail.test.jsx
@@ -136,7 +136,7 @@ describe('<ScheduleDetail />', () => {
expect(wrapper.find('Detail[label="Skip Tags"]').length).toBe(0);
});
test('details should render with the proper values with prompts', async () => {
- SchedulesAPI.readCredentials.mockResolvedValueOnce({
+ SchedulesAPI.readCredentials.mockResolvedValue({
data: {
count: 2,
results: [
@@ -182,6 +182,7 @@ describe('<ScheduleDetail />', () => {
);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
+ // await waitForElement(wrapper, 'Title', el => el.length > 0);
expect(
wrapper
.find('Detail[label="Name"]')
diff --git a/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.jsx b/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.jsx
index fa7627fddd..5203c149c7 100644
--- a/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.jsx
+++ b/awx/ui_next/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.jsx
@@ -36,7 +36,7 @@ function ScheduleOccurrences({ preview = { local: [], utc: [] }, i18n }) {
fullWidth
css="grid-column: 1 / -1"
>
- <Split gutter="sm">
+ <Split hasGutter>
<SplitItem>
<OccurrencesLabel>
<span>{i18n._(t`Occurrences`)}</span>
diff --git a/awx/ui_next/src/components/Schedule/shared/FrequencyDetailSubform.jsx b/awx/ui_next/src/components/Schedule/shared/FrequencyDetailSubform.jsx
index d40976e26a..8e6ea219c0 100644
--- a/awx/ui_next/src/components/Schedule/shared/FrequencyDetailSubform.jsx
+++ b/awx/ui_next/src/components/Schedule/shared/FrequencyDetailSubform.jsx
@@ -231,7 +231,9 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-run-every"
helperTextInvalid={intervalMeta.error}
isRequired
- isValid={!intervalMeta.touched || !intervalMeta.error}
+ validated={
+ !intervalMeta.touched || !intervalMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`Run every`)}
>
<div css="display: flex">
@@ -255,7 +257,11 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-days-of-week"
helperTextInvalid={daysOfWeekMeta.error}
isRequired
- isValid={!daysOfWeekMeta.touched || !daysOfWeekMeta.error}
+ validated={
+ !daysOfWeekMeta.touched || !daysOfWeekMeta.error
+ ? 'default'
+ : 'error'
+ }
label={i18n._(t`On days`)}
>
<div css="display: flex">
@@ -339,7 +345,9 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-run-on"
helperTextInvalid={runOnMeta.error}
isRequired
- isValid={!runOnMeta.touched || !runOnMeta.error}
+ validated={
+ !runOnMeta.touched || !runOnMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`Run on`)}
>
<RunOnRadio
@@ -502,7 +510,7 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-end"
helperTextInvalid={endMeta.error}
isRequired
- isValid={!endMeta.touched || !endMeta.error}
+ validated={!endMeta.touched || !endMeta.error ? 'default' : 'error'}
label={i18n._(t`End`)}
>
<Radio
@@ -556,7 +564,11 @@ const FrequencyDetailSubform = ({ i18n }) => {
fieldId="schedule-end-datetime"
helperTextInvalid={endDateTimeMeta.error}
isRequired
- isValid={!endDateTimeMeta.touched || !endDateTimeMeta.error}
+ validated={
+ !endDateTimeMeta.touched || !endDateTimeMeta.error
+ ? 'default'
+ : 'error'
+ }
label={i18n._(t`End date/time`)}
>
<input
diff --git a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx
index 795af0035a..756e400258 100644
--- a/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx
+++ b/awx/ui_next/src/components/Schedule/shared/ScheduleForm.jsx
@@ -104,7 +104,11 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
fieldId="schedule-start-datetime"
helperTextInvalid={startDateTimeMeta.error}
isRequired
- isValid={!startDateTimeMeta.touched || !startDateTimeMeta.error}
+ validated={
+ !startDateTimeMeta.touched || !startDateTimeMeta.error
+ ? 'default'
+ : 'error'
+ }
label={i18n._(t`Start date/time`)}
>
<input
@@ -120,7 +124,9 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
fieldId="schedule-timezone"
helperTextInvalid={timezoneMeta.error}
isRequired
- isValid={!timezoneMeta.touched || !timezoneMeta.error}
+ validated={
+ !timezoneMeta.touched || !timezoneMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`Local time zone`)}
>
<AnsibleSelect
@@ -134,7 +140,9 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
fieldId="schedule-requency"
helperTextInvalid={frequencyMeta.error}
isRequired
- isValid={!frequencyMeta.touched || !frequencyMeta.error}
+ validated={
+ !frequencyMeta.touched || !frequencyMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`Run frequency`)}
>
<AnsibleSelect
@@ -153,7 +161,9 @@ function ScheduleFormFields({ i18n, zoneOptions }) {
</FormGroup>
{frequency.value !== 'none' && (
<SubFormLayout>
- <Title size="md">{i18n._(t`Frequency Details`)}</Title>
+ <Title size="md" headingLevel="h4">
+ {i18n._(t`Frequency Details`)}
+ </Title>
<FormColumnLayout>
<FrequencyDetailSubform />
</FormColumnLayout>
diff --git a/awx/ui_next/src/components/Search/Search.jsx b/awx/ui_next/src/components/Search/Search.jsx
index 91c3987cea..0fb59e0806 100644
--- a/awx/ui_next/src/components/Search/Search.jsx
+++ b/awx/ui_next/src/components/Search/Search.jsx
@@ -16,12 +16,10 @@ import {
SelectOption,
SelectVariant,
TextInput,
+ ToolbarGroup,
+ ToolbarItem,
+ ToolbarFilter,
} from '@patternfly/react-core';
-import {
- DataToolbarGroup,
- DataToolbarItem,
- DataToolbarFilter,
-} from '@patternfly/react-core/dist/umd/experimental';
import { SearchIcon } from '@patternfly/react-icons';
import styled from 'styled-components';
import { parseQueryString } from '../../util/qs';
@@ -205,8 +203,8 @@ class Search extends React.Component {
const chipsByKey = getChipsByKey();
return (
- <DataToolbarGroup variant="filter-group">
- <DataToolbarItem>
+ <ToolbarGroup variant="filter-group">
+ <ToolbarItem>
{searchDropdownItems.length > 0 ? (
<Dropdown
onToggle={this.handleDropdownToggle}
@@ -227,10 +225,10 @@ class Search extends React.Component {
) : (
<NoOptionDropdown>{searchColumnName}</NoOptionDropdown>
)}
- </DataToolbarItem>
+ </ToolbarItem>
{columns.map(
({ key, name, options, isBoolean, booleanLabels = {} }) => (
- <DataToolbarFilter
+ <ToolbarFilter
chips={chipsByKey[key] ? chipsByKey[key].chips : []}
deleteChip={(unusedKey, chip) => {
const [columnKey, ...value] = chip.key.split(':');
@@ -253,7 +251,7 @@ class Search extends React.Component {
const [, ...value] = chip.key.split(':');
return value.join(':');
})}
- isExpanded={isFilterDropdownOpen}
+ isOpen={isFilterDropdownOpen}
placeholderText={`Filter By ${name}`}
>
{options.map(([optionKey, optionLabel]) => (
@@ -272,7 +270,7 @@ class Search extends React.Component {
this.handleFilterBooleanSelect(key, selection)
}
selections={chipsByKey[key].chips[0]}
- isExpanded={isFilterDropdownOpen}
+ isOpen={isFilterDropdownOpen}
placeholderText={`Filter By ${name}`}
>
<SelectOption key="true" value="true">
@@ -311,10 +309,10 @@ class Search extends React.Component {
</div>
</InputGroup>
)}
- </DataToolbarFilter>
+ </ToolbarFilter>
)
)}
- </DataToolbarGroup>
+ </ToolbarGroup>
);
}
}
diff --git a/awx/ui_next/src/components/Search/Search.test.jsx b/awx/ui_next/src/components/Search/Search.test.jsx
index 503fa9ec58..5eac1c532b 100644
--- a/awx/ui_next/src/components/Search/Search.test.jsx
+++ b/awx/ui_next/src/components/Search/Search.test.jsx
@@ -1,8 +1,5 @@
import React from 'react';
-import {
- DataToolbar,
- DataToolbarContent,
-} from '@patternfly/react-core/dist/umd/experimental';
+import { Toolbar, ToolbarContent } from '@patternfly/react-core';
import { createMemoryHistory } from 'history';
import { act } from 'react-dom/test-utils';
import { mountWithContexts } from '../../../testUtils/enzymeHelpers';
@@ -33,15 +30,15 @@ describe('<Search />', () => {
const onSearch = jest.fn();
search = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${QS_CONFIG.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search qsConfig={QS_CONFIG} columns={columns} onSearch={onSearch} />
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarContent>
+ </Toolbar>
);
search.find(searchTextInput).instance().value = 'test-321';
@@ -56,15 +53,15 @@ describe('<Search />', () => {
const columns = [{ name: 'Name', key: 'name', isDefault: true }];
const onSearch = jest.fn();
const wrapper = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${QS_CONFIG.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search qsConfig={QS_CONFIG} columns={columns} onSearch={onSearch} />
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarContent>
+ </Toolbar>
).find('Search');
expect(wrapper.state('isSearchDropdownOpen')).toEqual(false);
wrapper.instance().handleDropdownToggle(true);
@@ -78,15 +75,15 @@ describe('<Search />', () => {
];
const onSearch = jest.fn();
const wrapper = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${QS_CONFIG.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search qsConfig={QS_CONFIG} columns={columns} onSearch={onSearch} />
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarContent>
+ </Toolbar>
).find('Search');
expect(wrapper.state('searchKey')).toEqual('name');
wrapper
@@ -101,15 +98,15 @@ describe('<Search />', () => {
const columns = [{ name: 'Name', key: 'name', isDefault: true }];
const onSearch = jest.fn();
const wrapper = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${QS_CONFIG.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search qsConfig={QS_CONFIG} columns={columns} onSearch={onSearch} />
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarContent>
+ </Toolbar>
);
wrapper.find(searchTextInput).instance().value = '';
@@ -125,15 +122,15 @@ describe('<Search />', () => {
const columns = [{ name: 'Name', key: 'name', isDefault: true }];
const onSearch = jest.fn();
const wrapper = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${QS_CONFIG.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search qsConfig={QS_CONFIG} columns={columns} onSearch={onSearch} />
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarContent>
+ </Toolbar>
);
wrapper.find(searchTextInput).instance().value = 'test-321';
@@ -156,23 +153,23 @@ describe('<Search />', () => {
initialEntries: [`/organizations/${query}`],
});
const wrapper = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${QS_CONFIG.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search qsConfig={QS_CONFIG} columns={columns} />
- </DataToolbarContent>
- </DataToolbar>,
+ </ToolbarContent>
+ </Toolbar>,
{ context: { router: { history } } }
);
const typeFilterWrapper = wrapper.find(
- 'DataToolbarFilter[categoryName="Type"]'
+ 'ToolbarFilter[categoryName="Type"]'
);
expect(typeFilterWrapper.prop('chips')[0].key).toEqual('or__type:foo');
const nameFilterWrapper = wrapper.find(
- 'DataToolbarFilter[categoryName="Name"]'
+ 'ToolbarFilter[categoryName="Name"]'
);
expect(nameFilterWrapper.prop('chips')[0].key).toEqual('name:bar');
});
@@ -197,19 +194,19 @@ describe('<Search />', () => {
});
const onRemove = jest.fn();
const wrapper = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${qsConfigNew.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search
qsConfig={qsConfigNew}
columns={columns}
onRemove={onRemove}
/>
- </DataToolbarContent>
- </DataToolbar>,
+ </ToolbarContent>
+ </Toolbar>,
{ context: { router: { history } } }
);
expect(history.location.search).toEqual(query);
@@ -243,19 +240,19 @@ describe('<Search />', () => {
});
const onRemove = jest.fn();
const wrapper = mountWithContexts(
- <DataToolbar
+ <Toolbar
id={`${qsConfigNew.namespace}-list-toolbar`}
clearAllFilters={() => {}}
- collapseListedFiltersBreakpoint="md"
+ collapseListedFiltersBreakpoint="lg"
>
- <DataToolbarContent>
+ <ToolbarContent>
<Search
qsConfig={qsConfigNew}
columns={columns}
onRemove={onRemove}
/>
- </DataToolbarContent>
- </DataToolbar>,
+ </ToolbarContent>
+ </Toolbar>,
{ context: { router: { history } } }
);
expect(history.location.search).toEqual(query);
diff --git a/awx/ui_next/src/components/UserAndTeamAccessAdd/UserAndTeamAccessAdd.test.jsx b/awx/ui_next/src/components/UserAndTeamAccessAdd/UserAndTeamAccessAdd.test.jsx
index b80c24a493..b5f986c5db 100644
--- a/awx/ui_next/src/components/UserAndTeamAccessAdd/UserAndTeamAccessAdd.test.jsx
+++ b/awx/ui_next/src/components/UserAndTeamAccessAdd/UserAndTeamAccessAdd.test.jsx
@@ -56,6 +56,7 @@ describe('<UserAndTeamAccessAdd/>', () => {
/>
);
});
+ await waitForElement(wrapper, 'PFWizard');
});
afterEach(() => {
wrapper.unmount();
@@ -68,12 +69,12 @@ describe('<UserAndTeamAccessAdd/>', () => {
expect(wrapper.find('Button[type="submit"]').prop('isDisabled')).toBe(true);
expect(
wrapper
- .find('WizardNavItem[text="Select items from list"]')
+ .find('WizardNavItem[content="Select items from list"]')
.prop('isDisabled')
).toBe(true);
expect(
wrapper
- .find('WizardNavItem[text="Select roles to apply"]')
+ .find('WizardNavItem[content="Select roles to apply"]')
.prop('isDisabled')
).toBe(true);
await act(async () =>
@@ -90,16 +91,18 @@ describe('<UserAndTeamAccessAdd/>', () => {
);
wrapper.update();
expect(
- wrapper.find('WizardNavItem[text="Add resource type"]').prop('isDisabled')
+ wrapper
+ .find('WizardNavItem[content="Add resource type"]')
+ .prop('isDisabled')
).toBe(false);
expect(
wrapper
- .find('WizardNavItem[text="Select items from list"]')
+ .find('WizardNavItem[content="Select items from list"]')
.prop('isDisabled')
).toBe(false);
expect(
wrapper
- .find('WizardNavItem[text="Select roles to apply"]')
+ .find('WizardNavItem[content="Select roles to apply"]')
.prop('isDisabled')
).toBe(true);
});
diff --git a/awx/ui_next/src/components/Wizard/Wizard.jsx b/awx/ui_next/src/components/Wizard/Wizard.jsx
index 99e884baad..9f737d7691 100644
--- a/awx/ui_next/src/components/Wizard/Wizard.jsx
+++ b/awx/ui_next/src/components/Wizard/Wizard.jsx
@@ -3,7 +3,7 @@ import styled from 'styled-components';
Wizard.displayName = 'PFWizard';
export default styled(Wizard)`
- .pf-c-data-toolbar__content {
+ .pf-c-toolbar__content {
padding: 0 !important;
}
`;
diff --git a/awx/ui_next/src/screens/Application/ApplicationAdd/ApplicationAdd.test.jsx b/awx/ui_next/src/screens/Application/ApplicationAdd/ApplicationAdd.test.jsx
index bcf39fe64c..2bc0eba47e 100644
--- a/awx/ui_next/src/screens/Application/ApplicationAdd/ApplicationAdd.test.jsx
+++ b/awx/ui_next/src/screens/Application/ApplicationAdd/ApplicationAdd.test.jsx
@@ -91,8 +91,8 @@ describe('<ApplicationAdd/>', () => {
wrapper.update();
expect(wrapper.find('input#name').prop('value')).toBe('new foo');
expect(wrapper.find('input#description').prop('value')).toBe('new bar');
- expect(wrapper.find('InnerChipGroup').length).toBe(1);
- expect(wrapper.find('InnerChipGroup').text()).toBe('organization');
+ expect(wrapper.find('Chip').length).toBe(1);
+ expect(wrapper.find('Chip').text()).toBe('organization');
expect(
wrapper
.find('AnsibleSelect[name="authorization_grant_type"]')
diff --git a/awx/ui_next/src/screens/Application/shared/ApplicationForm.test.jsx b/awx/ui_next/src/screens/Application/shared/ApplicationForm.test.jsx
index 406c3d5ace..f43fc878d2 100644
--- a/awx/ui_next/src/screens/Application/shared/ApplicationForm.test.jsx
+++ b/awx/ui_next/src/screens/Application/shared/ApplicationForm.test.jsx
@@ -107,8 +107,8 @@ describe('<ApplicationForm', () => {
wrapper.update();
expect(wrapper.find('input#name').prop('value')).toBe('new foo');
expect(wrapper.find('input#description').prop('value')).toBe('new bar');
- expect(wrapper.find('InnerChipGroup').length).toBe(1);
- expect(wrapper.find('InnerChipGroup').text()).toBe('organization');
+ expect(wrapper.find('Chip').length).toBe(1);
+ expect(wrapper.find('Chip').text()).toBe('organization');
expect(
wrapper
.find('AnsibleSelect[name="authorization_grant_type"]')
diff --git a/awx/ui_next/src/screens/AuthSetting/AuthSettings.jsx b/awx/ui_next/src/screens/AuthSetting/AuthSettings.jsx
index a0fc4b5f73..e9f79a452a 100644
--- a/awx/ui_next/src/screens/AuthSetting/AuthSettings.jsx
+++ b/awx/ui_next/src/screens/AuthSetting/AuthSettings.jsx
@@ -15,7 +15,9 @@ class AuthSettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`Authentication Settings`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`Authentication Settings`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/Credential/Credential.jsx b/awx/ui_next/src/screens/Credential/Credential.jsx
index fd318bc07c..baa1e34e0f 100644
--- a/awx/ui_next/src/screens/Credential/Credential.jsx
+++ b/awx/ui_next/src/screens/Credential/Credential.jsx
@@ -1,7 +1,8 @@
import React, { useEffect, useState } from 'react';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
-import { Card, PageSection, CardActions } from '@patternfly/react-core';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import {
Switch,
useParams,
@@ -11,8 +12,6 @@ import {
Redirect,
Link,
} from 'react-router-dom';
-import { TabbedCardHeader } from '../../components/Card';
-import CardCloseButton from '../../components/CardCloseButton';
import { ResourceAccessList } from '../../components/ResourceAccessList';
import ContentError from '../../components/ContentError';
import RoutedTabs from '../../components/RoutedTabs';
@@ -46,6 +45,16 @@ function Credential({ i18n, setBreadcrumb }) {
}, [id, pathname, setBreadcrumb]);
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Credentials`)}
+ </>
+ ),
+ link: `/credentials`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `/credentials/${id}/details`, id: 0 },
];
@@ -57,17 +66,10 @@ function Credential({ i18n, setBreadcrumb }) {
});
}
- let cardHeader = hasContentLoading ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/credentials" />
- </CardActions>
- </TabbedCardHeader>
- );
+ let showCardHeader = true;
if (pathname.endsWith('edit') || pathname.endsWith('add')) {
- cardHeader = null;
+ showCardHeader = false;
}
if (!hasContentLoading && contentError) {
@@ -90,7 +92,7 @@ function Credential({ i18n, setBreadcrumb }) {
return (
<PageSection>
<Card>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/credentials/:id"
diff --git a/awx/ui_next/src/screens/Credential/Credential.test.jsx b/awx/ui_next/src/screens/Credential/Credential.test.jsx
index e1308aa750..7cb192ac0c 100644
--- a/awx/ui_next/src/screens/Credential/Credential.test.jsx
+++ b/awx/ui_next/src/screens/Credential/Credential.test.jsx
@@ -31,7 +31,7 @@ describe('<Credential />', () => {
wrapper = mountWithContexts(<Credential setBreadcrumb={() => {}} />);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
- await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 1);
+ await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 2);
});
test('initially renders org-based credential succesfully', async () => {
@@ -44,7 +44,7 @@ describe('<Credential />', () => {
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
// org-based credential detail needs access tab
- await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 2);
+ await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 3);
});
test('should show content error when user attempts to navigate to erroneous route', async () => {
diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx
index de814d2630..bc486bb8b1 100644
--- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx
+++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.jsx
@@ -104,7 +104,9 @@ function CredentialFormFields({
fieldId="credential-credentialType"
helperTextInvalid={credTypeMeta.error}
isRequired
- isValid={!credTypeMeta.touched || !credTypeMeta.error}
+ validated={
+ !credTypeMeta.touched || !credTypeMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`Credential Type`)}
>
<AnsibleSelect
diff --git a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx
index 2062ed01ee..88a81eaf2c 100644
--- a/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx
+++ b/awx/ui_next/src/screens/Credential/shared/CredentialForm.test.jsx
@@ -191,6 +191,12 @@ describe('<CredentialForm />', () => {
).toBe('');
});
test('should show error when error thrown parsing JSON', async () => {
+ await act(async () => {
+ await wrapper
+ .find('AnsibleSelect[id="credential_type"]')
+ .invoke('onChange')(null, 10);
+ });
+ wrapper.update();
expect(wrapper.find('#credential-gce-file-helper').text()).toBe(
'Select a JSON formatted service account key to autopopulate the following fields.'
);
@@ -201,7 +207,15 @@ describe('<CredentialForm />', () => {
});
});
wrapper.update();
- expect(wrapper.find('#credential-gce-file-helper').text()).toBe(
+ expect(
+ wrapper.find('FormGroup[fieldId="credential-gce-file"]').prop('isValid')
+ ).toBe(false);
+
+ expect(
+ wrapper
+ .find('FormGroup[fieldId="credential-gce-file"]')
+ .prop('helperTextInvalid')
+ ).toBe(
'There was an error parsing the file. Please check the file formatting and try again.'
);
});
diff --git a/awx/ui_next/src/screens/Credential/shared/TypeInputsSubForm.jsx b/awx/ui_next/src/screens/Credential/shared/TypeInputsSubForm.jsx
index d05e27d16e..c0a21b65b5 100644
--- a/awx/ui_next/src/screens/Credential/shared/TypeInputsSubForm.jsx
+++ b/awx/ui_next/src/screens/Credential/shared/TypeInputsSubForm.jsx
@@ -21,7 +21,9 @@ function TypeInputsSubForm({ credentialType, i18n }) {
);
return (
<SubFormLayout>
- <Title size="md">{i18n._(t`Type Details`)}</Title>
+ <Title size="md" headingLevel="h4">
+ {i18n._(t`Type Details`)}
+ </Title>
<FormColumnLayout>
{credentialType.namespace === 'gce' && <GceFileUploadField />}
{stringFields.map(fieldOptions =>
diff --git a/awx/ui_next/src/screens/Dashboard/Dashboard.jsx b/awx/ui_next/src/screens/Dashboard/Dashboard.jsx
index 0f2a7ceb79..b8e37fb1ad 100644
--- a/awx/ui_next/src/screens/Dashboard/Dashboard.jsx
+++ b/awx/ui_next/src/screens/Dashboard/Dashboard.jsx
@@ -15,7 +15,9 @@ class Dashboard extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`Dashboard`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`Dashboard`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/Host/Host.jsx b/awx/ui_next/src/screens/Host/Host.jsx
index d52737d195..536ac4f65b 100644
--- a/awx/ui_next/src/screens/Host/Host.jsx
+++ b/awx/ui_next/src/screens/Host/Host.jsx
@@ -9,10 +9,8 @@ import {
useRouteMatch,
useLocation,
} from 'react-router-dom';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
-
-import { TabbedCardHeader } from '../../components/Card';
-import CardCloseButton from '../../components/CardCloseButton';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import RoutedTabs from '../../components/RoutedTabs';
import ContentError from '../../components/ContentError';
import ContentLoading from '../../components/ContentLoading';
@@ -48,6 +46,16 @@ function Host({ i18n, setBreadcrumb }) {
const tabsArray = [
{
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Hosts`)}
+ </>
+ ),
+ link: `/hosts`,
+ id: 99,
+ },
+ {
name: i18n._(t`Details`),
link: `${match.url}/details`,
id: 0,
@@ -96,17 +104,16 @@ function Host({ i18n, setBreadcrumb }) {
);
}
+ let showCardHeader = true;
+
+ if (location.pathname.endsWith('edit')) {
+ showCardHeader = false;
+ }
+
return (
<PageSection>
<Card>
- {location.pathname.endsWith('edit') ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/hosts" />
- </CardActions>
- </TabbedCardHeader>
- )}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect from="/hosts/:id" to="/hosts/:id/details" exact />
{host && [
diff --git a/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.jsx b/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.jsx
index 022247193e..9a973bccc0 100644
--- a/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.jsx
+++ b/awx/ui_next/src/screens/InstanceGroup/InstanceGroups.jsx
@@ -15,7 +15,9 @@ class InstanceGroups extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`Instance Groups`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`Instance Groups`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/Inventory/Inventory.jsx b/awx/ui_next/src/screens/Inventory/Inventory.jsx
index 8515029f4e..2e02d5f03b 100644
--- a/awx/ui_next/src/screens/Inventory/Inventory.jsx
+++ b/awx/ui_next/src/screens/Inventory/Inventory.jsx
@@ -9,10 +9,8 @@ import {
useLocation,
useRouteMatch,
} from 'react-router-dom';
-
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
-import { TabbedCardHeader } from '../../components/Card';
-import CardCloseButton from '../../components/CardCloseButton';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import ContentError from '../../components/ContentError';
import ContentLoading from '../../components/ContentLoading';
import JobList from '../../components/JobList';
@@ -51,6 +49,16 @@ function Inventory({ i18n, setBreadcrumb }) {
}, [match.params.id, location.pathname, setBreadcrumb]);
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Inventories`)}
+ </>
+ ),
+ link: `/inventories`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
{ name: i18n._(t`Access`), link: `${match.url}/access`, id: 1 },
{ name: i18n._(t`Groups`), link: `${match.url}/groups`, id: 2 },
@@ -90,19 +98,20 @@ function Inventory({ i18n, setBreadcrumb }) {
);
}
+ let showCardHeader = true;
+
+ if (
+ ['edit', 'add', 'groups/', 'hosts/', 'sources/'].some(name =>
+ location.pathname.includes(name)
+ )
+ ) {
+ showCardHeader = false;
+ }
+
return (
<PageSection>
<Card>
- {['edit', 'add', 'groups/', 'hosts/', 'sources/'].some(name =>
- location.pathname.includes(name)
- ) ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/inventories" />
- </CardActions>
- </TabbedCardHeader>
- )}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/inventories/inventory/:id"
diff --git a/awx/ui_next/src/screens/Inventory/Inventory.test.jsx b/awx/ui_next/src/screens/Inventory/Inventory.test.jsx
index 652ba4cf88..de623f8b53 100644
--- a/awx/ui_next/src/screens/Inventory/Inventory.test.jsx
+++ b/awx/ui_next/src/screens/Inventory/Inventory.test.jsx
@@ -30,7 +30,7 @@ describe('<Inventory />', () => {
wrapper = mountWithContexts(<Inventory setBreadcrumb={() => {}} />);
});
await waitForElement(wrapper, 'ContentLoading', el => el.length === 0);
- await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 6);
+ await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 7);
});
test('should show content error when user attempts to navigate to erroneous route', async () => {
diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroup/InventoryGroup.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroup/InventoryGroup.jsx
index 28ac2daded..9818bd43de 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryGroup/InventoryGroup.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryGroup/InventoryGroup.jsx
@@ -10,13 +10,10 @@ import {
useLocation,
useParams,
} from 'react-router-dom';
-import { CardActions } from '@patternfly/react-core';
import { CaretLeftIcon } from '@patternfly/react-icons';
-import CardCloseButton from '../../../components/CardCloseButton';
import RoutedTabs from '../../../components/RoutedTabs';
import ContentError from '../../../components/ContentError';
import ContentLoading from '../../../components/ContentLoading';
-import { TabbedCardHeader } from '../../../components/Card';
import InventoryGroupEdit from '../InventoryGroupEdit/InventoryGroupEdit';
import InventoryGroupDetail from '../InventoryGroupDetail/InventoryGroupDetail';
import InventoryGroupHosts from '../InventoryGroupHosts';
@@ -99,18 +96,14 @@ function InventoryGroup({ i18n, setBreadcrumb, inventory }) {
);
}
+ let showCardHeader = true;
+ if (['add', 'edit'].some(name => location.pathname.includes(name))) {
+ showCardHeader = false;
+ }
+
return (
<>
- {['add', 'edit'].some(name => location.pathname.includes(name)) ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton
- linkTo={`/inventories/inventory/${inventory.id}/groups`}
- />
- </CardActions>
- </TabbedCardHeader>
- )}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/inventories/inventory/:id/groups/:groupId"
diff --git a/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx b/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx
index fbd02a9ad4..0827f68780 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryGroups/InventoryGroupsList.test.jsx
@@ -163,9 +163,7 @@ describe('<InventoryGroupsList />', () => {
});
wrapper.update();
await act(async () => {
- wrapper
- .find('DataToolbar Button[aria-label="Delete"]')
- .invoke('onClick')();
+ wrapper.find('Toolbar Button[aria-label="Delete"]').invoke('onClick')();
});
await waitForElement(
wrapper,
@@ -197,14 +195,12 @@ describe('<InventoryGroupsList />', () => {
});
wrapper.update();
await act(async () => {
- wrapper
- .find('DataToolbar Button[aria-label="Delete"]')
- .invoke('onClick')();
+ wrapper.find('Toolbar Button[aria-label="Delete"]').invoke('onClick')();
});
await waitForElement(
wrapper,
- 'InventoryGroupsDeleteModal',
- el => el.props().isModalOpen === true
+ 'AlertModal[title="Delete Group?"]',
+ el => el.props().isOpen === true
);
await act(async () => {
wrapper.find('Radio[id="radio-delete"]').invoke('onChange')();
@@ -215,7 +211,11 @@ describe('<InventoryGroupsList />', () => {
.find('ModalBoxFooter Button[aria-label="Delete"]')
.invoke('onClick')();
});
- await waitForElement(wrapper, { title: 'Error!', variant: 'error' });
+ await waitForElement(
+ wrapper,
+ 'AlertModal[title="Error!"] Modal',
+ el => el.props().isOpen === true && el.props().title === 'Error!'
+ );
await act(async () => {
wrapper.find('ModalBoxCloseButton').invoke('onClose')();
});
diff --git a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx
index ef674bc146..33e7884a73 100644
--- a/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventoryHost/InventoryHost.jsx
@@ -9,13 +9,11 @@ import {
useRouteMatch,
useLocation,
} from 'react-router-dom';
-import { Card, CardActions } from '@patternfly/react-core';
+import { Card } from '@patternfly/react-core';
import { CaretLeftIcon } from '@patternfly/react-icons';
import useRequest from '../../../util/useRequest';
import { InventoriesAPI } from '../../../api';
-import { TabbedCardHeader } from '../../../components/Card';
-import CardCloseButton from '../../../components/CardCloseButton';
import ContentError from '../../../components/ContentError';
import ContentLoading from '../../../components/ContentLoading';
import RoutedTabs from '../../../components/RoutedTabs';
@@ -110,16 +108,14 @@ function InventoryHost({ i18n, setBreadcrumb, inventory }) {
);
}
+ let showCardHeader = true;
+ if (['edit'].some(name => location.pathname.includes(name))) {
+ showCardHeader = false;
+ }
+
return (
<>
- {['edit'].some(name => location.pathname.includes(name)) ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo={hostListUrl} />
- </CardActions>
- </TabbedCardHeader>
- )}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
{isLoading && <ContentLoading />}
diff --git a/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx b/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx
index ecd065a57b..771401b7e4 100644
--- a/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx
+++ b/awx/ui_next/src/screens/Inventory/InventorySource/InventorySource.jsx
@@ -10,7 +10,6 @@ import {
useLocation,
} from 'react-router-dom';
import { CaretLeftIcon } from '@patternfly/react-icons';
-import { CardActions } from '@patternfly/react-core';
import useRequest from '../../../util/useRequest';
import {
@@ -18,9 +17,7 @@ import {
InventorySourcesAPI,
OrganizationsAPI,
} from '../../../api';
-import { TabbedCardHeader } from '../../../components/Card';
import { Schedules } from '../../../components/Schedule';
-import CardCloseButton from '../../../components/CardCloseButton';
import ContentError from '../../../components/ContentError';
import ContentLoading from '../../../components/ContentLoading';
import RoutedTabs from '../../../components/RoutedTabs';
@@ -112,18 +109,15 @@ function InventorySource({ i18n, inventory, setBreadcrumb, me }) {
return <ContentError error={error} />;
}
+ let showCardHeader = true;
+
+ if (['edit', 'schedules/'].some(name => location.pathname.includes(name))) {
+ showCardHeader = false;
+ }
+
return (
<>
- {['edit', 'schedules/'].some(name =>
- location.pathname.includes(name)
- ) ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo={sourceListUrl} />
- </CardActions>
- </TabbedCardHeader>
- )}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
{isLoading && <ContentLoading />}
diff --git a/awx/ui_next/src/screens/Inventory/SmartInventory.jsx b/awx/ui_next/src/screens/Inventory/SmartInventory.jsx
index 29e503faa9..f35876c768 100644
--- a/awx/ui_next/src/screens/Inventory/SmartInventory.jsx
+++ b/awx/ui_next/src/screens/Inventory/SmartInventory.jsx
@@ -1,10 +1,9 @@
import React, { Component } from 'react';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import { Switch, Route, Redirect, withRouter, Link } from 'react-router-dom';
-import { TabbedCardHeader } from '../../components/Card';
-import CardCloseButton from '../../components/CardCloseButton';
import ContentError from '../../components/ContentError';
import JobList from '../../components/JobList';
import RoutedTabs from '../../components/RoutedTabs';
@@ -64,6 +63,16 @@ class SmartInventory extends Component {
const { contentError, hasContentLoading, inventory } = this.state;
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Inventories`)}
+ </>
+ ),
+ link: `/inventories`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
{ name: i18n._(t`Access`), link: `${match.url}/access`, id: 1 },
{ name: i18n._(t`Hosts`), link: `${match.url}/hosts`, id: 2 },
@@ -74,17 +83,10 @@ class SmartInventory extends Component {
},
];
- let cardHeader = hasContentLoading ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/inventories" />
- </CardActions>
- </TabbedCardHeader>
- );
+ let showCardHeader = true;
if (location.pathname.endsWith('edit')) {
- cardHeader = null;
+ showCardHeader = false;
}
if (!hasContentLoading && contentError) {
@@ -108,7 +110,7 @@ class SmartInventory extends Component {
return (
<PageSection>
<Card>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/inventories/smart_inventory/:id"
diff --git a/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx b/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx
index 6483543fd7..e229e1bda8 100644
--- a/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx
+++ b/awx/ui_next/src/screens/Inventory/SmartInventory.test.jsx
@@ -29,7 +29,7 @@ describe('<SmartInventory />', () => {
'SmartInventory',
el => el.state('hasContentLoading') === false
);
- await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 4);
+ await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 5);
done();
});
test('should show content error when user attempts to navigate to erroneous route', async () => {
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceForm.jsx
index ffcab9f148..73dec8877f 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceForm.jsx
@@ -117,7 +117,9 @@ const InventorySourceFormFields = ({ sourceOptions, i18n }) => {
fieldId="source"
helperTextInvalid={sourceMeta.error}
isRequired
- isValid={!sourceMeta.touched || !sourceMeta.error}
+ validated={
+ !sourceMeta.touched || !sourceMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`Source`)}
>
<AnsibleSelect
@@ -161,7 +163,9 @@ const InventorySourceFormFields = ({ sourceOptions, i18n }) => {
)}
{sourceField.value !== '' && (
<SubFormLayout>
- <Title size="md">{i18n._(t`Source details`)}</Title>
+ <Title size="md" headingLevel="h4">
+ {i18n._(t`Source details`)}
+ </Title>
<FormColumnLayout>
{
{
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SCMSubForm.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SCMSubForm.jsx
index e9fe7f6690..3689e305a8 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SCMSubForm.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SCMSubForm.jsx
@@ -83,9 +83,11 @@ const SCMSubForm = ({ i18n }) => {
<FormGroup
fieldId="source_path"
helperTextInvalid={sourcePathError?.message || sourcePathMeta.error}
- isValid={
+ validated={
(!sourcePathMeta.error || !sourcePathMeta.touched) &&
!sourcePathError?.message
+ ? 'default'
+ : 'error'
}
isRequired
label={i18n._(t`Inventory file`)}
diff --git a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SharedFields.jsx b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SharedFields.jsx
index 698799ab62..b4cca4a073 100644
--- a/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SharedFields.jsx
+++ b/awx/ui_next/src/screens/Inventory/shared/InventorySourceSubForms/SharedFields.jsx
@@ -229,7 +229,7 @@ export const VerbosityField = withI18n()(({ i18n }) => {
return (
<FormGroup
fieldId="verbosity"
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={i18n._(t`Verbosity`)}
>
<FieldTooltip
diff --git a/awx/ui_next/src/screens/InventoryScript/InventoryScripts.jsx b/awx/ui_next/src/screens/InventoryScript/InventoryScripts.jsx
index 9fe0aea136..d45f660fa8 100644
--- a/awx/ui_next/src/screens/InventoryScript/InventoryScripts.jsx
+++ b/awx/ui_next/src/screens/InventoryScript/InventoryScripts.jsx
@@ -15,7 +15,9 @@ class InventoryScripts extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`Inventory Scripts`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`Inventory Scripts`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/Job/Job.jsx b/awx/ui_next/src/screens/Job/Job.jsx
index 624f7443ff..924ebfebcc 100644
--- a/awx/ui_next/src/screens/Job/Job.jsx
+++ b/awx/ui_next/src/screens/Job/Job.jsx
@@ -2,11 +2,10 @@ import React, { Component } from 'react';
import { Route, withRouter, Switch, Redirect, Link } from 'react-router-dom';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import { JobsAPI } from '../../api';
-import { TabbedCardHeader } from '../../components/Card';
import ContentError from '../../components/ContentError';
-import CardCloseButton from '../../components/CardCloseButton';
import RoutedTabs from '../../components/RoutedTabs';
import JobDetail from './JobDetail';
@@ -67,21 +66,24 @@ class Job extends Component {
}
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Jobs`)}
+ </>
+ ),
+ link: `/jobs`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
{ name: i18n._(t`Output`), link: `${match.url}/output`, id: 1 },
];
- let cardHeader = (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/jobs" />
- </CardActions>
- </TabbedCardHeader>
- );
+ let showCardHeader = true;
if (!isInitialized) {
- cardHeader = null;
+ showCardHeader = false;
}
if (!hasContentLoading && contentError) {
@@ -117,7 +119,7 @@ class Job extends Component {
return (
<PageSection>
<Card>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/jobs/:type/:id"
diff --git a/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.jsx b/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.jsx
index 7a9f1c9399..f82e12eb00 100644
--- a/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.jsx
+++ b/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.jsx
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
-import { Modal as PFModal, Tab, Tabs as PFTabs } from '@patternfly/react-core';
+import { Modal, Tab, Tabs, TabTitleText } from '@patternfly/react-core';
import PropTypes from 'prop-types';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
@@ -12,18 +12,6 @@ import CodeMirrorInput from '../../../components/CodeMirrorInput';
const entities = new AllHtmlEntities();
-const Modal = styled(PFModal)`
- --pf-c-modal-box__footer--MarginTop: 0;
- align-self: flex-start;
- margin-top: 200px;
- .pf-c-modal-box__body {
- overflow-y: hidden;
- }
- .pf-c-tab-content {
- padding: 24px 0;
- }
-`;
-
const HostNameDetailValue = styled.div`
align-items: center;
display: inline-grid;
@@ -31,31 +19,6 @@ const HostNameDetailValue = styled.div`
grid-template-columns: auto auto;
`;
-const Tabs = styled(PFTabs)`
- --pf-c-tabs__button--PaddingLeft: 20px;
- --pf-c-tabs__button--PaddingRight: 20px;
-
- .pf-c-tabs__list {
- li:first-of-type .pf-c-tabs__button {
- &::after {
- margin-left: 0;
- }
- }
- }
-
- &:not(.pf-c-tabs__item)::before {
- position: absolute;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- content: '';
- border-bottom: solid var(--pf-c-tabs__item--BorderColor);
- border-width: var(--pf-c-tabs__item--BorderWidth) 0
- var(--pf-c-tabs__item--BorderWidth) 0;
- }
-`;
-
const processEventStatus = event => {
let status = null;
if (event.event === 'runner_on_unreachable') {
@@ -133,11 +96,11 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
return (
<Modal
- isFooterLeftAligned
- isLarge
isOpen={isOpen}
onClose={onClose}
title={i18n._(t`Host Details`)}
+ aria-label={i18n._(t`Host details modal`)}
+ width="75%"
>
<Tabs
aria-label={i18n._(t`Tabs`)}
@@ -147,9 +110,12 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
<Tab
aria-label={i18n._(t`Details tab`)}
eventKey={0}
- title={i18n._(t`Details`)}
+ title={<TabTitleText>{i18n._(t`Details`)}</TabTitleText>}
>
- <DetailList style={{ alignItems: 'center' }} gutter="sm">
+ <DetailList
+ style={{ alignItems: 'center', marginTop: '20px' }}
+ gutter="sm"
+ >
<Detail
label={i18n._(t`Host Name`)}
value={
@@ -175,7 +141,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
</Tab>
<Tab
eventKey={1}
- title={i18n._(t`JSON`)}
+ title={<TabTitleText>{i18n._(t`JSON`)}</TabTitleText>}
aria-label={i18n._(t`JSON tab`)}
>
{activeTabKey === 1 && jsonObj ? (
@@ -193,7 +159,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
</Tab>
<Tab
eventKey={2}
- title={i18n._(t`Standard Out`)}
+ title={<TabTitleText>{i18n._(t`Standard Out`)}</TabTitleText>}
aria-label={i18n._(t`Standard out tab`)}
>
{activeTabKey === 2 && stdOut ? (
@@ -211,7 +177,7 @@ function HostEventModal({ onClose, hostEvent = {}, isOpen = false, i18n }) {
</Tab>
<Tab
eventKey={3}
- title={i18n._(t`Standard Error`)}
+ title={<TabTitleText>{i18n._(t`Standard Error`)}</TabTitleText>}
aria-label={i18n._(t`Standard error tab`)}
>
{activeTabKey === 3 && stdErr ? (
diff --git a/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx b/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx
index 0a18cc3d93..01b6ed61bd 100644
--- a/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx
+++ b/awx/ui_next/src/screens/Job/JobOutput/HostEventModal.test.jsx
@@ -88,16 +88,7 @@ describe('HostEventModal', () => {
);
/* eslint-disable react/button-has-type */
- expect(
- wrapper
- .find('Tabs')
- .containsAllMatchingElements([
- <button aria-label="Details tab">Details</button>,
- <button aria-label="JSON tab">JSON</button>,
- <button aria-label="Standard out tab">Standard Out</button>,
- <button aria-label="Standard error tab">Standard Error</button>,
- ])
- ).toEqual(true);
+ expect(wrapper.find('Tabs TabButton').length).toEqual(4);
});
test('should show details tab content on mount', () => {
diff --git a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx
index 4e72d0014c..9c6b324891 100644
--- a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx
+++ b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.jsx
@@ -475,6 +475,7 @@ class JobOutput extends Component {
variant="danger"
onClose={() => this.setState({ deletionError: null })}
title={i18n._(t`Job Delete Error`)}
+ label={i18n._(t`Job Delete Error`)}
>
<ErrorDetail error={deletionError} />
</AlertModal>
diff --git a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.test.jsx b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.test.jsx
index 5afa5d2573..5531a0ade6 100644
--- a/awx/ui_next/src/screens/Job/JobOutput/JobOutput.test.jsx
+++ b/awx/ui_next/src/screens/Job/JobOutput/JobOutput.test.jsx
@@ -338,7 +338,7 @@ describe('<JobOutput />', () => {
wrapper.find('Modal button[aria-label="Delete"]').simulate('click');
await waitForElement(wrapper, 'Modal ErrorDetail');
const errorModalCloseBtn = wrapper.find(
- 'ModalBox div[aria-label="Job Delete Error"] button[aria-label="Close"]'
+ 'ModalBox[aria-label="Job Delete Error"] ModalBoxCloseButton'
);
errorModalCloseBtn.simulate('click');
await waitForElement(wrapper, 'Modal ErrorDetail', el => el.length === 0);
diff --git a/awx/ui_next/src/screens/JobsSetting/JobsSettings.jsx b/awx/ui_next/src/screens/JobsSetting/JobsSettings.jsx
index ded44676f6..f5fb77ef50 100644
--- a/awx/ui_next/src/screens/JobsSetting/JobsSettings.jsx
+++ b/awx/ui_next/src/screens/JobsSetting/JobsSettings.jsx
@@ -15,7 +15,9 @@ class JobsSettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`Jobs Settings`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`Jobs Settings`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/License/License.jsx b/awx/ui_next/src/screens/License/License.jsx
index cebf2a4734..1ec59d2930 100644
--- a/awx/ui_next/src/screens/License/License.jsx
+++ b/awx/ui_next/src/screens/License/License.jsx
@@ -15,7 +15,9 @@ class License extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`License`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`License`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/ManagementJob/ManagementJobs.jsx b/awx/ui_next/src/screens/ManagementJob/ManagementJobs.jsx
index f86e9b3040..658cfcb403 100644
--- a/awx/ui_next/src/screens/ManagementJob/ManagementJobs.jsx
+++ b/awx/ui_next/src/screens/ManagementJob/ManagementJobs.jsx
@@ -15,7 +15,9 @@ class ManagementJobs extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`Management Jobs`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`Management Jobs`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.jsx b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.jsx
index abcf1ab511..857201bc6b 100644
--- a/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.jsx
+++ b/awx/ui_next/src/screens/NotificationTemplate/NotificationTemplates.jsx
@@ -15,7 +15,9 @@ class NotificationTemplates extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`Notification Templates`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`Notification Templates`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/Organization/Organization.jsx b/awx/ui_next/src/screens/Organization/Organization.jsx
index 6dfb120c29..248f5fc430 100644
--- a/awx/ui_next/src/screens/Organization/Organization.jsx
+++ b/awx/ui_next/src/screens/Organization/Organization.jsx
@@ -2,9 +2,8 @@ import React, { Component } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Switch, Route, withRouter, Redirect, Link } from 'react-router-dom';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
-import CardCloseButton from '../../components/CardCloseButton';
-import { TabbedCardHeader } from '../../components/Card';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import RoutedTabs from '../../components/RoutedTabs';
import ContentError from '../../components/ContentError';
import NotificationList from '../../components/NotificationList/NotificationList';
@@ -116,6 +115,16 @@ class Organization extends Component {
(me.is_system_auditor || isAuditorOfThisOrg || isAdminOfThisOrg);
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Organizations`)}
+ </>
+ ),
+ link: `/organizations`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
{ name: i18n._(t`Access`), link: `${match.url}/access`, id: 1 },
{ name: i18n._(t`Teams`), link: `${match.url}/teams`, id: 2 },
@@ -129,21 +138,10 @@ class Organization extends Component {
});
}
- let cardHeader = (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/organizations" />
- </CardActions>
- </TabbedCardHeader>
- );
-
- if (!isInitialized) {
- cardHeader = null;
- }
+ let showCardHeader = true;
- if (location.pathname.endsWith('edit')) {
- cardHeader = null;
+ if (!isInitialized || location.pathname.endsWith('edit')) {
+ showCardHeader = false;
}
if (!hasContentLoading && contentError) {
@@ -168,7 +166,7 @@ class Organization extends Component {
return (
<PageSection>
<Card>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/organizations/:id"
diff --git a/awx/ui_next/src/screens/Organization/Organization.test.jsx b/awx/ui_next/src/screens/Organization/Organization.test.jsx
index a287b87f85..298ae9188e 100644
--- a/awx/ui_next/src/screens/Organization/Organization.test.jsx
+++ b/awx/ui_next/src/screens/Organization/Organization.test.jsx
@@ -53,7 +53,7 @@ describe('<Organization />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 4
+ el => el.length === 5
);
expect(tabs.last().text()).toEqual('Notifications');
done();
@@ -74,7 +74,7 @@ describe('<Organization />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 3
+ el => el.length === 4
);
tabs.forEach(tab => expect(tab.text()).not.toEqual('Notifications'));
done();
diff --git a/awx/ui_next/src/screens/Portal/Portal.jsx b/awx/ui_next/src/screens/Portal/Portal.jsx
index d5f6cbecec..6651fc25d2 100644
--- a/awx/ui_next/src/screens/Portal/Portal.jsx
+++ b/awx/ui_next/src/screens/Portal/Portal.jsx
@@ -15,7 +15,9 @@ class Portal extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`My View`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`My View`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/Project/Project.jsx b/awx/ui_next/src/screens/Project/Project.jsx
index f20b66e3ca..3dae7a5a6c 100644
--- a/awx/ui_next/src/screens/Project/Project.jsx
+++ b/awx/ui_next/src/screens/Project/Project.jsx
@@ -2,9 +2,8 @@ import React, { Component } from 'react';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { Switch, Route, withRouter, Redirect, Link } from 'react-router-dom';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
-import { TabbedCardHeader } from '../../components/Card';
-import CardCloseButton from '../../components/CardCloseButton';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import RoutedTabs from '../../components/RoutedTabs';
import ContentError from '../../components/ContentError';
import NotificationList from '../../components/NotificationList';
@@ -121,6 +120,16 @@ class Project extends Component {
const canToggleNotifications = isNotifAdmin;
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Projects`)}
+ </>
+ ),
+ link: `/projects`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details` },
{ name: i18n._(t`Access`), link: `${match.url}/access` },
];
@@ -148,24 +157,14 @@ class Project extends Component {
tab.id = n;
});
- let cardHeader = (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/projects" />
- </CardActions>
- </TabbedCardHeader>
- );
-
- if (!isInitialized) {
- cardHeader = null;
- }
+ let showCardHeader = true;
if (
+ !isInitialized ||
location.pathname.endsWith('edit') ||
location.pathname.includes('schedules/')
) {
- cardHeader = null;
+ showCardHeader = false;
}
if (!hasContentLoading && contentError) {
@@ -188,7 +187,7 @@ class Project extends Component {
return (
<PageSection>
<Card>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect from="/projects/:id" to="/projects/:id/details" exact />
{project && (
diff --git a/awx/ui_next/src/screens/Project/Project.test.jsx b/awx/ui_next/src/screens/Project/Project.test.jsx
index f2ecf09cc7..7d8080e8a9 100644
--- a/awx/ui_next/src/screens/Project/Project.test.jsx
+++ b/awx/ui_next/src/screens/Project/Project.test.jsx
@@ -44,9 +44,9 @@ describe('<Project />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 5
+ el => el.length === 6
);
- expect(tabs.at(2).text()).toEqual('Notifications');
+ expect(tabs.at(3).text()).toEqual('Notifications');
done();
});
@@ -65,7 +65,7 @@ describe('<Project />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 4
+ el => el.length === 5
);
tabs.forEach(tab => expect(tab.text()).not.toEqual('Notifications'));
done();
@@ -86,9 +86,9 @@ describe('<Project />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 4
+ el => el.length === 5
);
- expect(tabs.at(3).text()).toEqual('Schedules');
+ expect(tabs.at(4).text()).toEqual('Schedules');
done();
});
@@ -108,7 +108,7 @@ describe('<Project />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 3
+ el => el.length === 4
);
tabs.forEach(tab => expect(tab.text()).not.toEqual('Schedules'));
done();
diff --git a/awx/ui_next/src/screens/Project/shared/ProjectForm.jsx b/awx/ui_next/src/screens/Project/shared/ProjectForm.jsx
index eee485d646..692c66d3d2 100644
--- a/awx/ui_next/src/screens/Project/shared/ProjectForm.jsx
+++ b/awx/ui_next/src/screens/Project/shared/ProjectForm.jsx
@@ -172,7 +172,9 @@ function ProjectFormFields({
fieldId="project-scm-type"
helperTextInvalid={scmTypeMeta.error}
isRequired
- isValid={!scmTypeMeta.touched || !scmTypeMeta.error}
+ validated={
+ !scmTypeMeta.touched || !scmTypeMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`Source Control Credential Type`)}
>
<AnsibleSelect
@@ -204,7 +206,9 @@ function ProjectFormFields({
</FormGroup>
{formik.values.scm_type !== '' && (
<SubFormLayout>
- <Title size="md">{i18n._(t`Type Details`)}</Title>
+ <Title size="md" headingLevel="h4">
+ {i18n._(t`Type Details`)}
+ </Title>
<FormColumnLayout>
{
{
diff --git a/awx/ui_next/src/screens/Project/shared/ProjectSubForms/ManualSubForm.jsx b/awx/ui_next/src/screens/Project/shared/ProjectSubForms/ManualSubForm.jsx
index 96646238d9..b6ece76103 100644
--- a/awx/ui_next/src/screens/Project/shared/ProjectSubForms/ManualSubForm.jsx
+++ b/awx/ui_next/src/screens/Project/shared/ProjectSubForms/ManualSubForm.jsx
@@ -81,7 +81,7 @@ const ManualSubForm = ({
fieldId="project-local-path"
helperTextInvalid={pathMeta.error}
isRequired
- isValid={!pathMeta.touched || !pathMeta.error}
+ validated={!pathMeta.touched || !pathMeta.error ? 'default' : 'error'}
label={i18n._(t`Playbook Directory`)}
>
<FieldTooltip
diff --git a/awx/ui_next/src/screens/Project/shared/ProjectSubForms/SharedFields.jsx b/awx/ui_next/src/screens/Project/shared/ProjectSubForms/SharedFields.jsx
index 0833c9e49d..4956c1cab1 100644
--- a/awx/ui_next/src/screens/Project/shared/ProjectSubForms/SharedFields.jsx
+++ b/awx/ui_next/src/screens/Project/shared/ProjectSubForms/SharedFields.jsx
@@ -104,7 +104,9 @@ export const ScmTypeOptions = withI18n()(
{scmUpdateOnLaunch && (
<>
- <Title size="md">{i18n._(t`Option Details`)}</Title>
+ <Title size="md" headingLevel="h4">
+ {i18n._(t`Option Details`)}
+ </Title>
<FormField
id="project-cache-timeout"
name="scm_update_cache_timeout"
diff --git a/awx/ui_next/src/screens/SystemSetting/SystemSettings.jsx b/awx/ui_next/src/screens/SystemSetting/SystemSettings.jsx
index d81dda3ea2..458658e23c 100644
--- a/awx/ui_next/src/screens/SystemSetting/SystemSettings.jsx
+++ b/awx/ui_next/src/screens/SystemSetting/SystemSettings.jsx
@@ -15,7 +15,9 @@ class SystemSettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`System Settings`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`System Settings`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/Team/Team.jsx b/awx/ui_next/src/screens/Team/Team.jsx
index b7e878b415..c3366af422 100644
--- a/awx/ui_next/src/screens/Team/Team.jsx
+++ b/awx/ui_next/src/screens/Team/Team.jsx
@@ -9,9 +9,8 @@ import {
useLocation,
useParams,
} from 'react-router-dom';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
-import CardCloseButton from '../../components/CardCloseButton';
-import { TabbedCardHeader } from '../../components/Card';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import RoutedTabs from '../../components/RoutedTabs';
import ContentError from '../../components/ContentError';
import TeamDetail from './TeamDetail';
@@ -41,22 +40,25 @@ function Team({ i18n, setBreadcrumb }) {
}, [id, setBreadcrumb, location]);
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Teams`)}
+ </>
+ ),
+ link: `/teams`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `/teams/${id}/details`, id: 0 },
{ name: i18n._(t`Users`), link: `/teams/${id}/users`, id: 1 },
{ name: i18n._(t`Access`), link: `/teams/${id}/access`, id: 2 },
];
- let cardHeader = (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/teams" />
- </CardActions>
- </TabbedCardHeader>
- );
+ let showCardHeader = true;
if (location.pathname.endsWith('edit')) {
- cardHeader = null;
+ showCardHeader = false;
}
if (!hasContentLoading && contentError) {
@@ -79,7 +81,7 @@ function Team({ i18n, setBreadcrumb }) {
return (
<PageSection>
<Card>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect from="/teams/:id" to="/teams/:id/details" exact />
{team && (
diff --git a/awx/ui_next/src/screens/Team/TeamAccess/TeamAccessListItem.jsx b/awx/ui_next/src/screens/Team/TeamAccess/TeamAccessListItem.jsx
index 12495c8003..e32199d19e 100644
--- a/awx/ui_next/src/screens/Team/TeamAccess/TeamAccessListItem.jsx
+++ b/awx/ui_next/src/screens/Team/TeamAccess/TeamAccessListItem.jsx
@@ -40,12 +40,12 @@ function TeamAccessListItem({ role, i18n, detailUrl, onSelect }) {
label={i18n._(t`Role`)}
value={
<Chip
- isReadOnly={
- !role.summary_fields.user_capabilities.unattach
- }
key={role.name}
aria-label={role.name}
onClick={() => onSelect(role)}
+ isReadOnly={
+ !role.summary_fields.user_capabilities.unattach
+ }
>
{role.name}
</Chip>
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx
index 755956a5f4..bdc70c4fff 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyList.test.jsx
@@ -142,7 +142,7 @@ describe('<SurveyList />', () => {
expect(
wrapper
- .find('DataToolbar')
+ .find('Toolbar')
.find('Checkbox')
.prop('isDisabled')
).toBe(true);
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx
index e9d8f0a1d2..f26f1f8ed1 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.jsx
@@ -30,9 +30,10 @@ function SurveyPreviewModal({
return (
<Modal
title={i18n._(t`Survey Preview`)}
+ aria-label={i18n._(t`Survey preview modal`)}
isOpen={isPreviewModalOpen}
onClose={() => onToggleModalOpen(false)}
- isSmall
+ variant="small"
>
<Formik initialValues={initialValues}>
{() => (
@@ -97,7 +98,7 @@ function SurveyPreviewModal({
isDisabled
isReadOnly
variant={SelectVariant.typeaheadMulti}
- isExpanded={false}
+ isOpen={false}
selections={q.default.length > 0 && q.default.split('\n')}
onToggle={() => {}}
aria-label={i18n._(t`Multi-Select`)}
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.test.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.test.jsx
index ec56a7c7b7..74aac44a3f 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.test.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyPreviewModal.test.jsx
@@ -106,19 +106,20 @@ describe('<SurveyPreviewModal />', () => {
.find('Select[aria-label="Multi-Select"]')
.find('Chip');
- expect(question1.text()).toBe('Text Question');
+ expect(question1.text()).toBe('Text Question ');
expect(question1Value.prop('value')).toBe('Text Question Value');
expect(question1Value.prop('isDisabled')).toBe(true);
expect(question2.text()).toBe('Select Question');
- expect(question2Value.find('span').text()).toBe('Select Question Value');
+ expect(question2Value.find('.pf-c-select__toggle-text').text()).toBe(
+ 'Select Question Value'
+ );
expect(question2Value.prop('isDisabled')).toBe(true);
expect(question3.text()).toBe('Text Area Question');
expect(question3Value.prop('value')).toBe('Text Area Question Value');
expect(question3Value.prop('disabled')).toBe(true);
-
- expect(question4.text()).toBe('Password Question');
+ expect(question4.text()).toBe('Password Question ');
expect(question4Value.prop('placeholder')).toBe('ENCRYPTED');
expect(question4Value.prop('isDisabled')).toBe(true);
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.jsx
index af6144025a..16eac2be70 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.jsx
@@ -5,15 +5,17 @@ import { withI18n } from '@lingui/react';
import styled from 'styled-components';
import {
- DataToolbar as _DataToolbar,
- DataToolbarContent,
- DataToolbarGroup,
- DataToolbarItem,
-} from '@patternfly/react-core/dist/umd/experimental';
-import { Switch, Checkbox, Button } from '@patternfly/react-core';
+ Switch,
+ Checkbox,
+ Button,
+ Toolbar as _Toolbar,
+ ToolbarContent,
+ ToolbarGroup,
+ ToolbarItem,
+} from '@patternfly/react-core';
import { ToolbarAddButton } from '../../../components/PaginatedDataList';
-const DataToolbar = styled(_DataToolbar)`
+const Toolbar = styled(_Toolbar)`
margin-left: 52px;
`;
@@ -30,9 +32,9 @@ function SurveyToolbar({
isDeleteDisabled = !canEdit || isDeleteDisabled;
const match = useRouteMatch();
return (
- <DataToolbar id="survey-toolbar">
- <DataToolbarContent>
- <DataToolbarItem>
+ <Toolbar id="survey-toolbar">
+ <ToolbarContent>
+ <ToolbarItem>
<Checkbox
isDisabled={!canEdit}
isChecked={isAllSelected}
@@ -42,8 +44,8 @@ function SurveyToolbar({
aria-label={i18n._(t`Select all`)}
id="select-all"
/>
- </DataToolbarItem>
- <DataToolbarItem>
+ </ToolbarItem>
+ <ToolbarItem>
<Switch
aria-label={i18n._(t`Survey Toggle`)}
id="survey-toggle"
@@ -53,15 +55,15 @@ function SurveyToolbar({
isDisabled={!canEdit}
onChange={() => onToggleSurvey(!surveyEnabled)}
/>
- </DataToolbarItem>
- <DataToolbarGroup>
- <DataToolbarItem>
+ </ToolbarItem>
+ <ToolbarGroup>
+ <ToolbarItem>
<ToolbarAddButton
isDisabled={!canEdit}
linkTo={`${match.url}/add`}
/>
- </DataToolbarItem>
- <DataToolbarItem>
+ </ToolbarItem>
+ <ToolbarItem>
<Button
variant="danger"
isDisabled={isDeleteDisabled}
@@ -69,10 +71,10 @@ function SurveyToolbar({
>
{i18n._(t`Delete`)}
</Button>
- </DataToolbarItem>
- </DataToolbarGroup>
- </DataToolbarContent>
- </DataToolbar>
+ </ToolbarItem>
+ </ToolbarGroup>
+ </ToolbarContent>
+ </Toolbar>
);
}
diff --git a/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.test.jsx b/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.test.jsx
index 8fb4857525..2311f1d443 100644
--- a/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.test.jsx
+++ b/awx/ui_next/src/screens/Template/Survey/SurveyToolbar.test.jsx
@@ -102,7 +102,7 @@ describe('<SurveyToolbar />', () => {
});
expect(
wrapper
- .find('DataToolbar')
+ .find('Toolbar')
.find('Checkbox')
.prop('isDisabled')
).toBe(true);
diff --git a/awx/ui_next/src/screens/Template/Template.jsx b/awx/ui_next/src/screens/Template/Template.jsx
index 7110f025fc..5bd84e8383 100644
--- a/awx/ui_next/src/screens/Template/Template.jsx
+++ b/awx/ui_next/src/screens/Template/Template.jsx
@@ -1,7 +1,8 @@
import React, { useEffect, useCallback } from 'react';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import {
Switch,
Route,
@@ -11,14 +12,11 @@ import {
useParams,
useRouteMatch,
} from 'react-router-dom';
+import RoutedTabs from '../../components/RoutedTabs';
import useRequest from '../../util/useRequest';
-
-import { TabbedCardHeader } from '../../components/Card';
-import CardCloseButton from '../../components/CardCloseButton';
import ContentError from '../../components/ContentError';
import JobList from '../../components/JobList';
import NotificationList from '../../components/NotificationList';
-import RoutedTabs from '../../components/RoutedTabs';
import { Schedules } from '../../components/Schedule';
import { ResourceAccessList } from '../../components/ResourceAccessList';
import JobTemplateDetail from './JobTemplateDetail';
@@ -82,6 +80,16 @@ function Template({ i18n, me, setBreadcrumb }) {
template?.summary_fields?.user_capabilities.delete;
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Templates`)}
+ </>
+ ),
+ link: `/templates`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details` },
{ name: i18n._(t`Access`), link: `${match.url}/access` },
];
@@ -115,19 +123,13 @@ function Template({ i18n, me, setBreadcrumb }) {
tab.id = n;
});
- let cardHeader = (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/templates" />
- </CardActions>
- </TabbedCardHeader>
- );
+ let showCardHeader = true;
+
if (
location.pathname.endsWith('edit') ||
location.pathname.includes('schedules/')
) {
- cardHeader = null;
+ showCardHeader = false;
}
const contentError = rolesAndTemplateError;
@@ -151,7 +153,7 @@ function Template({ i18n, me, setBreadcrumb }) {
return (
<PageSection>
<Card>
- {cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/templates/:templateType/:id"
diff --git a/awx/ui_next/src/screens/Template/Template.test.jsx b/awx/ui_next/src/screens/Template/Template.test.jsx
index 0495fdd9bf..8176e4486a 100644
--- a/awx/ui_next/src/screens/Template/Template.test.jsx
+++ b/awx/ui_next/src/screens/Template/Template.test.jsx
@@ -59,9 +59,9 @@ describe('<Template />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 6
+ el => el.length === 7
);
- expect(tabs.at(2).text()).toEqual('Notifications');
+ expect(tabs.at(3).text()).toEqual('Notifications');
done();
});
test('notifications tab hidden with reduced permissions', async done => {
@@ -83,7 +83,7 @@ describe('<Template />', () => {
const tabs = await waitForElement(
wrapper,
'.pf-c-tabs__item',
- el => el.length === 5
+ el => el.length === 6
);
tabs.forEach(tab => expect(tab.text()).not.toEqual('Notifications'));
done();
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplate.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplate.jsx
index eb40b93f4f..9706f89ae2 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplate.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplate.jsx
@@ -1,11 +1,10 @@
import React, { Component } from 'react';
import { t } from '@lingui/macro';
import { withI18n } from '@lingui/react';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import { Switch, Route, Redirect, withRouter, Link } from 'react-router-dom';
-import { TabbedCardHeader } from '../../components/Card';
import AppendBody from '../../components/AppendBody';
-import CardCloseButton from '../../components/CardCloseButton';
import ContentError from '../../components/ContentError';
import FullPage from '../../components/FullPage';
import JobList from '../../components/JobList';
@@ -121,6 +120,16 @@ class WorkflowJobTemplate extends Component {
template?.summary_fields?.user_capabilities.delete;
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Templates`)}
+ </>
+ ),
+ link: `/templates`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details` },
{ name: i18n._(t`Access`), link: `${match.url}/access` },
];
@@ -183,22 +192,19 @@ class WorkflowJobTemplate extends Component {
);
}
- const cardHeader = (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo="/templates" />
- </CardActions>
- </TabbedCardHeader>
- );
+ let showCardHeader = true;
+
+ if (
+ location.pathname.endsWith('edit') ||
+ location.pathname.includes('schedules/')
+ ) {
+ showCardHeader = false;
+ }
return (
<PageSection>
<Card>
- {location.pathname.endsWith('edit') ||
- location.pathname.includes('schedules/')
- ? null
- : cardHeader}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
<Switch>
<Redirect
from="/templates/workflow_job_template/:id"
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.test.jsx
index 9930643538..5217dff7c5 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.test.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateDetail/WorkflowJobTemplateDetail.test.jsx
@@ -131,11 +131,11 @@ describe('<WorkflowJobTemplateDetail/>', () => {
const organization = wrapper
.find('Detail[label="Organization"]')
- .find('span');
+ .find('.pf-c-label__content');
const inventory = wrapper.find('Detail[label="Inventory"]').find('a');
const labels = wrapper
.find('Detail[label="Labels"]')
- .find('Chip[component="li"]');
+ .find('Chip[component="div"]');
const sparkline = wrapper.find('Sparkline Link');
expect(organization.text()).toBe('Org');
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkAddModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkAddModal.jsx
index 97a941755e..5d7baf4099 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkAddModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkAddModal.jsx
@@ -1,5 +1,5 @@
import React, { useContext } from 'react';
-import { BaseSizes, Title, TitleLevel } from '@patternfly/react-core';
+import { Title } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { WorkflowDispatchContext } from '../../../../../contexts/Workflow';
@@ -10,7 +10,7 @@ function LinkAddModal({ i18n }) {
return (
<LinkModal
header={
- <Title headingLevel={TitleLevel.h1} size={BaseSizes['2xl']}>
+ <Title headingLevel="h1" size="xl">
{i18n._(t`Add Link`)}
</Title>
}
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkEditModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkEditModal.jsx
index 177e11bb32..8c4259b73a 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkEditModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkEditModal.jsx
@@ -1,5 +1,5 @@
import React, { useContext } from 'react';
-import { BaseSizes, Title, TitleLevel } from '@patternfly/react-core';
+import { Title } from '@patternfly/react-core';
import { withI18n } from '@lingui/react';
import { t } from '@lingui/macro';
import { WorkflowDispatchContext } from '../../../../../contexts/Workflow';
@@ -10,7 +10,7 @@ function LinkEditModal({ i18n }) {
return (
<LinkModal
header={
- <Title headingLevel={TitleLevel.h1} size={BaseSizes['2xl']}>
+ <Title headingLevel="h1" size="xl">
{i18n._(t`Edit Link`)}
</Title>
}
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.jsx
index 0cf4601c4c..ed11bf59c2 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/LinkModals/LinkModal.jsx
@@ -20,8 +20,8 @@ function LinkModal({ header, i18n, onConfirm }) {
width={600}
header={header}
isOpen
- isFooterLeftAligned
title={i18n._(t`Workflow Link`)}
+ aria-label={i18n._(t`Workflow link modal`)}
onClose={() => dispatch({ type: 'CANCEL_LINK_MODAL' })}
actions={[
<Button
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeModal.test.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeModal.test.jsx
index 39f410f338..405e8a91e4 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeModal.test.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeModal.test.jsx
@@ -4,7 +4,10 @@ import {
WorkflowDispatchContext,
WorkflowStateContext,
} from '../../../../../contexts/Workflow';
-import { mountWithContexts } from '../../../../../../testUtils/enzymeHelpers';
+import {
+ waitForElement,
+ mountWithContexts,
+} from '../../../../../../testUtils/enzymeHelpers';
import {
InventorySourcesAPI,
JobTemplatesAPI,
@@ -95,6 +98,7 @@ describe('NodeModal', () => {
</WorkflowDispatchContext.Provider>
);
});
+ await waitForElement(wrapper, 'PFWizard');
});
afterAll(() => {
@@ -307,6 +311,7 @@ describe('NodeModal', () => {
</WorkflowDispatchContext.Provider>
);
});
+ await waitForElement(wrapper, 'PFWizard');
expect(wrapper.find('AnsibleSelect').prop('value')).toBe('project_sync');
await act(async () => {
wrapper.find('AnsibleSelect').prop('onChange')(null, 'approval');
@@ -388,6 +393,7 @@ describe('NodeModal', () => {
</WorkflowDispatchContext.Provider>
);
});
+ await waitForElement(wrapper, 'PFWizard');
expect(wrapper.find('AnsibleSelect').prop('value')).toBe('approval');
await act(async () => {
wrapper.find('AnsibleSelect').prop('onChange')(
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx
index 146485d4cb..e9ee7928bb 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeTypeStep/NodeTypeStep.jsx
@@ -131,14 +131,14 @@ function NodeTypeStep({
<FormGroup
fieldId="approval-name"
isRequired
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
label={i18n._(t`Name`)}
>
<TextInput
autoFocus
id="approval-name"
isRequired
- isValid={isValid}
+ validated={isValid ? 'default' : 'error'}
type="text"
{...field}
onChange={(value, evt) => {
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.jsx
index 281c7b0368..6eb01a9a0e 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/NodeModals/NodeViewModal.jsx
@@ -131,10 +131,10 @@ function NodeViewModal({ i18n }) {
return (
<Modal
- isLarge
+ variant="large"
isOpen
- isFooterLeftAligned
title={unifiedJobTemplate.name}
+ aria-label={i18n._(t`Workflow node view modal`)}
onClose={() => dispatch({ type: 'SET_NODE_TO_VIEW', value: null })}
actions={[
<Button
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.jsx
index d06803ee53..84316595c3 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/Modals/UnsavedChangesModal.jsx
@@ -11,8 +11,8 @@ function UnsavedChangesModal({ i18n, onSaveAndExit, onExit }) {
<Modal
width={600}
isOpen
- isFooterLeftAligned
title={i18n._(t`Warning: Unsaved Changes`)}
+ aria-label={i18n._(t`Unsaved changes modal`)}
onClose={() => dispatch({ type: 'TOGGLE_UNSAVED_CHANGES_MODAL' })}
actions={[
<Button
diff --git a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
index 7f93f9a315..0857313036 100644
--- a/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
+++ b/awx/ui_next/src/screens/Template/WorkflowJobTemplateVisualizer/VisualizerToolbar.jsx
@@ -68,7 +68,11 @@ function VisualizerToolbar({
return (
<div id="visualizer-toolbar">
<div css="align-items: center; border-bottom: 1px solid grey; display: flex; height: 56px; padding: 0px 20px;">
- <Title size="xl" id="visualizer-toolbar-template-name">
+ <Title
+ headingLevel="h2"
+ size="xl"
+ id="visualizer-toolbar-template-name"
+ >
{template.name}
</Title>
<div css="align-items: center; display: flex; flex: 1; justify-content: flex-end">
diff --git a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
index 7bd4409fde..ca5ad56073 100644
--- a/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
+++ b/awx/ui_next/src/screens/Template/shared/JobTemplateForm.jsx
@@ -291,7 +291,9 @@ function JobTemplateForm({
<FormGroup
fieldId="template-playbook"
helperTextInvalid={playbookMeta.error}
- isValid={!playbookMeta.touched || !playbookMeta.error}
+ validated={
+ !playbookMeta.touched || !playbookMeta.error ? 'default' : 'error'
+ }
isRequired
label={i18n._(t`Playbook`)}
>
@@ -381,7 +383,9 @@ function JobTemplateForm({
<TextInput
id="template-limit"
{...limitField}
- isValid={!limitMeta.touched || !limitMeta.error}
+ validated={
+ !limitMeta.touched || !limitMeta.error ? 'default' : 'error'
+ }
onChange={value => {
limitHelpers.setValue(value);
}}
diff --git a/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx b/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx
index d1f8de5ecc..539947738f 100644
--- a/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx
+++ b/awx/ui_next/src/screens/Template/shared/LabelSelect.jsx
@@ -83,8 +83,8 @@ function LabelSelect({ value, placeholder, onChange, onError, createText }) {
}}
isDisabled={isLoading}
selections={selections}
- isExpanded={isExpanded}
- ariaLabelledBy="label-select"
+ isOpen={isExpanded}
+ aria-labelledby="label-select"
placeholderText={placeholder}
createText={createText}
>
diff --git a/awx/ui_next/src/screens/UISetting/UISettings.jsx b/awx/ui_next/src/screens/UISetting/UISettings.jsx
index 1905463cd2..1ecec2af54 100644
--- a/awx/ui_next/src/screens/UISetting/UISettings.jsx
+++ b/awx/ui_next/src/screens/UISetting/UISettings.jsx
@@ -15,7 +15,9 @@ class UISettings extends Component {
return (
<Fragment>
<PageSection variant={light} className="pf-m-condensed">
- <Title size="2xl">{i18n._(t`User Interface Settings`)}</Title>
+ <Title size="2xl" headingLevel="h2">
+ {i18n._(t`User Interface Settings`)}
+ </Title>
</PageSection>
<PageSection />
</Fragment>
diff --git a/awx/ui_next/src/screens/User/User.jsx b/awx/ui_next/src/screens/User/User.jsx
index 5e195da2f3..1aa8bca032 100644
--- a/awx/ui_next/src/screens/User/User.jsx
+++ b/awx/ui_next/src/screens/User/User.jsx
@@ -9,11 +9,10 @@ import {
useRouteMatch,
useLocation,
} from 'react-router-dom';
-import { Card, CardActions, PageSection } from '@patternfly/react-core';
+import { CaretLeftIcon } from '@patternfly/react-icons';
+import { Card, PageSection } from '@patternfly/react-core';
import useRequest from '../../util/useRequest';
import { UsersAPI } from '../../api';
-import { TabbedCardHeader } from '../../components/Card';
-import CardCloseButton from '../../components/CardCloseButton';
import ContentError from '../../components/ContentError';
import ContentLoading from '../../components/ContentLoading';
import RoutedTabs from '../../components/RoutedTabs';
@@ -52,6 +51,16 @@ function User({ i18n, setBreadcrumb }) {
}, [user, setBreadcrumb]);
const tabsArray = [
+ {
+ name: (
+ <>
+ <CaretLeftIcon />
+ {i18n._(t`Back to Users`)}
+ </>
+ ),
+ link: `/users`,
+ id: 99,
+ },
{ name: i18n._(t`Details`), link: `${match.url}/details`, id: 0 },
{
name: i18n._(t`Organizations`),
@@ -63,6 +72,11 @@ function User({ i18n, setBreadcrumb }) {
{ name: i18n._(t`Tokens`), link: `${match.url}/tokens`, id: 4 },
];
+ let showCardHeader = true;
+ if (['edit'].some(name => location.pathname.includes(name))) {
+ showCardHeader = false;
+ }
+
if (contentError) {
return (
<PageSection>
@@ -82,14 +96,7 @@ function User({ i18n, setBreadcrumb }) {
return (
<PageSection>
<Card>
- {['edit'].some(name => location.pathname.includes(name)) ? null : (
- <TabbedCardHeader>
- <RoutedTabs tabsArray={tabsArray} />
- <CardActions>
- <CardCloseButton linkTo={userListUrl} />
- </CardActions>
- </TabbedCardHeader>
- )}
+ {showCardHeader && <RoutedTabs tabsArray={tabsArray} />}
{isLoading && <ContentLoading />}
{!isLoading && user && (
<Switch>
diff --git a/awx/ui_next/src/screens/User/User.test.jsx b/awx/ui_next/src/screens/User/User.test.jsx
index 725247776d..ae3d951ceb 100644
--- a/awx/ui_next/src/screens/User/User.test.jsx
+++ b/awx/ui_next/src/screens/User/User.test.jsx
@@ -72,20 +72,10 @@ describe('<User />', () => {
},
});
});
- await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 5);
+ await waitForElement(wrapper, '.pf-c-tabs__item', el => el.length === 6);
/* eslint-disable react/button-has-type */
- expect(
- wrapper
- .find('Tabs')
- .containsAllMatchingElements([
- <button aria-label="Details">Details</button>,
- <button aria-label="Organizations">Organizations</button>,
- <button aria-label="Teams">Teams</button>,
- <button aria-label="Access">Access</button>,
- <button aria-label="Tokens">Tokens</button>,
- ])
- ).toEqual(true);
+ expect(wrapper.find('Tabs TabButton').length).toEqual(6);
});
test('should show content error when user attempts to navigate to erroneous route', async () => {
diff --git a/awx/ui_next/src/screens/User/UserAccess/UserAccessListItem.jsx b/awx/ui_next/src/screens/User/UserAccess/UserAccessListItem.jsx
index c06e4cca8d..524d07d438 100644
--- a/awx/ui_next/src/screens/User/UserAccess/UserAccessListItem.jsx
+++ b/awx/ui_next/src/screens/User/UserAccess/UserAccessListItem.jsx
@@ -40,12 +40,12 @@ function UserAccessListItem({ role, i18n, detailUrl, onSelect }) {
label={i18n._(t`Role`)}
value={
<Chip
- isReadOnly={
- !role.summary_fields.user_capabilities.unattach
- }
key={role.name}
aria-label={role.name}
onClick={() => onSelect(role)}
+ isReadOnly={
+ !role.summary_fields.user_capabilities.unattach
+ }
>
{role.name}
</Chip>
diff --git a/awx/ui_next/src/screens/User/shared/UserForm.jsx b/awx/ui_next/src/screens/User/shared/UserForm.jsx
index 47294ff105..aa5229f296 100644
--- a/awx/ui_next/src/screens/User/shared/UserForm.jsx
+++ b/awx/ui_next/src/screens/User/shared/UserForm.jsx
@@ -117,7 +117,9 @@ function UserFormFields({ user, i18n }) {
fieldId="user-type"
helperTextInvalid={userTypeMeta.error}
isRequired
- isValid={!userTypeMeta.touched || !userTypeMeta.error}
+ validated={
+ !userTypeMeta.touched || !userTypeMeta.error ? 'default' : 'error'
+ }
label={i18n._(t`User Type`)}
>
<AnsibleSelect