From 5400094b2d137259da5f2b6e20519fb51cd7eb5e Mon Sep 17 00:00:00 2001 From: blaipr Date: Fri, 19 Jun 2026 02:12:32 +0200 Subject: [PATCH] Convert .defaultProps to ES default parameters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit defaultProps on function components is deprecated in React 18.3 and removed in React 19, so convert all 117 component files from `Component.defaultProps = {...}` to ES default parameters in the function signature. De-risks the React 18 bump (otherwise every defaultProps usage would warn and, via the strict console trap, fail its test suite). - eslint.config.mjs: set react/require-default-props to { functions: 'defaultArguments' } so the rule accepts signature default params instead of requiring a defaultProps declaration. - CheckboxListItem: isSelected had a default param but was marked isRequired; a prop with a default is optional, so drop .isRequired (the new rule surfaced this pre-existing inconsistency). - CredentialLookup: its idOrKind validator relied on defaultProps being applied to the element BEFORE PropTypes ran (the '' default made credentialTypeKind always present, silently disabling the validator). Default params don't reach PropTypes, so treat an omitted credentialTypeKind as that former '' default to preserve behavior (callers like the EC2/Azure/... subforms pass credentialTypeNamespace instead of id/kind). - Stabilize the seven defaults that feed a hook dependency array (PaginatedTable clearSelected, VariablesField validators, PeersLookup instance_details, ScheduleForm schedule, HostEventModal hostEvent, PlaybookSelect onChange, JobTemplateForm template) by hoisting the literal to a module-level constant — defaultProps created the value once (stable ref); a param default would create a new one each render, re-running the dependent effect/memo. - Remove two obsolete tests that asserted Component.defaultProps.onBlur directly (that object no longer exists; the param-default noop is self-evidently safe). Full Jest suite green (552 suites / 2908 tests), lint clean. --- awx/ui/eslint.config.mjs | 4 ++ awx/ui/src/components/About/About.js | 7 +- .../src/components/AddRole/AddResourceRole.js | 13 ++-- awx/ui/src/components/AddRole/CheckboxCard.js | 15 ++--- .../components/AddRole/SelectResourceStep.js | 21 ++---- .../src/components/AddRole/SelectRoleStep.js | 18 ++--- .../components/AnsibleSelect/AnsibleSelect.js | 18 ++--- .../AppContainer/PageHeaderToolbar.js | 6 +- .../CheckboxListItem/CheckboxListItem.js | 2 +- .../src/components/CodeEditor/CodeEditor.js | 21 ++---- .../components/CodeEditor/CodeEditorField.js | 18 ++--- .../components/CodeEditor/VariablesDetail.js | 12 +--- .../components/CodeEditor/VariablesField.js | 23 +++---- .../components/ContentError/ContentError.js | 7 +- .../src/components/CopyButton/CopyButton.js | 9 +-- .../DataListToolbar/DataListToolbar.js | 54 +++++---------- .../components/DeleteButton/DeleteButton.js | 6 +- .../src/components/DetailList/CodeDetail.js | 15 +++-- awx/ui/src/components/DetailList/Detail.js | 15 ++--- .../components/DetailList/UserDateDetail.js | 6 +- .../DisassociateButton/DisassociateButton.js | 6 -- .../src/components/ErrorDetail/ErrorDetail.js | 6 +- .../ExecutionEnvironmentDetail.js | 21 ++---- .../ExpandCollapse/ExpandCollapse.js | 6 +- .../FieldWithPrompt/FieldWithPrompt.js | 9 +-- .../FormActionGroup/FormActionGroup.js | 6 +- .../components/FormField/ArrayTextField.js | 34 ++++------ .../src/components/FormField/CheckboxField.js | 9 +-- awx/ui/src/components/FormField/FormField.js | 35 ++++------ .../src/components/FormField/PasswordField.js | 27 +++++--- .../src/components/FormField/PasswordInput.js | 26 +++----- awx/ui/src/components/HostForm/HostForm.js | 31 ++++----- .../InstanceGroupLabels.js | 4 +- .../components/JobList/JobListCancelButton.js | 7 +- .../src/components/LabelSelect/LabelSelect.js | 12 ++-- .../src/components/ListHeader/ListHeader.js | 30 ++++----- .../components/Lookup/ApplicationLookup.js | 14 ++-- .../src/components/Lookup/CredentialLookup.js | 56 ++++++---------- .../Lookup/CredentialLookup.test.js | 5 -- .../Lookup/ExecutionEnvironmentLookup.js | 27 +++----- .../src/components/Lookup/HostFilterLookup.js | 24 ++----- .../components/Lookup/InstanceGroupsLookup.js | 21 ++---- .../src/components/Lookup/InventoryLookup.js | 30 +++------ awx/ui/src/components/Lookup/Lookup.js | 66 +++++++------------ .../Lookup/MultiCredentialsLookup.js | 12 +--- .../components/Lookup/OrganizationLookup.js | 33 +++------- .../Lookup/OrganizationLookup.test.js | 5 -- awx/ui/src/components/Lookup/PeersLookup.js | 38 ++++------- awx/ui/src/components/Lookup/ProjectLookup.js | 33 +++------- .../NotificationList/NotificationList.js | 6 +- .../NotificationList/NotificationListItem.js | 18 ++--- .../src/components/OptionsList/OptionsList.js | 20 ++---- .../components/PaginatedTable/HeaderRow.js | 6 +- .../PaginatedTable/PaginatedTable.js | 36 ++++------ .../PaginatedTable/ToolbarAddButton.js | 8 +-- .../PaginatedTable/ToolbarDeleteButton.js | 12 +--- .../PaginatedTable/ToolbarSyncSourceButton.js | 5 +- awx/ui/src/components/Popover/Popover.js | 16 ++--- .../components/PromptDetail/PromptDetail.js | 6 +- .../DeleteRoleConfirmationModal.js | 11 ++-- .../Schedule/ScheduleAdd/ScheduleAdd.js | 2 - .../Schedule/ScheduleEdit/ScheduleEdit.js | 2 - .../Schedule/ScheduleList/ScheduleList.js | 5 +- .../ScheduleOccurrences.js | 10 ++- .../Schedule/shared/ScheduleForm.js | 11 ++-- .../src/components/Search/AdvancedSearch.js | 21 ++---- .../src/components/Search/LookupTypeInput.js | 17 ++--- awx/ui/src/components/Search/Search.js | 24 ++----- .../SelectableCard/SelectableCard.js | 15 ++--- .../SelectedList/DraggableSelectedList.js | 11 ++-- .../components/SelectedList/SelectedList.js | 20 +++--- awx/ui/src/components/Sort/Sort.js | 6 +- awx/ui/src/components/Sparkline/Sparkline.js | 5 +- .../Workflow/WorkflowActionTooltipItem.js | 12 +--- .../components/Workflow/WorkflowStartNode.js | 6 +- .../Credential/shared/CredentialForm.js | 10 +-- .../CredentialFormFields/BecomeMethodField.js | 5 +- .../CredentialFormFields/CredentialField.js | 8 +-- .../CredentialPluginField.js | 14 ++-- .../CredentialPluginPrompt.js | 6 +- .../CredentialPluginSelected.js | 9 +-- .../CredentialPluginTestAlert.js | 9 +-- .../Credential/shared/ExternalTestModal.js | 6 +- .../Credential/shared/TypeInputsSubForm.js | 2 - .../shared/CredentialTypeForm.js | 7 +- .../shared/ExecutionEnvironmentForm.js | 10 +-- .../Host/HostList/SmartInventoryButton.js | 12 +--- .../HostMetrics/HostMetricsDeleteButton.js | 9 +-- .../shared/ContainerGroupForm.js | 12 +--- .../InstanceGroup/shared/InstanceGroupForm.js | 7 +- .../shared/ConstructedInventoryForm.js | 6 +- .../shared/FederatedInventoryForm.js | 6 +- .../screens/Inventory/shared/InventoryForm.js | 10 +-- .../shared/InventoryGroupsDeleteModal.js | 10 +-- .../Inventory/shared/InventorySourceForm.js | 4 -- .../shared/InventorySourceSyncButton.js | 7 +- .../Inventory/shared/SmartInventoryForm.js | 12 +--- .../screens/Job/JobOutput/HostEventModal.js | 9 +-- .../Job/JobOutput/shared/OutputToolbar.js | 11 ++-- awx/ui/src/screens/Job/JobTypeRedirect.js | 5 +- .../WorkflowOutput/WorkflowOutputToolbar.js | 11 ++-- .../shared/NotificationTemplateForm.js | 17 ++--- .../shared/TypeInputsSubForm.js | 45 +++---------- .../Organization/shared/OrganizationForm.js | 24 +++---- .../src/screens/Project/shared/ProjectForm.js | 7 +- .../screens/Setting/shared/SharedFields.js | 10 +-- awx/ui/src/screens/Team/shared/TeamForm.js | 15 ++--- .../Template/Survey/SurveyQuestionForm.js | 8 +-- .../NodeTypeStep/InventorySourcesList.js | 6 +- .../NodeTypeStep/JobTemplatesList.js | 6 +- .../NodeModals/NodeTypeStep/ProjectsList.js | 6 +- .../NodeTypeStep/SystemJobTemplatesList.js | 6 +- .../NodeTypeStep/WorkflowJobTemplatesList.js | 6 +- .../VisualizerNode.js | 6 +- .../Template/shared/JobTemplateForm.js | 46 +++++++------ .../screens/Template/shared/PlaybookSelect.js | 11 ++-- .../shared/WorkflowJobTemplateForm.js | 25 +++---- awx/ui/src/screens/User/shared/UserForm.js | 6 +- .../WorkflowApprovalDetail.js | 5 -- .../WorkflowApprovalListApproveButton.js | 6 +- .../WorkflowApprovalListDenyButton.js | 6 +- 121 files changed, 547 insertions(+), 1171 deletions(-) diff --git a/awx/ui/eslint.config.mjs b/awx/ui/eslint.config.mjs index 97d906b45..d1fc03f6c 100644 --- a/awx/ui/eslint.config.mjs +++ b/awx/ui/eslint.config.mjs @@ -214,6 +214,10 @@ export default defineConfig([ 'react/jsx-props-no-spreading': ['off'], 'react/prefer-stateless-function': 'off', 'react/prop-types': 'off', + // default values are expressed via ES default parameters (the React + // 18.3/19 migration away from the deprecated defaultProps), so accept a + // destructured default argument in place of a defaultProps entry + 'react/require-default-props': ['error', { functions: 'defaultArguments' }], 'react/sort-comp': ['error', {}], 'jsx-a11y/label-has-for': 'off', 'jsx-a11y/label-has-associated-control': 'off', diff --git a/awx/ui/src/components/About/About.js b/awx/ui/src/components/About/About.js index 6882dae74..714ef8af4 100644 --- a/awx/ui/src/components/About/About.js +++ b/awx/ui/src/components/About/About.js @@ -8,7 +8,7 @@ import { useLingui } from '@lingui/react/macro'; import { AboutModal } from '@patternfly/react-core'; import useBrandName from 'hooks/useBrandName'; -function About({ version, isOpen, onClose }) { +function About({ version = null, isOpen = false, onClose }) { const { t } = useLingui(); const brandName = useBrandName(); @@ -76,9 +76,4 @@ About.propTypes = { version: PropTypes.string, }; -About.defaultProps = { - isOpen: false, - version: null, -}; - export default About; diff --git a/awx/ui/src/components/AddRole/AddResourceRole.js b/awx/ui/src/components/AddRole/AddResourceRole.js index a909280eb..3a297efc2 100644 --- a/awx/ui/src/components/AddRole/AddResourceRole.js +++ b/awx/ui/src/components/AddRole/AddResourceRole.js @@ -18,7 +18,13 @@ const readTeams = async (queryParams) => TeamsAPI.read(queryParams); const readTeamsOptions = async () => TeamsAPI.readOptions(); -function AddResourceRole({ onSave, onClose, roles, resource, onError }) { +function AddResourceRole({ + onSave, + onClose, + roles = {}, + resource = {}, + onError, +}) { const { t } = useLingui(); const userSearchColumns = useMemo(() => [ @@ -285,10 +291,5 @@ AddResourceRole.propTypes = { resource: PropTypes.shape(), }; -AddResourceRole.defaultProps = { - roles: {}, - resource: {}, -}; - export { AddResourceRole as _AddResourceRole }; export default AddResourceRole; diff --git a/awx/ui/src/components/AddRole/CheckboxCard.js b/awx/ui/src/components/AddRole/CheckboxCard.js index b055ee930..b4fd17aae 100644 --- a/awx/ui/src/components/AddRole/CheckboxCard.js +++ b/awx/ui/src/components/AddRole/CheckboxCard.js @@ -17,8 +17,13 @@ const Checkbox = styled(PFCheckbox)` } `; -function CheckboxCard(props) { - const { name, description, isSelected, onSelect, itemId } = props; +function CheckboxCard({ + name, + description = '', + isSelected = false, + onSelect = null, + itemId, +}) { return ( }`, }); function SelectResourceStep({ - searchColumns, - sortColumns, - displayKey, - onRowClick, - selectedLabel, - selectedResourceRows, + searchColumns = null, + sortColumns = null, + displayKey = 'name', + onRowClick = () => {}, + selectedLabel = null, + selectedResourceRows = [], fetchItems, fetchOptions, }) { @@ -150,14 +150,5 @@ SelectResourceStep.propTypes = { selectedResourceRows: PropTypes.arrayOf(PropTypes.object), }; -SelectResourceStep.defaultProps = { - searchColumns: null, - sortColumns: null, - displayKey: 'name', - onRowClick: () => {}, - selectedLabel: null, - selectedResourceRows: [], -}; - export { SelectResourceStep as _SelectResourceStep }; export default SelectResourceStep; diff --git a/awx/ui/src/components/AddRole/SelectRoleStep.js b/awx/ui/src/components/AddRole/SelectRoleStep.js index 96c4f8b8e..81b83559d 100644 --- a/awx/ui/src/components/AddRole/SelectRoleStep.js +++ b/awx/ui/src/components/AddRole/SelectRoleStep.js @@ -7,12 +7,12 @@ import CheckboxCard from './CheckboxCard'; import { SelectedList } from '../SelectedList'; function RolesStep({ - onRolesClick, + onRolesClick = () => {}, roles, - selectedListKey, - selectedListLabel, - selectedResourceRows, - selectedRoleRows, + selectedListKey = 'name', + selectedListLabel = null, + selectedResourceRows = [], + selectedRoleRows = [], }) { const { t } = useLingui(); @@ -65,12 +65,4 @@ RolesStep.propTypes = { selectedRoleRows: PropTypes.arrayOf(PropTypes.object), }; -RolesStep.defaultProps = { - onRolesClick: () => {}, - selectedListKey: 'name', - selectedListLabel: null, - selectedResourceRows: [], - selectedRoleRows: [], -}; - export default RolesStep; diff --git a/awx/ui/src/components/AnsibleSelect/AnsibleSelect.js b/awx/ui/src/components/AnsibleSelect/AnsibleSelect.js index 96281d80d..47e58abfc 100644 --- a/awx/ui/src/components/AnsibleSelect/AnsibleSelect.js +++ b/awx/ui/src/components/AnsibleSelect/AnsibleSelect.js @@ -14,12 +14,12 @@ import { FormSelect, FormSelectOption } from '@patternfly/react-core'; function AnsibleSelect({ id, - data, - isValid, - onBlur, + data = [], + isValid = true, + onBlur = () => {}, value, - className, - isDisabled, + className = '', + isDisabled = false, onChange, name, }) { @@ -62,14 +62,6 @@ const Option = shape({ isDisabled: bool, }); -AnsibleSelect.defaultProps = { - data: [], - isValid: true, - onBlur: () => {}, - className: '', - isDisabled: false, -}; - AnsibleSelect.propTypes = { data: arrayOf(Option), id: string.isRequired, diff --git a/awx/ui/src/components/AppContainer/PageHeaderToolbar.js b/awx/ui/src/components/AppContainer/PageHeaderToolbar.js index 6941400a3..132860a35 100644 --- a/awx/ui/src/components/AppContainer/PageHeaderToolbar.js +++ b/awx/ui/src/components/AppContainer/PageHeaderToolbar.js @@ -39,7 +39,7 @@ const UserName = styled.span` `; function PageHeaderToolbar({ - isAboutDisabled, + isAboutDisabled = false, onAboutClick, onLogoutClick, loggedInUser, @@ -239,8 +239,4 @@ PageHeaderToolbar.propTypes = { onLogoutClick: PropTypes.func.isRequired, }; -PageHeaderToolbar.defaultProps = { - isAboutDisabled: false, -}; - export default PageHeaderToolbar; diff --git a/awx/ui/src/components/CheckboxListItem/CheckboxListItem.js b/awx/ui/src/components/CheckboxListItem/CheckboxListItem.js index f26a1945f..506dcc5b6 100644 --- a/awx/ui/src/components/CheckboxListItem/CheckboxListItem.js +++ b/awx/ui/src/components/CheckboxListItem/CheckboxListItem.js @@ -79,7 +79,7 @@ const CheckboxListItem = ({ }; CheckboxListItem.propTypes = { - isSelected: PropTypes.bool.isRequired, + isSelected: PropTypes.bool, itemId: PropTypes.number.isRequired, label: PropTypes.string.isRequired, name: PropTypes.string.isRequired, diff --git a/awx/ui/src/components/CodeEditor/CodeEditor.js b/awx/ui/src/components/CodeEditor/CodeEditor.js index e7feaa699..54658c799 100644 --- a/awx/ui/src/components/CodeEditor/CodeEditor.js +++ b/awx/ui/src/components/CodeEditor/CodeEditor.js @@ -86,15 +86,15 @@ AceEditor.displayName = 'AceEditor'; function CodeEditor({ id, value, - onChange, + onChange = () => {}, onFocus, onBlur, mode, - readOnly, - hasErrors, - rows, - fullHeight, - className, + readOnly = false, + hasErrors = false, + rows = 6, + fullHeight = false, + className = '', }) { const { t } = useLingui(); if (rows && typeof rows !== 'number' && rows !== 'auto') { @@ -213,13 +213,4 @@ CodeEditor.propTypes = { rows: oneOfType([number, string]), className: string, }; -CodeEditor.defaultProps = { - readOnly: false, - onChange: () => {}, - rows: 6, - fullHeight: false, - hasErrors: false, - className: '', -}; - export default CodeEditor; diff --git a/awx/ui/src/components/CodeEditor/CodeEditorField.js b/awx/ui/src/components/CodeEditor/CodeEditorField.js index ee7f4d9cd..f2fec4404 100644 --- a/awx/ui/src/components/CodeEditor/CodeEditorField.js +++ b/awx/ui/src/components/CodeEditor/CodeEditorField.js @@ -18,11 +18,12 @@ function CodeEditorField({ id, name, label, - tooltip, - helperText, - validate, - isRequired, + tooltip = null, + helperText = '', + validate = () => {}, + isRequired = false, mode, + rows = 5, ...rest }) { const [field, meta, helpers] = useField({ name, validate }); @@ -47,6 +48,7 @@ function CodeEditorField({ helpers.setValue(value); }} mode={mode} + rows={rows} /> ); @@ -63,12 +65,4 @@ CodeEditorField.propTypes = { rows: number, }; -CodeEditorField.defaultProps = { - helperText: '', - validate: () => {}, - isRequired: false, - tooltip: null, - rows: 5, -}; - export default CodeEditorField; diff --git a/awx/ui/src/components/CodeEditor/VariablesDetail.js b/awx/ui/src/components/CodeEditor/VariablesDetail.js index 6d1df2748..7a2c82384 100644 --- a/awx/ui/src/components/CodeEditor/VariablesDetail.js +++ b/awx/ui/src/components/CodeEditor/VariablesDetail.js @@ -18,11 +18,11 @@ import CodeEditor from './CodeEditor'; import { JSON_MODE, YAML_MODE } from './constants'; function VariablesDetail({ - dataCy, - helpText, + dataCy = '', + helpText = '', value, label, - rows, + rows = null, fullHeight, name, }) { @@ -158,12 +158,6 @@ VariablesDetail.propTypes = { helpText: oneOfType([node, string]), name: string.isRequired, }; -VariablesDetail.defaultProps = { - rows: null, - dataCy: '', - helpText: '', -}; - function ModeToggle({ id, label, diff --git a/awx/ui/src/components/CodeEditor/VariablesField.js b/awx/ui/src/components/CodeEditor/VariablesField.js index b9889c8e5..21f5f2da8 100644 --- a/awx/ui/src/components/CodeEditor/VariablesField.js +++ b/awx/ui/src/components/CodeEditor/VariablesField.js @@ -29,17 +29,19 @@ const StyledCheckboxField = styled(CheckboxField)` margin-left: auto; `; +const defaultValidators = {}; + function VariablesField({ id, name, label, - readOnly, - promptId, + readOnly = false, + promptId = null, tooltip, - initialMode, - onModeChange, - isRequired, - validators, + initialMode = YAML_MODE, + onModeChange = () => {}, + isRequired = false, + validators = defaultValidators, }) { const { t } = useLingui(); // track focus manually, because the Code Editor library doesn't wire @@ -192,15 +194,6 @@ VariablesField.propTypes = { isRequired: bool, validators: shape({}), }; -VariablesField.defaultProps = { - readOnly: false, - promptId: null, - initialMode: YAML_MODE, - onModeChange: () => {}, - isRequired: false, - validators: {}, -}; - function VariablesFieldInternals({ id, name, diff --git a/awx/ui/src/components/ContentError/ContentError.js b/awx/ui/src/components/ContentError/ContentError.js index 5ebf0c938..6f19d2ccc 100644 --- a/awx/ui/src/components/ContentError/ContentError.js +++ b/awx/ui/src/components/ContentError/ContentError.js @@ -15,7 +15,7 @@ import { ExclamationTriangleIcon } from '@patternfly/react-icons'; import { useSession } from 'contexts/Session'; import ErrorDetail from '../ErrorDetail'; -function ContentError({ error, children, isNotFound }) { +function ContentError({ error = null, children, isNotFound = false }) { const { t } = useLingui(); const { logout } = useSession(); @@ -58,10 +58,5 @@ ContentError.propTypes = { error: instanceOf(Error), isNotFound: bool, }; -ContentError.defaultProps = { - error: null, - isNotFound: false, -}; - export { ContentError as _ContentError }; export default ContentError; diff --git a/awx/ui/src/components/CopyButton/CopyButton.js b/awx/ui/src/components/CopyButton/CopyButton.js index 599aec5bb..a5d2a03b5 100644 --- a/awx/ui/src/components/CopyButton/CopyButton.js +++ b/awx/ui/src/components/CopyButton/CopyButton.js @@ -10,11 +10,11 @@ import ErrorDetail from '../ErrorDetail'; function CopyButton({ id, copyItem, - isDisabled, + isDisabled = false, onCopyStart, onCopyFinish, errorMessage, - ouiaId, + ouiaId = null, }) { const { t } = useLingui(); const { @@ -69,9 +69,4 @@ CopyButton.propTypes = { ouiaId: PropTypes.string, }; -CopyButton.defaultProps = { - isDisabled: false, - ouiaId: null, -}; - export default CopyButton; diff --git a/awx/ui/src/components/DataListToolbar/DataListToolbar.js b/awx/ui/src/components/DataListToolbar/DataListToolbar.js index 0055b92c4..ffc1af1a8 100644 --- a/awx/ui/src/components/DataListToolbar/DataListToolbar.js +++ b/awx/ui/src/components/DataListToolbar/DataListToolbar.js @@ -35,29 +35,29 @@ const ToolbarContent = styled(PFToolbarContent)` function DataListToolbar({ isAllExpanded, onExpandAll, - itemCount, - clearAllFilters, + itemCount = 0, + clearAllFilters = null, searchColumns, - searchableKeys, - relatedSearchableKeys, - sortColumns, - isAllSelected, - onSelectAll, - isCompact, - onSort, - onSearch, - onReplaceSearch, + searchableKeys = [], + relatedSearchableKeys = [], + sortColumns = null, + isAllSelected = false, + onSelectAll = null, + isCompact = false, + onSort = null, + onSearch = null, + onReplaceSearch = null, onRemove, - onCompact, - onExpand, - additionalControls, + onCompact = null, + onExpand = null, + additionalControls = [], qsConfig, pagination, - enableNegativeFiltering, - enableRelatedFuzzyFiltering, + enableNegativeFiltering = true, + enableRelatedFuzzyFiltering = true, handleIsAnsibleFactsSelected, isFilterCleared, - advancedSearchDisabled, + advancedSearchDisabled = false, }) { const { t } = useLingui(); const showExpandCollapse = onCompact && onExpand; @@ -230,24 +230,4 @@ DataListToolbar.propTypes = { advancedSearchDisabled: PropTypes.bool, }; -DataListToolbar.defaultProps = { - itemCount: 0, - searchableKeys: [], - relatedSearchableKeys: [], - sortColumns: null, - clearAllFilters: null, - isAllSelected: false, - isCompact: false, - onCompact: null, - onExpand: null, - onSearch: null, - onReplaceSearch: null, - onSelectAll: null, - onSort: null, - additionalControls: [], - enableNegativeFiltering: true, - enableRelatedFuzzyFiltering: true, - advancedSearchDisabled: false, -}; - export default DataListToolbar; diff --git a/awx/ui/src/components/DeleteButton/DeleteButton.js b/awx/ui/src/components/DeleteButton/DeleteButton.js index c1bf06069..0b3610a51 100644 --- a/awx/ui/src/components/DeleteButton/DeleteButton.js +++ b/awx/ui/src/components/DeleteButton/DeleteButton.js @@ -24,7 +24,7 @@ function DeleteButton({ variant, children, isDisabled, - ouiaId, + ouiaId = null, deleteMessage, deleteDetailsRequests, disabledTooltip, @@ -155,8 +155,4 @@ DeleteButton.propTypes = { ouiaId: PropTypes.string, }; -DeleteButton.defaultProps = { - ouiaId: null, -}; - export default DeleteButton; diff --git a/awx/ui/src/components/DetailList/CodeDetail.js b/awx/ui/src/components/DetailList/CodeDetail.js index 9a6a27f3f..d1f66d369 100644 --- a/awx/ui/src/components/DetailList/CodeDetail.js +++ b/awx/ui/src/components/DetailList/CodeDetail.js @@ -13,7 +13,14 @@ import { DetailName, DetailValue } from './Detail'; import CodeEditor from '../CodeEditor'; import Popover from '../Popover'; -function CodeDetail({ value, label, mode, rows, helpText, dataCy }) { +function CodeDetail({ + value, + label, + mode, + rows = null, + helpText = '', + dataCy = '', +}) { const labelCy = dataCy ? `${dataCy}-label` : null; const valueCy = dataCy ? `${dataCy}-value` : null; const editorId = dataCy ? `${dataCy}-editor` : 'code-editor'; @@ -65,10 +72,4 @@ CodeDetail.propTypes = { rows: oneOfType([number, string]), mode: oneOf(['json', 'javascript', 'yaml', 'jinja2']).isRequired, }; -CodeDetail.defaultProps = { - rows: null, - helpText: '', - dataCy: '', -}; - export default CodeDetail; diff --git a/awx/ui/src/components/DetailList/Detail.js b/awx/ui/src/components/DetailList/Detail.js index bd89cfdd2..b7beeac7b 100644 --- a/awx/ui/src/components/DetailList/Detail.js +++ b/awx/ui/src/components/DetailList/Detail.js @@ -36,13 +36,13 @@ const DetailValue = styled( const Detail = ({ label, - value, - fullWidth, + value = null, + fullWidth = false, className, dataCy, - alwaysVisible, + alwaysVisible = false, isEmpty, - helpText, + helpText = null, isEncrypted, isNotConfigured, }) => { @@ -89,13 +89,6 @@ Detail.propTypes = { alwaysVisible: bool, helpText: oneOfType([string, node]), }; -Detail.defaultProps = { - value: null, - fullWidth: false, - alwaysVisible: false, - helpText: null, -}; - export default Detail; export { DetailName }; export { DetailValue }; diff --git a/awx/ui/src/components/DetailList/UserDateDetail.js b/awx/ui/src/components/DetailList/UserDateDetail.js index 2803983da..b0e54eee3 100644 --- a/awx/ui/src/components/DetailList/UserDateDetail.js +++ b/awx/ui/src/components/DetailList/UserDateDetail.js @@ -11,7 +11,7 @@ const Detail = styled(_Detail)` word-break: break-word; `; -function UserDateDetail({ label, date, user }) { +function UserDateDetail({ label, date, user = null }) { const dateStr = formatDateString(date); const username = user ? user.username : ''; return ( @@ -35,8 +35,4 @@ UserDateDetail.propTypes = { date: string.isRequired, user: SummaryFieldUser, }; -UserDateDetail.defaultProps = { - user: null, -}; - export default UserDateDetail; diff --git a/awx/ui/src/components/DisassociateButton/DisassociateButton.js b/awx/ui/src/components/DisassociateButton/DisassociateButton.js index f18fbe8c6..df4a2e85d 100644 --- a/awx/ui/src/components/DisassociateButton/DisassociateButton.js +++ b/awx/ui/src/components/DisassociateButton/DisassociateButton.js @@ -167,12 +167,6 @@ function DisassociateButton({ ); } -DisassociateButton.defaultProps = { - itemsToDisassociate: [], - modalNote: '', - modalTitle: '', -}; - DisassociateButton.propTypes = { itemsToDisassociate: oneOfType([ arrayOf( diff --git a/awx/ui/src/components/ErrorDetail/ErrorDetail.js b/awx/ui/src/components/ErrorDetail/ErrorDetail.js index ea4b689f8..3dae8b2bf 100644 --- a/awx/ui/src/components/ErrorDetail/ErrorDetail.js +++ b/awx/ui/src/components/ErrorDetail/ErrorDetail.js @@ -33,7 +33,7 @@ const Expandable = styled(PFExpandable)` } `; -function ErrorDetail({ error }) { +function ErrorDetail({ error = null }) { const { t } = useLingui(); const { response } = error; const [isExpanded, setIsExpanded] = useState(false); @@ -101,8 +101,4 @@ function ErrorDetail({ error }) { ErrorDetail.propTypes = { error: PropTypes.instanceOf(Error), }; -ErrorDetail.defaultProps = { - error: null, -}; - export default ErrorDetail; diff --git a/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.js b/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.js index e13a3572d..5af2c8f4d 100644 --- a/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.js +++ b/awx/ui/src/components/ExecutionEnvironmentDetail/ExecutionEnvironmentDetail.js @@ -26,12 +26,12 @@ const ExclamationTrianglePopover = styled(PFExclamationTriangleIcon)` ExclamationTrianglePopover.displayName = 'ExclamationTrianglePopover'; function ExecutionEnvironmentDetail({ - executionEnvironment, - isDefaultEnvironment, - virtualEnvironment, - verifyMissingVirtualEnv, - helpText, - dataCy, + executionEnvironment = null, + isDefaultEnvironment = false, + virtualEnvironment = '', + verifyMissingVirtualEnv = true, + helpText = '', + dataCy = 'execution-environment-detail', }) { const { t } = useLingui(); const config = useConfig(); @@ -137,13 +137,4 @@ ExecutionEnvironmentDetail.propTypes = { dataCy: string, }; -ExecutionEnvironmentDetail.defaultProps = { - isDefaultEnvironment: false, - executionEnvironment: null, - virtualEnvironment: '', - verifyMissingVirtualEnv: true, - helpText: '', - dataCy: 'execution-environment-detail', -}; - export default ExecutionEnvironmentDetail; diff --git a/awx/ui/src/components/ExpandCollapse/ExpandCollapse.js b/awx/ui/src/components/ExpandCollapse/ExpandCollapse.js index 6d0679b2b..fdf78c3e5 100644 --- a/awx/ui/src/components/ExpandCollapse/ExpandCollapse.js +++ b/awx/ui/src/components/ExpandCollapse/ExpandCollapse.js @@ -31,7 +31,7 @@ const ToolbarItem = styled(PFToolbarItem)` // TODO: Recommend renaming this component to avoid confusion // with ExpandingContainer -function ExpandCollapse({ isCompact, onCompact, onExpand }) { +function ExpandCollapse({ isCompact = true, onCompact, onExpand }) { const { t } = useLingui(); return ( <> @@ -67,8 +67,4 @@ ExpandCollapse.propTypes = { isCompact: PropTypes.bool, }; -ExpandCollapse.defaultProps = { - isCompact: true, -}; - export default ExpandCollapse; diff --git a/awx/ui/src/components/FieldWithPrompt/FieldWithPrompt.js b/awx/ui/src/components/FieldWithPrompt/FieldWithPrompt.js index 3c8c5c1f8..baffc6913 100644 --- a/awx/ui/src/components/FieldWithPrompt/FieldWithPrompt.js +++ b/awx/ui/src/components/FieldWithPrompt/FieldWithPrompt.js @@ -19,11 +19,11 @@ const StyledCheckboxField = styled(CheckboxField)` function FieldWithPrompt({ children, fieldId, - isRequired, + isRequired = false, label, promptId, promptName, - tooltip, + tooltip = null, isDisabled, }) { const { t } = useLingui(); @@ -63,9 +63,4 @@ FieldWithPrompt.propTypes = { tooltip: node, }; -FieldWithPrompt.defaultProps = { - isRequired: false, - tooltip: null, -}; - export default FieldWithPrompt; diff --git a/awx/ui/src/components/FormActionGroup/FormActionGroup.js b/awx/ui/src/components/FormActionGroup/FormActionGroup.js index 3b1d247d4..4cfd0e8d6 100644 --- a/awx/ui/src/components/FormActionGroup/FormActionGroup.js +++ b/awx/ui/src/components/FormActionGroup/FormActionGroup.js @@ -5,7 +5,7 @@ import { useLingui } from '@lingui/react/macro'; import { ActionGroup, Button } from '@patternfly/react-core'; import { FormFullWidthLayout } from '../FormLayout'; -const FormActionGroup = ({ onCancel, onSubmit, submitDisabled }) => { +const FormActionGroup = ({ onCancel, onSubmit, submitDisabled = false }) => { const { t } = useLingui(); return ( @@ -41,8 +41,4 @@ FormActionGroup.propTypes = { submitDisabled: PropTypes.bool, }; -FormActionGroup.defaultProps = { - submitDisabled: false, -}; - export default FormActionGroup; diff --git a/awx/ui/src/components/FormField/ArrayTextField.js b/awx/ui/src/components/FormField/ArrayTextField.js index f96505682..00ad86ca6 100644 --- a/awx/ui/src/components/FormField/ArrayTextField.js +++ b/awx/ui/src/components/FormField/ArrayTextField.js @@ -4,20 +4,18 @@ import { useField } from 'formik'; import { FormGroup, TextArea } from '@patternfly/react-core'; import Popover from '../Popover'; -function ArrayTextField(props) { - const { - id, - helperText, - name, - label, - tooltip, - tooltipMaxWidth, - validate, - isRequired, - type, - ...rest - } = props; - +function ArrayTextField({ + id, + helperText = '', + name, + label, + tooltip = null, + tooltipMaxWidth = '', + validate = () => {}, + isRequired = false, + type, + ...rest +}) { const [field, meta, helpers] = useField({ name, validate }); const isValid = !(meta.touched && meta.error); const value = field.value || []; @@ -63,12 +61,4 @@ ArrayTextField.propTypes = { tooltipMaxWidth: PropTypes.string, }; -ArrayTextField.defaultProps = { - helperText: '', - validate: () => {}, - isRequired: false, - tooltip: null, - tooltipMaxWidth: '', -}; - export default ArrayTextField; diff --git a/awx/ui/src/components/FormField/CheckboxField.js b/awx/ui/src/components/FormField/CheckboxField.js index daa8677ca..abe2f5333 100644 --- a/awx/ui/src/components/FormField/CheckboxField.js +++ b/awx/ui/src/components/FormField/CheckboxField.js @@ -8,8 +8,8 @@ function CheckboxField({ id, name, label, - tooltip, - validate, + tooltip = '', + validate = () => {}, isDisabled, ...rest }) { @@ -43,9 +43,4 @@ CheckboxField.propTypes = { validate: func, tooltip: node, }; -CheckboxField.defaultProps = { - validate: () => {}, - tooltip: '', -}; - export default CheckboxField; diff --git a/awx/ui/src/components/FormField/FormField.js b/awx/ui/src/components/FormField/FormField.js index 20a3dfec1..af0468f62 100644 --- a/awx/ui/src/components/FormField/FormField.js +++ b/awx/ui/src/components/FormField/FormField.js @@ -5,20 +5,18 @@ import { useField } from 'formik'; import { FormGroup, TextInput, TextArea } from '@patternfly/react-core'; import Popover from '../Popover'; -function FormField(props) { - const { - id, - helperText, - name, - label, - tooltip, - tooltipMaxWidth, - validate, - isRequired, - type, - ...rest - } = props; - +function FormField({ + id, + helperText = '', + name, + label, + tooltip = null, + tooltipMaxWidth = '', + validate = () => {}, + isRequired = false, + type = 'text', + ...rest +}) { const [field, meta] = useField({ name, validate }); const isValid = !(meta.touched && meta.error); @@ -87,13 +85,4 @@ FormField.propTypes = { tooltipMaxWidth: PropTypes.string, }; -FormField.defaultProps = { - helperText: '', - type: 'text', - validate: () => {}, - isRequired: false, - tooltip: null, - tooltipMaxWidth: '', -}; - export default FormField; diff --git a/awx/ui/src/components/FormField/PasswordField.js b/awx/ui/src/components/FormField/PasswordField.js index 44ebe5f88..2133e8ab9 100644 --- a/awx/ui/src/components/FormField/PasswordField.js +++ b/awx/ui/src/components/FormField/PasswordField.js @@ -5,8 +5,15 @@ import { FormGroup, InputGroup } from '@patternfly/react-core'; import Popover from '../Popover'; import PasswordInput from './PasswordInput'; -function PasswordField(props) { - const { id, name, label, validate, isRequired, helperText } = props; +function PasswordField({ + id, + name, + label, + validate = () => {}, + isRequired = false, + helperText, + ...rest +}) { const [, meta] = useField({ name, validate }); const isValid = !(meta.touched && meta.error); @@ -20,7 +27,15 @@ function PasswordField(props) { labelIcon={helperText && } > - + ); @@ -35,10 +50,4 @@ PasswordField.propTypes = { isDisabled: PropTypes.bool, }; -PasswordField.defaultProps = { - validate: () => {}, - isRequired: false, - isDisabled: false, -}; - export default PasswordField; diff --git a/awx/ui/src/components/FormField/PasswordInput.js b/awx/ui/src/components/FormField/PasswordInput.js index 9ed652983..dd7bcb92e 100644 --- a/awx/ui/src/components/FormField/PasswordInput.js +++ b/awx/ui/src/components/FormField/PasswordInput.js @@ -11,17 +11,16 @@ import { } from '@patternfly/react-core'; import { EyeIcon, EyeSlashIcon } from '@patternfly/react-icons'; -function PasswordInput(props) { +function PasswordInput({ + autocomplete = 'new-password', + id, + name, + validate = () => {}, + isFieldGroupValid, + isRequired = false, + isDisabled = false, +}) { const { t } = useLingui(); - const { - autocomplete, - id, - name, - validate, - isFieldGroupValid, - isRequired, - isDisabled, - } = props; const [inputType, setInputType] = useState('password'); const [field, meta] = useField({ name, validate }); @@ -76,11 +75,4 @@ PasswordInput.propTypes = { isDisabled: PropTypes.bool, }; -PasswordInput.defaultProps = { - autocomplete: 'new-password', - validate: () => {}, - isRequired: false, - isDisabled: false, -}; - export default PasswordInput; diff --git a/awx/ui/src/components/HostForm/HostForm.js b/awx/ui/src/components/HostForm/HostForm.js index a8d1d6b5c..b2f5e19e2 100644 --- a/awx/ui/src/components/HostForm/HostForm.js +++ b/awx/ui/src/components/HostForm/HostForm.js @@ -73,10 +73,18 @@ const InventoryLookupField = ({ isDisabled }) => { const HostForm = ({ handleCancel, handleSubmit, - host, - isInventoryVisible, - submitError, - disableInventoryLookup, + host = { + name: '', + description: '', + inventory: undefined, + variables: '---\n', + summary_fields: { + inventory: null, + }, + }, + isInventoryVisible = true, + submitError = null, + disableInventoryLookup = false, }) => { const { t } = useLingui(); return ( @@ -137,20 +145,5 @@ HostForm.propTypes = { disableInventoryLookup: bool, }; -HostForm.defaultProps = { - host: { - name: '', - description: '', - inventory: undefined, - variables: '---\n', - summary_fields: { - inventory: null, - }, - }, - isInventoryVisible: true, - submitError: null, - disableInventoryLookup: false, -}; - export { HostForm as _HostForm }; export default HostForm; diff --git a/awx/ui/src/components/InstanceGroupLabels/InstanceGroupLabels.js b/awx/ui/src/components/InstanceGroupLabels/InstanceGroupLabels.js index e3d89f928..f6fe77fda 100644 --- a/awx/ui/src/components/InstanceGroupLabels/InstanceGroupLabels.js +++ b/awx/ui/src/components/InstanceGroupLabels/InstanceGroupLabels.js @@ -4,7 +4,7 @@ import { arrayOf, bool, number, shape, string } from 'prop-types'; import { Label, LabelGroup } from '@patternfly/react-core'; import { Link } from 'react-router-dom'; -function InstanceGroupLabels({ labels, isLinkable }) { +function InstanceGroupLabels({ labels, isLinkable = false }) { const buildLinkURL = (isContainerGroup) => isContainerGroup ? '/instance_groups/container_group/' @@ -44,6 +44,4 @@ InstanceGroupLabels.propTypes = { isLinkable: bool, }; -InstanceGroupLabels.defaultProps = { isLinkable: false }; - export default InstanceGroupLabels; diff --git a/awx/ui/src/components/JobList/JobListCancelButton.js b/awx/ui/src/components/JobList/JobListCancelButton.js index 646bcd330..75df44113 100644 --- a/awx/ui/src/components/JobList/JobListCancelButton.js +++ b/awx/ui/src/components/JobList/JobListCancelButton.js @@ -17,7 +17,7 @@ function cannotCancelBecauseNotRunning(job) { return !isJobRunning(job.status); } -function JobListCancelButton({ jobsToCancel, onCancel }) { +function JobListCancelButton({ jobsToCancel = [], onCancel = () => {} }) { const { t } = useLingui(); const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext); const [isModalOpen, setIsModalOpen] = useState(false); @@ -188,9 +188,4 @@ JobListCancelButton.propTypes = { onCancel: func, }; -JobListCancelButton.defaultProps = { - jobsToCancel: [], - onCancel: () => {}, -}; - export default JobListCancelButton; diff --git a/awx/ui/src/components/LabelSelect/LabelSelect.js b/awx/ui/src/components/LabelSelect/LabelSelect.js index 3d1cb8a75..016e56126 100644 --- a/awx/ui/src/components/LabelSelect/LabelSelect.js +++ b/awx/ui/src/components/LabelSelect/LabelSelect.js @@ -40,7 +40,13 @@ async function loadLabelOptions(setLabels, onError, isMounted) { } } -function LabelSelect({ value, placeholder, onChange, onError, createText }) { +function LabelSelect({ + value, + placeholder = '', + onChange, + onError, + createText, +}) { const [isLoading, setIsLoading] = useState(true); const [isExpanded, setIsExpanded] = useState(false); const isMounted = useIsMounted(); @@ -147,8 +153,4 @@ LabelSelect.propTypes = { onChange: func.isRequired, onError: func.isRequired, }; -LabelSelect.defaultProps = { - placeholder: '', -}; - export default LabelSelect; diff --git a/awx/ui/src/components/ListHeader/ListHeader.js b/awx/ui/src/components/ListHeader/ListHeader.js index e9aff4f03..9ae5a2fd1 100644 --- a/awx/ui/src/components/ListHeader/ListHeader.js +++ b/awx/ui/src/components/ListHeader/ListHeader.js @@ -26,21 +26,20 @@ const EmptyStateControlsWrapper = styled.div` margin-left: 20px; } `; -function ListHeader(props) { +function ListHeader({ + emptyStateControls, + itemCount, + pagination, + qsConfig, + relatedSearchableKeys = [], + renderToolbar = (toolbarProps) => , + searchColumns, + searchableKeys = [], + sortColumns = null, +}) { const { search, pathname } = useLocation(); const [isFilterCleared, setIsFilterCleared] = useState(false); const navigate = useNavigate(); - const { - emptyStateControls, - itemCount, - pagination, - qsConfig, - relatedSearchableKeys, - renderToolbar, - searchColumns, - searchableKeys, - sortColumns, - } = props; const handleSearch = (key, value) => { const params = parseQueryString(qsConfig, search); @@ -141,11 +140,4 @@ ListHeader.propTypes = { renderToolbar: PropTypes.func, }; -ListHeader.defaultProps = { - renderToolbar: (props) => , - searchableKeys: [], - sortColumns: null, - relatedSearchableKeys: [], -}; - export default ListHeader; diff --git a/awx/ui/src/components/Lookup/ApplicationLookup.js b/awx/ui/src/components/Lookup/ApplicationLookup.js index 4309c59bf..3a14fde85 100644 --- a/awx/ui/src/components/Lookup/ApplicationLookup.js +++ b/awx/ui/src/components/Lookup/ApplicationLookup.js @@ -18,7 +18,13 @@ const QS_CONFIG = getQSConfig('applications', { order_by: 'name', }); -function ApplicationLookup({ onChange, value, label, fieldName, validate }) { +function ApplicationLookup({ + onChange, + value = null, + label, + fieldName = 'application', + validate = () => undefined, +}) { const { t } = useLingui(); const location = useLocation(); const { @@ -146,10 +152,4 @@ ApplicationLookup.propTypes = { fieldName: string, }; -ApplicationLookup.defaultProps = { - value: null, - validate: () => undefined, - fieldName: 'application', -}; - export default ApplicationLookup; diff --git a/awx/ui/src/components/Lookup/CredentialLookup.js b/awx/ui/src/components/Lookup/CredentialLookup.js index cf2b3b68c..8b6960cfa 100644 --- a/awx/ui/src/components/Lookup/CredentialLookup.js +++ b/awx/ui/src/components/Lookup/CredentialLookup.js @@ -30,24 +30,24 @@ const QS_CONFIG = getQSConfig('credentials', { }); function CredentialLookup({ - autoPopulate, - credentialTypeId, - credentialTypeKind, + autoPopulate = false, + credentialTypeId = '', + credentialTypeKind = '', credentialTypeNamespace, - fieldName, - helperTextInvalid, - isDisabled, + fieldName = 'credential', + helperTextInvalid = '', + isDisabled = false, isSelectedDraggable, - isValid, + isValid = true, label, modalDescription, - multiple, - onBlur, + multiple = false, + onBlur = () => {}, onChange, - required, + required = false, tooltip, - validate, - value, + validate = () => undefined, + value = null, }) { const { t } = useLingui(); const location = useLocation(); @@ -233,16 +233,17 @@ function CredentialLookup({ function idOrKind(props, propName, componentName) { let error; + // credentialTypeKind formerly defaulted to '' via defaultProps, which React + // applied to the element's props BEFORE running PropTypes — so this validator + // always saw a present empty string and never fired (callers may pass + // credentialTypeNamespace instead of id/kind). Default params don't reach + // PropTypes, so treat an omitted/undefined value as that former '' default to + // preserve behavior. + const kindValue = + props.credentialTypeKind === undefined ? '' : props.credentialTypeKind; if ( !Object.prototype.hasOwnProperty.call(props, 'credentialTypeId') && - !Object.prototype.hasOwnProperty.call(props, 'credentialTypeKind') - ) - error = new Error( - `Either "credentialTypeId" or "credentialTypeKind" is required` - ); - if ( - !Object.prototype.hasOwnProperty.call(props, 'credentialTypeId') && - typeof props[propName] !== 'string' + typeof kindValue !== 'string' ) { error = new Error( `Invalid prop '${propName}' '${props[propName]}' supplied to '${componentName}'.` @@ -268,20 +269,5 @@ CredentialLookup.propTypes = { fieldName: string, }; -CredentialLookup.defaultProps = { - credentialTypeId: '', - credentialTypeKind: '', - helperTextInvalid: '', - isValid: true, - multiple: false, - onBlur: () => {}, - required: false, - value: null, - isDisabled: false, - autoPopulate: false, - validate: () => undefined, - fieldName: 'credential', -}; - export { CredentialLookup as _CredentialLookup }; export default CredentialLookup; diff --git a/awx/ui/src/components/Lookup/CredentialLookup.test.js b/awx/ui/src/components/Lookup/CredentialLookup.test.js index d3a59bcc0..20d4c7a3a 100644 --- a/awx/ui/src/components/Lookup/CredentialLookup.test.js +++ b/awx/ui/src/components/Lookup/CredentialLookup.test.js @@ -74,11 +74,6 @@ describe('CredentialLookup', () => { expect(await screen.findByText('Foo')).toBeInTheDocument(); }); - test('should define default value for function props', () => { - expect(_CredentialLookup.defaultProps.onBlur).toBeInstanceOf(Function); - expect(_CredentialLookup.defaultProps.onBlur).not.toThrow(); - }); - test('should not auto-select credential when autoPopulate prop is false', async () => { CredentialsAPI.read.mockResolvedValue({ data: { diff --git a/awx/ui/src/components/Lookup/ExecutionEnvironmentLookup.js b/awx/ui/src/components/Lookup/ExecutionEnvironmentLookup.js index ec84d19be..5bdf399ab 100644 --- a/awx/ui/src/components/Lookup/ExecutionEnvironmentLookup.js +++ b/awx/ui/src/components/Lookup/ExecutionEnvironmentLookup.js @@ -21,21 +21,21 @@ const QS_CONFIG = getQSConfig('execution_environments', { }); function ExecutionEnvironmentLookup({ - id, + id = 'execution-environments', globallyAvailable, helperTextInvalid, isDisabled, isValid, onBlur, onChange, - organizationId, - popoverContent, - projectId, + organizationId = null, + popoverContent = '', + projectId = null, tooltip, - validate, - value, - fieldName, - overrideLabel, + validate = () => undefined, + value = null, + fieldName = 'execution_environment', + overrideLabel = false, isPromptableField, promptId, promptName, @@ -254,15 +254,4 @@ ExecutionEnvironmentLookup.propTypes = { overrideLabel: bool, }; -ExecutionEnvironmentLookup.defaultProps = { - id: 'execution-environments', - popoverContent: '', - value: null, - projectId: null, - organizationId: null, - validate: () => undefined, - fieldName: 'execution_environment', - overrideLabel: false, -}; - export default ExecutionEnvironmentLookup; diff --git a/awx/ui/src/components/Lookup/HostFilterLookup.js b/awx/ui/src/components/Lookup/HostFilterLookup.js index 56fc66f27..72a2bf5c8 100644 --- a/awx/ui/src/components/Lookup/HostFilterLookup.js +++ b/awx/ui/src/components/Lookup/HostFilterLookup.js @@ -92,14 +92,14 @@ const QS_CONFIG = getQSConfig( function HostFilterLookup({ helperTextInvalid, - isValid, + isValid = true, isDisabled, - onBlur, - onChange, - organizationId, - value, - enableNegativeFiltering, - enableRelatedFuzzyFiltering, + onBlur = () => {}, + onChange = () => {}, + organizationId = null, + value = '', + enableNegativeFiltering = true, + enableRelatedFuzzyFiltering = true, }) { const { t } = useLingui(); const navigate = useNavigate(); @@ -465,14 +465,4 @@ HostFilterLookup.propTypes = { enableNegativeFiltering: bool, enableRelatedFuzzyFiltering: bool, }; -HostFilterLookup.defaultProps = { - isValid: true, - onBlur: () => {}, - onChange: () => {}, - organizationId: null, - value: '', - enableNegativeFiltering: true, - enableRelatedFuzzyFiltering: true, -}; - export default HostFilterLookup; diff --git a/awx/ui/src/components/Lookup/InstanceGroupsLookup.js b/awx/ui/src/components/Lookup/InstanceGroupsLookup.js index c5e63fe8d..3bacb1303 100644 --- a/awx/ui/src/components/Lookup/InstanceGroupsLookup.js +++ b/awx/ui/src/components/Lookup/InstanceGroupsLookup.js @@ -21,14 +21,14 @@ const QS_CONFIG = getQSConfig('instance-groups', { }); function InstanceGroupsLookup({ - id, + id = 'org-instance-groups', value, onChange, - tooltip, - className, - required, - fieldName, - validate, + tooltip = '', + className = '', + required = false, + fieldName = 'instance_groups', + validate = () => undefined, isPromptableField, promptId, promptName, @@ -169,13 +169,4 @@ InstanceGroupsLookup.propTypes = { fieldName: string, }; -InstanceGroupsLookup.defaultProps = { - id: 'org-instance-groups', - tooltip: '', - className: '', - required: false, - validate: () => undefined, - fieldName: 'instance_groups', -}; - export default InstanceGroupsLookup; diff --git a/awx/ui/src/components/Lookup/InventoryLookup.js b/awx/ui/src/components/Lookup/InventoryLookup.js index 395727f9a..b68f468ee 100644 --- a/awx/ui/src/components/Lookup/InventoryLookup.js +++ b/awx/ui/src/components/Lookup/InventoryLookup.js @@ -20,20 +20,20 @@ const QS_CONFIG = getQSConfig('inventory', { }); function InventoryLookup({ - autoPopulate, - excludeIds, - fieldId, - fieldName, - hideAdvancedInventories, - isDisabled, + autoPopulate = false, + excludeIds = [], + fieldId = 'inventory', + fieldName = 'inventory', + hideAdvancedInventories = false, + isDisabled = false, isPromptableField, onBlur, onChange, promptId, promptName, - required, - validate, - value, + required = false, + validate = () => {}, + value = null, multiple, }) { const location = useLocation(); @@ -265,16 +265,4 @@ InventoryLookup.propTypes = { value: oneOfType([Inventory, arrayOf(Inventory)]), }; -InventoryLookup.defaultProps = { - autoPopulate: false, - excludeIds: [], - fieldId: 'inventory', - fieldName: 'inventory', - hideAdvancedInventories: false, - isDisabled: false, - required: false, - validate: () => {}, - value: null, -}; - export default InventoryLookup; diff --git a/awx/ui/src/components/Lookup/Lookup.js b/awx/ui/src/components/Lookup/Lookup.js index beb47cdb1..bf64007e9 100644 --- a/awx/ui/src/components/Lookup/Lookup.js +++ b/awx/ui/src/components/Lookup/Lookup.js @@ -33,26 +33,29 @@ const ChipHolder = styled.div` background-color: ${(props) => props.$isDisabled ? 'var(--pf-global--disabled-color--300)' : null}; `; -function Lookup(props) { - const { - id, - header, - onChange, - onBlur, - isLoading, - value, - multiple, - required, - qsConfig, - renderItemChip, - renderOptionsList, - isDisabled, - onDebounce, - fieldName, - validate, - modalDescription, - onUpdate, - } = props; +function Lookup({ + id = 'lookup-search', + header = null, + onChange, + onBlur = () => {}, + isLoading, + value = null, + multiple = false, + required = false, + qsConfig, + renderItemChip = ({ item, removeItem, canDelete }) => ( + removeItem(item)} isReadOnly={!canDelete}> + {item.name} + + ), + renderOptionsList, + isDisabled = false, + onDebounce = () => undefined, + fieldName, + validate = () => undefined, + modalDescription = '', + onUpdate = () => {}, +}) { const { t } = useLingui(); const location = useLocation(); const navigate = useNavigate(); @@ -255,28 +258,5 @@ Lookup.propTypes = { isDisabled: bool, }; -Lookup.defaultProps = { - id: 'lookup-search', - header: null, - value: null, - multiple: false, - required: false, - modalDescription: '', - onBlur: () => {}, - renderItemChip: ({ item, removeItem, canDelete }) => ( - removeItem(item)} - isReadOnly={!canDelete} - > - {item.name} - - ), - validate: () => undefined, - onDebounce: () => undefined, - onUpdate: () => {}, - isDisabled: false, -}; - export { Lookup as _Lookup }; export default Lookup; diff --git a/awx/ui/src/components/Lookup/MultiCredentialsLookup.js b/awx/ui/src/components/Lookup/MultiCredentialsLookup.js index 3253800d7..614ea2679 100644 --- a/awx/ui/src/components/Lookup/MultiCredentialsLookup.js +++ b/awx/ui/src/components/Lookup/MultiCredentialsLookup.js @@ -26,11 +26,11 @@ async function loadCredentials(params, selectedCredentialTypeId) { } function MultiCredentialsLookup({ - value, + value = [], onChange, onError, - fieldName, - validate, + fieldName = 'credentials', + validate = () => undefined, }) { const location = useLocation(); const navigate = useNavigate(); @@ -260,11 +260,5 @@ MultiCredentialsLookup.propTypes = { fieldName: PropTypes.string, }; -MultiCredentialsLookup.defaultProps = { - value: [], - validate: () => undefined, - fieldName: 'credentials', -}; - export { MultiCredentialsLookup as _MultiCredentialsLookup }; export default MultiCredentialsLookup; diff --git a/awx/ui/src/components/Lookup/OrganizationLookup.js b/awx/ui/src/components/Lookup/OrganizationLookup.js index af8ff8c25..40b5ff660 100644 --- a/awx/ui/src/components/Lookup/OrganizationLookup.js +++ b/awx/ui/src/components/Lookup/OrganizationLookup.js @@ -20,18 +20,18 @@ const QS_CONFIG = getQSConfig('organizations', { }); function OrganizationLookup({ - id, - helperTextInvalid, - isValid, - onBlur, + id = 'organization', + helperTextInvalid = '', + isValid = true, + onBlur = () => {}, onChange, - required, - value, - autoPopulate, - isDisabled, + required = false, + value = null, + autoPopulate = false, + isDisabled = false, helperText, - validate, - fieldName, + validate = () => undefined, + fieldName = 'organization', }) { const location = useLocation(); const { t } = useLingui(); @@ -173,18 +173,5 @@ OrganizationLookup.propTypes = { fieldName: string, }; -OrganizationLookup.defaultProps = { - id: 'organization', - helperTextInvalid: '', - isValid: true, - onBlur: () => {}, - required: false, - value: null, - autoPopulate: false, - isDisabled: false, - validate: () => undefined, - fieldName: 'organization', -}; - export { OrganizationLookup as _OrganizationLookup }; export default OrganizationLookup; diff --git a/awx/ui/src/components/Lookup/OrganizationLookup.test.js b/awx/ui/src/components/Lookup/OrganizationLookup.test.js index 633ffeb94..757d48141 100644 --- a/awx/ui/src/components/Lookup/OrganizationLookup.test.js +++ b/awx/ui/src/components/Lookup/OrganizationLookup.test.js @@ -58,11 +58,6 @@ describe('OrganizationLookup', () => { expect(await screen.findByText('Organization')).toBeInTheDocument(); }); - test('should define default value for function props', () => { - expect(_OrganizationLookup.defaultProps.onBlur).toBeInstanceOf(Function); - expect(_OrganizationLookup.defaultProps.onBlur).not.toThrow(); - }); - test('should auto-select organization when only one available and autoPopulate prop is true', async () => { const org = { id: 1, name: 'org', url: '/api/v2/organizations/1/' }; OrganizationsAPI.read.mockResolvedValue({ diff --git a/awx/ui/src/components/Lookup/PeersLookup.js b/awx/ui/src/components/Lookup/PeersLookup.js index 0bf46a8e5..481283509 100755 --- a/awx/ui/src/components/Lookup/PeersLookup.js +++ b/awx/ui/src/components/Lookup/PeersLookup.js @@ -20,23 +20,25 @@ const QS_CONFIG = getQSConfig('instances', { order_by: 'hostname', }); +const defaultInstanceDetails = {}; + function PeersLookup({ - id, + id = 'instances', value, onChange, - tooltip, - className, - required, - fieldName, - multiple, - validate, - columns, + tooltip = '', + className = '', + required = false, + fieldName = 'instances', + multiple = true, + validate = () => undefined, + columns = undefined, isPromptableField, promptId, promptName, - formLabel, - typePeers, - instance_details, + formLabel = undefined, + typePeers = false, + instance_details = defaultInstanceDetails, }) { const location = useLocation(); const { t } = useLingui(); @@ -187,18 +189,4 @@ PeersLookup.propTypes = { typePeers: bool, }; -PeersLookup.defaultProps = { - id: 'instances', - tooltip: '', - className: '', - required: false, - validate: () => undefined, - fieldName: 'instances', - columns: undefined, - formLabel: undefined, - instance_details: {}, - multiple: true, - typePeers: false, -}; - export default PeersLookup; diff --git a/awx/ui/src/components/Lookup/ProjectLookup.js b/awx/ui/src/components/Lookup/ProjectLookup.js index 26492e282..0decf071e 100644 --- a/awx/ui/src/components/Lookup/ProjectLookup.js +++ b/awx/ui/src/components/Lookup/ProjectLookup.js @@ -22,17 +22,17 @@ const QS_CONFIG = getQSConfig('project', { }); function ProjectLookup({ - helperTextInvalid, - autoPopulate, - isValid, + helperTextInvalid = '', + autoPopulate = false, + isValid = true, onChange, - required, - tooltip, - value, - onBlur, - isOverrideDisabled, - validate, - fieldName, + required = false, + tooltip = '', + value = null, + onBlur = () => {}, + isOverrideDisabled = false, + validate = () => undefined, + fieldName = 'project', }) { const location = useLocation(); const { t } = useLingui(); @@ -192,18 +192,5 @@ ProjectLookup.propTypes = { fieldName: string, }; -ProjectLookup.defaultProps = { - autoPopulate: false, - helperTextInvalid: '', - isValid: true, - onBlur: () => {}, - required: false, - tooltip: '', - value: null, - isOverrideDisabled: false, - validate: () => undefined, - fieldName: 'project', -}; - export { ProjectLookup as _ProjectLookup }; export default ProjectLookup; diff --git a/awx/ui/src/components/NotificationList/NotificationList.js b/awx/ui/src/components/NotificationList/NotificationList.js index e0617c877..9996e2a73 100644 --- a/awx/ui/src/components/NotificationList/NotificationList.js +++ b/awx/ui/src/components/NotificationList/NotificationList.js @@ -26,7 +26,7 @@ function NotificationList({ canToggleNotifications, id, - showApprovalsToggle, + showApprovalsToggle = false, }) { const { t } = useLingui(); const location = useLocation(); @@ -265,8 +265,4 @@ NotificationList.propTypes = { showApprovalsToggle: bool, }; -NotificationList.defaultProps = { - showApprovalsToggle: false, -}; - export default NotificationList; diff --git a/awx/ui/src/components/NotificationList/NotificationListItem.js b/awx/ui/src/components/NotificationList/NotificationListItem.js index 37c04e9ef..7a9d53bb0 100644 --- a/awx/ui/src/components/NotificationList/NotificationListItem.js +++ b/awx/ui/src/components/NotificationList/NotificationListItem.js @@ -12,14 +12,14 @@ function NotificationListItem({ canToggleNotifications, notification, detailUrl, - approvalsTurnedOn, - startedTurnedOn, - successTurnedOn, - errorTurnedOn, + approvalsTurnedOn = false, + startedTurnedOn = false, + successTurnedOn = false, + errorTurnedOn = false, toggleNotification, typeLabels, - showApprovalsToggle, + showApprovalsToggle = false, }) { const { t } = useLingui(); return ( @@ -121,12 +121,4 @@ NotificationListItem.propTypes = { showApprovalsToggle: bool, }; -NotificationListItem.defaultProps = { - approvalsTurnedOn: false, - errorTurnedOn: false, - startedTurnedOn: false, - successTurnedOn: false, - showApprovalsToggle: false, -}; - export default NotificationListItem; diff --git a/awx/ui/src/components/OptionsList/OptionsList.js b/awx/ui/src/components/OptionsList/OptionsList.js index c69b0a527..223496c80 100644 --- a/awx/ui/src/components/OptionsList/OptionsList.js +++ b/awx/ui/src/components/OptionsList/OptionsList.js @@ -26,22 +26,22 @@ function OptionsList({ columns, contentError, deselectItem, - displayKey, + displayKey = 'name', header, isLoading, - isSelectedDraggable, - multiple, + isSelectedDraggable = false, + multiple = false, name, optionCount, options, qsConfig, readOnly, relatedSearchableKeys, - renderItemChip, - searchColumns, + renderItemChip = null, + searchColumns = [], searchableKeys, selectItem, - sortColumns, + sortColumns = [], sortSelectedItems, value, }) { @@ -145,13 +145,5 @@ OptionsList.propTypes = { sortColumns: SortColumns, value: oneOfType([arrayOf(Item), arrayOf(InstanceItem)]).isRequired, }; -OptionsList.defaultProps = { - isSelectedDraggable: false, - multiple: false, - renderItemChip: null, - searchColumns: [], - sortColumns: [], - displayKey: 'name', -}; export default OptionsList; diff --git a/awx/ui/src/components/PaginatedTable/HeaderRow.js b/awx/ui/src/components/PaginatedTable/HeaderRow.js index 13269593f..38a95c19b 100644 --- a/awx/ui/src/components/PaginatedTable/HeaderRow.js +++ b/awx/ui/src/components/PaginatedTable/HeaderRow.js @@ -14,7 +14,7 @@ const Th = styled(PFTh)` export default function HeaderRow({ qsConfig, isExpandable, - isSelectable, + isSelectable = true, children, }) { const location = useLocation(); @@ -59,10 +59,6 @@ export default function HeaderRow({ ); } -HeaderRow.defaultProps = { - isSelectable: true, -}; - export function HeaderCell({ sortKey, onSort, diff --git a/awx/ui/src/components/PaginatedTable/PaginatedTable.js b/awx/ui/src/components/PaginatedTable/PaginatedTable.js index 75c97dc62..d6758f6c2 100644 --- a/awx/ui/src/components/PaginatedTable/PaginatedTable.js +++ b/awx/ui/src/components/PaginatedTable/PaginatedTable.js @@ -19,24 +19,27 @@ import Pagination from '../Pagination'; import DataListToolbar from '../DataListToolbar'; import LoadingSpinner from '../LoadingSpinner'; +// Stable default so the clearSelected effect dep does not change every render. +const noop = () => {}; + function PaginatedTable({ - contentError, - hasContentLoading, + contentError = null, + hasContentLoading = false, emptyStateControls, items, itemCount, qsConfig, headerRow, renderRow, - toolbarSearchColumns, - toolbarSearchableKeys, - toolbarRelatedSearchableKeys, - pluralizedItemName, - showPageSizeOptions, - renderToolbar, + toolbarSearchColumns = [], + toolbarSearchableKeys = [], + toolbarRelatedSearchableKeys = [], + pluralizedItemName = null, + showPageSizeOptions = true, + renderToolbar = (props) => , emptyContentMessage, - clearSelected, - ouiaId, + clearSelected = noop, + ouiaId = null, }) { const { t } = useLingui(); const location = useLocation(); @@ -207,18 +210,5 @@ PaginatedTable.propTypes = { ouiaId: PropTypes.string, }; -PaginatedTable.defaultProps = { - hasContentLoading: false, - contentError: null, - toolbarSearchColumns: [], - toolbarSearchableKeys: [], - toolbarRelatedSearchableKeys: [], - pluralizedItemName: null, - showPageSizeOptions: true, - renderToolbar: (props) => , - ouiaId: null, - clearSelected: () => {}, -}; - export { PaginatedTable as _PaginatedTable }; export default PaginatedTable; diff --git a/awx/ui/src/components/PaginatedTable/ToolbarAddButton.js b/awx/ui/src/components/PaginatedTable/ToolbarAddButton.js index 7de33f03d..4a0e9fa3d 100644 --- a/awx/ui/src/components/PaginatedTable/ToolbarAddButton.js +++ b/awx/ui/src/components/PaginatedTable/ToolbarAddButton.js @@ -7,8 +7,8 @@ import { useLingui } from '@lingui/react/macro'; import { useKebabifiedMenu } from 'contexts/Kebabified'; function ToolbarAddButton({ - linkTo, - onClick, + linkTo = null, + onClick = null, isDisabled, defaultLabel, showToggleIndicator, @@ -64,9 +64,5 @@ ToolbarAddButton.propTypes = { linkTo: string, onClick: func, }; -ToolbarAddButton.defaultProps = { - linkTo: null, - onClick: null, -}; export default ToolbarAddButton; diff --git a/awx/ui/src/components/PaginatedTable/ToolbarDeleteButton.js b/awx/ui/src/components/PaginatedTable/ToolbarDeleteButton.js index f25737e16..11ab33ff7 100644 --- a/awx/ui/src/components/PaginatedTable/ToolbarDeleteButton.js +++ b/awx/ui/src/components/PaginatedTable/ToolbarDeleteButton.js @@ -88,13 +88,13 @@ const ItemToDelete = shape({ function ToolbarDeleteButton({ itemsToDelete, - pluralizedItemName, + pluralizedItemName = 'Items', errorMessage, onDelete, deleteDetailsRequests, - warningMessage, + warningMessage = null, deleteMessage, - cannotDelete, + cannotDelete = (item) => !item.summary_fields.user_capabilities.delete, }) { const { t } = useLingui(); const { isKebabified, onKebabModalChange } = useContext(KebabifiedContext); @@ -312,10 +312,4 @@ ToolbarDeleteButton.propTypes = { cannotDelete: func, }; -ToolbarDeleteButton.defaultProps = { - pluralizedItemName: 'Items', - warningMessage: null, - cannotDelete: (item) => !item.summary_fields.user_capabilities.delete, -}; - export default ToolbarDeleteButton; diff --git a/awx/ui/src/components/PaginatedTable/ToolbarSyncSourceButton.js b/awx/ui/src/components/PaginatedTable/ToolbarSyncSourceButton.js index e148182bc..16c81be59 100644 --- a/awx/ui/src/components/PaginatedTable/ToolbarSyncSourceButton.js +++ b/awx/ui/src/components/PaginatedTable/ToolbarSyncSourceButton.js @@ -5,7 +5,7 @@ import { useLingui } from '@lingui/react/macro'; import { useKebabifiedMenu } from 'contexts/Kebabified'; -function ToolbarSyncSourceButton({ onClick }) { +function ToolbarSyncSourceButton({ onClick = null }) { const { t } = useLingui(); const { isKebabified } = useKebabifiedMenu(); @@ -43,8 +43,5 @@ function ToolbarSyncSourceButton({ onClick }) { ToolbarSyncSourceButton.propTypes = { onClick: func, }; -ToolbarSyncSourceButton.defaultProps = { - onClick: null, -}; export default ToolbarSyncSourceButton; diff --git a/awx/ui/src/components/Popover/Popover.js b/awx/ui/src/components/Popover/Popover.js index 4ed98142b..3dceadd1d 100644 --- a/awx/ui/src/components/Popover/Popover.js +++ b/awx/ui/src/components/Popover/Popover.js @@ -13,7 +13,14 @@ const PopoverButton = styled.button` --pf-c-form__group-label-help--hover--Color: var(--pf-global--Color--100); `; -function Popover({ ariaLabel, content, header, id, maxWidth, ...rest }) { +function Popover({ + ariaLabel = null, + content = null, + header = null, + id = '', + maxWidth = '', + ...rest +}) { const { t } = useLingui(); if (!content) { return null; @@ -48,12 +55,5 @@ Popover.propTypes = { id: string, maxWidth: string, }; -Popover.defaultProps = { - ariaLabel: null, - content: null, - header: null, - id: '', - maxWidth: '', -}; export default Popover; diff --git a/awx/ui/src/components/PromptDetail/PromptDetail.js b/awx/ui/src/components/PromptDetail/PromptDetail.js index 8002e91d9..1039cc785 100644 --- a/awx/ui/src/components/PromptDetail/PromptDetail.js +++ b/awx/ui/src/components/PromptDetail/PromptDetail.js @@ -99,7 +99,7 @@ function omitOverrides(resource, overrides, defaultConfig) { function PromptDetail({ resource, - launchConfig = {}, + launchConfig = { defaults: {} }, overrides = {}, workflowNode = false, }) { @@ -386,10 +386,6 @@ function PromptDetail({ ); } -PromptDetail.defaultProps = { - launchConfig: { defaults: {} }, -}; - PromptDetail.propTypes = { resource: shape({}).isRequired, launchConfig: shape({}), diff --git a/awx/ui/src/components/ResourceAccessList/DeleteRoleConfirmationModal.js b/awx/ui/src/components/ResourceAccessList/DeleteRoleConfirmationModal.js index 8810acd83..badc02286 100644 --- a/awx/ui/src/components/ResourceAccessList/DeleteRoleConfirmationModal.js +++ b/awx/ui/src/components/ResourceAccessList/DeleteRoleConfirmationModal.js @@ -7,7 +7,12 @@ import { useLingui } from '@lingui/react/macro'; import { Role } from 'types'; import AlertModal from '../AlertModal'; -function DeleteRoleConfirmationModal({ role, username, onCancel, onConfirm }) { +function DeleteRoleConfirmationModal({ + role, + username = '', + onCancel, + onConfirm, +}) { const { t } = useLingui(); const sourceOfRole = () => typeof role.team_id !== 'undefined' ? t`Team` : t`User`; @@ -61,8 +66,4 @@ DeleteRoleConfirmationModal.propTypes = { onConfirm: func.isRequired, }; -DeleteRoleConfirmationModal.defaultProps = { - username: '', -}; - export default DeleteRoleConfirmationModal; diff --git a/awx/ui/src/components/Schedule/ScheduleAdd/ScheduleAdd.js b/awx/ui/src/components/Schedule/ScheduleAdd/ScheduleAdd.js index b9cfa1f4f..c8d661c64 100644 --- a/awx/ui/src/components/Schedule/ScheduleAdd/ScheduleAdd.js +++ b/awx/ui/src/components/Schedule/ScheduleAdd/ScheduleAdd.js @@ -168,6 +168,4 @@ ScheduleAdd.propTypes = { apiModel: shape({ createSchedule: func.isRequired }).isRequired, }; -ScheduleAdd.defaultProps = {}; - export default ScheduleAdd; diff --git a/awx/ui/src/components/Schedule/ScheduleEdit/ScheduleEdit.js b/awx/ui/src/components/Schedule/ScheduleEdit/ScheduleEdit.js index 2814ceb12..ac352cfd0 100644 --- a/awx/ui/src/components/Schedule/ScheduleEdit/ScheduleEdit.js +++ b/awx/ui/src/components/Schedule/ScheduleEdit/ScheduleEdit.js @@ -201,6 +201,4 @@ ScheduleEdit.propTypes = { schedule: shape({}).isRequired, }; -ScheduleEdit.defaultProps = {}; - export default ScheduleEdit; diff --git a/awx/ui/src/components/Schedule/ScheduleList/ScheduleList.js b/awx/ui/src/components/Schedule/ScheduleList/ScheduleList.js index dedb81d16..aa1cbc8ae 100644 --- a/awx/ui/src/components/Schedule/ScheduleList/ScheduleList.js +++ b/awx/ui/src/components/Schedule/ScheduleList/ScheduleList.js @@ -27,7 +27,7 @@ const QS_CONFIG = getQSConfig('schedule', { function ScheduleList({ loadSchedules, loadScheduleOptions, - hideAddButton, + hideAddButton = false, resource, launchConfig, surveyConfig, @@ -259,8 +259,5 @@ ScheduleList.propTypes = { loadSchedules: func.isRequired, loadScheduleOptions: func.isRequired, }; -ScheduleList.defaultProps = { - hideAddButton: false, -}; export default ScheduleList; diff --git a/awx/ui/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.js b/awx/ui/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.js index 41fa5b725..7a6fa9001 100644 --- a/awx/ui/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.js +++ b/awx/ui/src/components/Schedule/ScheduleOccurrences/ScheduleOccurrences.js @@ -22,7 +22,10 @@ const OccurrencesLabel = styled.div` } `; -function ScheduleOccurrences({ preview = { local: [], utc: [] }, tz }) { +function ScheduleOccurrences({ + preview = { local: [], utc: [] }, + tz = Intl.DateTimeFormat().resolvedOptions().timeZone, +}) { const { t } = useLingui(); const [mode, setMode] = useState('local'); @@ -79,9 +82,4 @@ ScheduleOccurrences.propTypes = { tz: string, }; -ScheduleOccurrences.defaultProps = { - preview: { local: [], utc: [] }, - tz: Intl.DateTimeFormat().resolvedOptions().timeZone, -}; - export default ScheduleOccurrences; diff --git a/awx/ui/src/components/Schedule/shared/ScheduleForm.js b/awx/ui/src/components/Schedule/shared/ScheduleForm.js index a3e52f217..78ad95791 100644 --- a/awx/ui/src/components/Schedule/shared/ScheduleForm.js +++ b/awx/ui/src/components/Schedule/shared/ScheduleForm.js @@ -28,12 +28,14 @@ const NUM_DAYS_PER_FREQUENCY = { year: 365, }; +const defaultSchedule = {}; + function ScheduleForm({ hasDaysToKeepField, handleCancel, handleSubmit: submitSchedule, - schedule, - submitError, + schedule = defaultSchedule, + submitError = null, resource, launchConfig, surveyConfig, @@ -577,11 +579,6 @@ ScheduleForm.propTypes = { submitError: shape(), }; -ScheduleForm.defaultProps = { - schedule: {}, - submitError: null, -}; - export default ScheduleForm; function scheduleHasInstances(values) { diff --git a/awx/ui/src/components/Search/AdvancedSearch.js b/awx/ui/src/components/Search/AdvancedSearch.js index ff0c85cef..135ad2427 100644 --- a/awx/ui/src/components/Search/AdvancedSearch.js +++ b/awx/ui/src/components/Search/AdvancedSearch.js @@ -42,12 +42,12 @@ const AdvancedGroup = styled.div` function AdvancedSearch({ onSearch, - searchableKeys, - relatedSearchableKeys, - maxSelectHeight, - enableNegativeFiltering, - enableRelatedFuzzyFiltering, - handleIsAnsibleFactsSelected, + searchableKeys = [], + relatedSearchableKeys = [], + maxSelectHeight = '300px', + enableNegativeFiltering = true, + enableRelatedFuzzyFiltering = true, + handleIsAnsibleFactsSelected = () => {}, isFilterCleared, }) { const { t } = useLingui(); @@ -356,13 +356,4 @@ AdvancedSearch.propTypes = { handleIsAnsibleFactsSelected: func, }; -AdvancedSearch.defaultProps = { - searchableKeys: [], - relatedSearchableKeys: [], - maxSelectHeight: '300px', - enableNegativeFiltering: true, - enableRelatedFuzzyFiltering: true, - handleIsAnsibleFactsSelected: () => {}, -}; - export default AdvancedSearch; diff --git a/awx/ui/src/components/Search/LookupTypeInput.js b/awx/ui/src/components/Search/LookupTypeInput.js index 42a316342..b5eb60c18 100644 --- a/awx/ui/src/components/Search/LookupTypeInput.js +++ b/awx/ui/src/components/Search/LookupTypeInput.js @@ -3,17 +3,19 @@ import { string, oneOfType, arrayOf, func } from 'prop-types'; import { useLingui } from '@lingui/react/macro'; import { Select, SelectOption, SelectVariant } from '@patternfly/react-core'; -function Option({ show, ...props }) { +function Option({ show = true, ...props }) { if (!show) { return null; } return ; } -Option.defaultProps = { - show: true, -}; -function LookupTypeInput({ value, type, setValue, maxSelectHeight }) { +function LookupTypeInput({ + value = '', + type = 'string', + setValue, + maxSelectHeight = '300px', +}) { const [isOpen, setIsOpen] = useState(false); const { t } = useLingui(); return ( @@ -148,10 +150,5 @@ LookupTypeInput.propTypes = { setValue: func.isRequired, maxSelectHeight: string, }; -LookupTypeInput.defaultProps = { - type: 'string', - value: '', - maxSelectHeight: '300px', -}; export default LookupTypeInput; diff --git a/awx/ui/src/components/Search/Search.js b/awx/ui/src/components/Search/Search.js index 0269ff925..047cf46df 100644 --- a/awx/ui/src/components/Search/Search.js +++ b/awx/ui/src/components/Search/Search.js @@ -49,17 +49,17 @@ const NoOptionDropdown = styled.div` function Search({ columns, - onSearch, + onSearch = null, onReplaceSearch, - onRemove, + onRemove = null, qsConfig, - searchableKeys, + searchableKeys = [], relatedSearchableKeys, onShowAdvancedSearch, - isDisabled, - maxSelectHeight, - enableNegativeFiltering, - enableRelatedFuzzyFiltering, + isDisabled = false, + maxSelectHeight = '300px', + enableNegativeFiltering = true, + enableRelatedFuzzyFiltering = true, handleIsAnsibleFactsSelected, isFilterCleared, }) { @@ -400,14 +400,4 @@ Search.propTypes = { searchableKeys: SearchableKeys, }; -Search.defaultProps = { - onSearch: null, - onRemove: null, - isDisabled: false, - maxSelectHeight: '300px', - enableNegativeFiltering: true, - enableRelatedFuzzyFiltering: true, - searchableKeys: [], -}; - export default Search; diff --git a/awx/ui/src/components/SelectableCard/SelectableCard.js b/awx/ui/src/components/SelectableCard/SelectableCard.js index d383c59d1..0c35a6046 100644 --- a/awx/ui/src/components/SelectableCard/SelectableCard.js +++ b/awx/ui/src/components/SelectableCard/SelectableCard.js @@ -32,12 +32,12 @@ const Description = styled.p` `; function SelectableCard({ - label, - description, + label = '', + description = '', onClick, - isSelected, + isSelected = false, dataCy, - ariaLabel, + ariaLabel = '', }) { return ( null, + onRowDrag = () => null, +}) { const { t } = useLingui(); const [liveText, setLiveText] = useState(''); const [id, setId] = useState(''); @@ -134,10 +138,5 @@ DraggableSelectedList.propTypes = { onRowDrag: PropTypes.func, selected: PropTypes.arrayOf(ListItem), }; -DraggableSelectedList.defaultProps = { - onRemove: () => null, - onRowDrag: () => null, - selected: [], -}; export default DraggableSelectedList; diff --git a/awx/ui/src/components/SelectedList/SelectedList.js b/awx/ui/src/components/SelectedList/SelectedList.js index aaf7dca48..bd6287cb1 100644 --- a/awx/ui/src/components/SelectedList/SelectedList.js +++ b/awx/ui/src/components/SelectedList/SelectedList.js @@ -16,10 +16,14 @@ const SplitLabelItem = styled(SplitItem)` word-break: initial; `; -function SelectedList(props) { - const { label, selected, onRemove, displayKey, isReadOnly, renderItemChip } = - props; - +function SelectedList({ + label = 'Selected', + selected, + onRemove = () => null, + displayKey = 'name', + isReadOnly = false, + renderItemChip = null, +}) { const renderChip = renderItemChip || (({ item, removeItem }) => ( @@ -59,12 +63,4 @@ SelectedList.propTypes = { renderItemChip: PropTypes.func, }; -SelectedList.defaultProps = { - displayKey: 'name', - label: 'Selected', - onRemove: () => null, - isReadOnly: false, - renderItemChip: null, -}; - export default SelectedList; diff --git a/awx/ui/src/components/Sort/Sort.js b/awx/ui/src/components/Sort/Sort.js index 4d01ca056..0a16567f2 100644 --- a/awx/ui/src/components/Sort/Sort.js +++ b/awx/ui/src/components/Sort/Sort.js @@ -32,7 +32,7 @@ const NoOptionDropdown = styled.div` border-bottom-color: var(--pf-global--BorderColor--200); `; -function Sort({ columns, qsConfig, onSort }) { +function Sort({ columns, qsConfig, onSort = null }) { const { t } = useLingui(); const location = useLocation(); const [isSortDropdownOpen, setIsSortDropdownOpen] = useState(false); @@ -155,8 +155,4 @@ Sort.propTypes = { onSort: PropTypes.func, }; -Sort.defaultProps = { - onSort: null, -}; - export default Sort; diff --git a/awx/ui/src/components/Sparkline/Sparkline.js b/awx/ui/src/components/Sparkline/Sparkline.js index 64eba5ec2..1980f6209 100644 --- a/awx/ui/src/components/Sparkline/Sparkline.js +++ b/awx/ui/src/components/Sparkline/Sparkline.js @@ -21,7 +21,7 @@ const Wrapper = styled.div` `; /* eslint-enable react/jsx-pascal-case */ -const Sparkline = ({ jobs }) => { +const Sparkline = ({ jobs = [] }) => { const { t } = useLingui(); const generateTooltip = (job) => ( <> @@ -56,8 +56,5 @@ const Sparkline = ({ jobs }) => { Sparkline.propTypes = { jobs: arrayOf(Job), }; -Sparkline.defaultProps = { - jobs: [], -}; export default Sparkline; diff --git a/awx/ui/src/components/Workflow/WorkflowActionTooltipItem.js b/awx/ui/src/components/Workflow/WorkflowActionTooltipItem.js index 419a4465f..3dd647857 100644 --- a/awx/ui/src/components/Workflow/WorkflowActionTooltipItem.js +++ b/awx/ui/src/components/Workflow/WorkflowActionTooltipItem.js @@ -25,9 +25,9 @@ const TooltipItem = styled.div` function WorkflowActionTooltipItem({ children, id, - onClick, - onMouseEnter, - onMouseLeave, + onClick = () => {}, + onMouseEnter = () => {}, + onMouseLeave = () => {}, }) { return ( {}, - onMouseEnter: () => {}, - onMouseLeave: () => {}, -}; - export default WorkflowActionTooltipItem; diff --git a/awx/ui/src/components/Workflow/WorkflowStartNode.js b/awx/ui/src/components/Workflow/WorkflowStartNode.js index 245c1b688..f48f9a598 100644 --- a/awx/ui/src/components/Workflow/WorkflowStartNode.js +++ b/awx/ui/src/components/Workflow/WorkflowStartNode.js @@ -30,7 +30,7 @@ const StartDiv = styled.div` padding: 0px 10px; `; -function WorkflowStartNode({ onUpdateHelpText, showActionTooltip }) { +function WorkflowStartNode({ onUpdateHelpText = () => {}, showActionTooltip }) { const { t } = useLingui(); const ref = useRef(null); const startNodeRef = useRef(null); @@ -90,8 +90,4 @@ WorkflowStartNode.propTypes = { onUpdateHelpText: func, }; -WorkflowStartNode.defaultProps = { - onUpdateHelpText: () => {}, -}; - export default WorkflowStartNode; diff --git a/awx/ui/src/screens/Credential/shared/CredentialForm.js b/awx/ui/src/screens/Credential/shared/CredentialForm.js index 5497b3ab0..952f1b351 100644 --- a/awx/ui/src/screens/Credential/shared/CredentialForm.js +++ b/awx/ui/src/screens/Credential/shared/CredentialForm.js @@ -211,10 +211,10 @@ function CredentialFormFields({ initialTypeId, credentialTypes }) { function CredentialForm({ credential = {}, credentialTypes, - inputSources, + inputSources = {}, onSubmit, onCancel, - submitError, + submitError = null, isOrgLookupDisabled, ...rest }) { @@ -364,10 +364,4 @@ CredentialForm.propTypes = { submitError: shape({}), }; -CredentialForm.defaultProps = { - credential: {}, - inputSources: {}, - submitError: null, -}; - export default CredentialForm; diff --git a/awx/ui/src/screens/Credential/shared/CredentialFormFields/BecomeMethodField.js b/awx/ui/src/screens/Credential/shared/CredentialFormFields/BecomeMethodField.js index eab798e92..d66a53abe 100644 --- a/awx/ui/src/screens/Credential/shared/CredentialFormFields/BecomeMethodField.js +++ b/awx/ui/src/screens/Credential/shared/CredentialFormFields/BecomeMethodField.js @@ -10,7 +10,7 @@ import { } from '@patternfly/react-core'; import Popover from 'components/Popover'; -function BecomeMethodField({ fieldOptions, isRequired }) { +function BecomeMethodField({ fieldOptions, isRequired = false }) { const { t } = useLingui(); const [isOpen, setIsOpen] = useState(false); const [options, setOptions] = useState( @@ -80,8 +80,5 @@ BecomeMethodField.propTypes = { }).isRequired, isRequired: bool, }; -BecomeMethodField.defaultProps = { - isRequired: false, -}; export default BecomeMethodField; diff --git a/awx/ui/src/screens/Credential/shared/CredentialFormFields/CredentialField.js b/awx/ui/src/screens/Credential/shared/CredentialFormFields/CredentialField.js index 9ffeae675..a3e2cef3d 100644 --- a/awx/ui/src/screens/Credential/shared/CredentialFormFields/CredentialField.js +++ b/awx/ui/src/screens/Credential/shared/CredentialFormFields/CredentialField.js @@ -29,7 +29,7 @@ const FileUpload = styled(PFFileUpload)` function CredentialInput({ fieldOptions, isFieldGroupValid, - credentialKind, + credentialKind = '', isVaultIdDisabled, ...rest }) { @@ -167,10 +167,6 @@ CredentialInput.propTypes = { credentialKind: string, }; -CredentialInput.defaultProps = { - credentialKind: '', -}; - function CredentialField({ credentialType, fieldOptions }) { const { values: formikValues } = useFormikContext(); const location = useLocation(); @@ -256,6 +252,4 @@ CredentialField.propTypes = { }).isRequired, }; -CredentialField.defaultProps = {}; - export default CredentialField; diff --git a/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.js b/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.js index 5649c890b..c5643d141 100644 --- a/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.js +++ b/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginField.js @@ -95,8 +95,13 @@ function CredentialPluginInput(props) { ); } -function CredentialPluginField(props) { - const { fieldOptions, isRequired, validated } = props; +function CredentialPluginField({ + isDisabled = false, + isRequired = false, + ...restProps +}) { + const props = { isDisabled, isRequired, ...restProps }; + const { fieldOptions, validated } = props; const [, meta, helpers] = useField(`inputs.${fieldOptions.id}`); const [passwordPromptField] = useField(`passwordPrompts.${fieldOptions.id}`); @@ -170,9 +175,4 @@ CredentialPluginField.propTypes = { isRequired: PropTypes.bool, }; -CredentialPluginField.defaultProps = { - isDisabled: false, - isRequired: false, -}; - export default CredentialPluginField; diff --git a/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.js b/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.js index c2e9db0bf..cc44f5536 100644 --- a/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.js +++ b/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginPrompt/CredentialPluginPrompt.js @@ -129,7 +129,7 @@ function CredentialPluginWizard({ handleSubmit, onClose }) { ); } -function CredentialPluginPrompt({ onClose, onSubmit, initialValues }) { +function CredentialPluginPrompt({ onClose, onSubmit, initialValues = {} }) { return ( {}, + onClearPlugin = () => {}, fieldId, }) { const { t } = useLingui(); @@ -63,9 +63,4 @@ CredentialPluginSelected.propTypes = { onClearPlugin: func, }; -CredentialPluginSelected.defaultProps = { - onEditPlugin: () => {}, - onClearPlugin: () => {}, -}; - export default CredentialPluginSelected; diff --git a/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.js b/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.js index 8a5699d3f..2979c7b02 100644 --- a/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.js +++ b/awx/ui/src/screens/Credential/shared/CredentialPlugins/CredentialPluginTestAlert.js @@ -10,8 +10,8 @@ import { function CredentialPluginTestAlert({ credentialName, - successResponse, - errorResponse, + successResponse = null, + errorResponse = null, }) { const { t } = useLingui(); const [testMessage, setTestMessage] = useState(''); @@ -79,9 +79,4 @@ CredentialPluginTestAlert.propTypes = { errorResponse: shape({}), }; -CredentialPluginTestAlert.defaultProps = { - successResponse: null, - errorResponse: null, -}; - export default CredentialPluginTestAlert; diff --git a/awx/ui/src/screens/Credential/shared/ExternalTestModal.js b/awx/ui/src/screens/Credential/shared/ExternalTestModal.js index 6578cf7f5..43ad6b1b2 100644 --- a/awx/ui/src/screens/Credential/shared/ExternalTestModal.js +++ b/awx/ui/src/screens/Credential/shared/ExternalTestModal.js @@ -14,7 +14,7 @@ import useRequest from 'hooks/useRequest'; import { CredentialPluginTestAlert } from './CredentialPlugins'; function ExternalTestModal({ - credential, + credential = null, credentialType, credentialFormValues, onClose, @@ -175,8 +175,4 @@ ExternalTestModal.propType = { onClose: func.isRequired, }; -ExternalTestModal.defaultProps = { - credential: null, -}; - export default ExternalTestModal; diff --git a/awx/ui/src/screens/Credential/shared/TypeInputsSubForm.js b/awx/ui/src/screens/Credential/shared/TypeInputsSubForm.js index 95b5bfb84..b295b21a6 100644 --- a/awx/ui/src/screens/Credential/shared/TypeInputsSubForm.js +++ b/awx/ui/src/screens/Credential/shared/TypeInputsSubForm.js @@ -71,6 +71,4 @@ TypeInputsSubForm.propTypes = { credentialType: CredentialType.isRequired, }; -TypeInputsSubForm.defaultProps = {}; - export default TypeInputsSubForm; diff --git a/awx/ui/src/screens/CredentialType/shared/CredentialTypeForm.js b/awx/ui/src/screens/CredentialType/shared/CredentialTypeForm.js index b73f97f36..cb1c11beb 100644 --- a/awx/ui/src/screens/CredentialType/shared/CredentialTypeForm.js +++ b/awx/ui/src/screens/CredentialType/shared/CredentialTypeForm.js @@ -55,7 +55,7 @@ function CredentialTypeForm({ credentialType = {}, onSubmit, onCancel, - submitError, + submitError = null, ...rest }) { const initialValues = { @@ -96,9 +96,4 @@ CredentialTypeForm.propTypes = { submitError: shape({}), }; -CredentialTypeForm.defaultProps = { - credentialType: {}, - submitError: null, -}; - export default CredentialTypeForm; diff --git a/awx/ui/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.js b/awx/ui/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.js index eb526b03a..499d70fa6 100644 --- a/awx/ui/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.js +++ b/awx/ui/src/screens/ExecutionEnvironment/shared/ExecutionEnvironmentForm.js @@ -159,9 +159,9 @@ function ExecutionEnvironmentForm({ executionEnvironment = {}, onSubmit, onCancel, - submitError, + submitError = null, me, - isOrgLookupDisabled, + isOrgLookupDisabled = false, ...rest }) { const { @@ -234,10 +234,4 @@ ExecutionEnvironmentForm.propTypes = { isOrgLookupDisabled: bool, }; -ExecutionEnvironmentForm.defaultProps = { - executionEnvironment: {}, - submitError: null, - isOrgLookupDisabled: false, -}; - export default ExecutionEnvironmentForm; diff --git a/awx/ui/src/screens/Host/HostList/SmartInventoryButton.js b/awx/ui/src/screens/Host/HostList/SmartInventoryButton.js index 8ab1bdf86..3d320954f 100644 --- a/awx/ui/src/screens/Host/HostList/SmartInventoryButton.js +++ b/awx/ui/src/screens/Host/HostList/SmartInventoryButton.js @@ -8,9 +8,9 @@ import { useKebabifiedMenu } from 'contexts/Kebabified'; function SmartInventoryButton({ onClick, - isDisabled, - hasInvalidKeys, - hasAnsibleFactsKeys, + isDisabled = false, + hasInvalidKeys = false, + hasAnsibleFactsKeys = false, }) { const { t } = useLingui(); const { isKebabified } = useKebabifiedMenu(); @@ -74,10 +74,4 @@ SmartInventoryButton.propTypes = { hasAnsibleFactsKeys: bool, }; -SmartInventoryButton.defaultProps = { - hasInvalidKeys: false, - isDisabled: false, - hasAnsibleFactsKeys: false, -}; - export default SmartInventoryButton; diff --git a/awx/ui/src/screens/HostMetrics/HostMetricsDeleteButton.js b/awx/ui/src/screens/HostMetrics/HostMetricsDeleteButton.js index 6fd7787cd..89e84bdd3 100644 --- a/awx/ui/src/screens/HostMetrics/HostMetricsDeleteButton.js +++ b/awx/ui/src/screens/HostMetrics/HostMetricsDeleteButton.js @@ -24,10 +24,10 @@ const ItemToDelete = shape({ function HostMetricsDeleteButton({ itemsToDelete, - pluralizedItemName, + pluralizedItemName = 'Items', onDelete, deleteDetailsRequests, - warningMessage, + warningMessage = null, deleteMessage, }) { const { t } = useLingui(); @@ -198,9 +198,4 @@ HostMetricsDeleteButton.propTypes = { warningMessage: node, }; -HostMetricsDeleteButton.defaultProps = { - pluralizedItemName: 'Items', - warningMessage: null, -}; - export default HostMetricsDeleteButton; diff --git a/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js b/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js index b49177690..49d91f58b 100644 --- a/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js +++ b/awx/ui/src/screens/InstanceGroup/shared/ContainerGroupForm.js @@ -108,11 +108,11 @@ function ContainerGroupFormFields({ instanceGroup }) { } function ContainerGroupForm({ - initialPodSpec, - instanceGroup, + initialPodSpec = {}, + instanceGroup = {}, onSubmit, onCancel, - submitError, + submitError = null, ...rest }) { const isCheckboxChecked = Boolean(instanceGroup?.pod_spec_override) || false; @@ -159,10 +159,4 @@ ContainerGroupForm.propTypes = { initialPodSpec: shape({}), }; -ContainerGroupForm.defaultProps = { - instanceGroup: {}, - submitError: null, - initialPodSpec: {}, -}; - export default ContainerGroupForm; diff --git a/awx/ui/src/screens/InstanceGroup/shared/InstanceGroupForm.js b/awx/ui/src/screens/InstanceGroup/shared/InstanceGroupForm.js index 0622ac825..7efab01e9 100644 --- a/awx/ui/src/screens/InstanceGroup/shared/InstanceGroupForm.js +++ b/awx/ui/src/screens/InstanceGroup/shared/InstanceGroupForm.js @@ -66,7 +66,7 @@ function InstanceGroupForm({ instanceGroup = {}, onSubmit, onCancel, - submitError, + submitError = null, ...rest }) { const initialValues = { @@ -104,9 +104,4 @@ InstanceGroupForm.propTypes = { submitError: shape({}), }; -InstanceGroupForm.defaultProps = { - instanceGroup: {}, - submitError: null, -}; - export default InstanceGroupForm; diff --git a/awx/ui/src/screens/Inventory/shared/ConstructedInventoryForm.js b/awx/ui/src/screens/Inventory/shared/ConstructedInventoryForm.js index b30f89f25..2f58e3de4 100644 --- a/awx/ui/src/screens/Inventory/shared/ConstructedInventoryForm.js +++ b/awx/ui/src/screens/Inventory/shared/ConstructedInventoryForm.js @@ -160,7 +160,7 @@ function ConstructedInventoryForm({ inputInventories, onCancel, onSubmit, - submitError, + submitError = null, options, }) { const initialValues = { @@ -200,8 +200,4 @@ ConstructedInventoryForm.propTypes = { submitError: shape({}), }; -ConstructedInventoryForm.defaultProps = { - submitError: null, -}; - export default ConstructedInventoryForm; diff --git a/awx/ui/src/screens/Inventory/shared/FederatedInventoryForm.js b/awx/ui/src/screens/Inventory/shared/FederatedInventoryForm.js index f875371a5..5ded87ec4 100644 --- a/awx/ui/src/screens/Inventory/shared/FederatedInventoryForm.js +++ b/awx/ui/src/screens/Inventory/shared/FederatedInventoryForm.js @@ -109,7 +109,7 @@ function FederatedInventoryForm({ inputInventories, onCancel, onSubmit, - submitError, + submitError = null, }) { const initialValues = { kind: 'federated', @@ -143,8 +143,4 @@ FederatedInventoryForm.propTypes = { submitError: shape({}), }; -FederatedInventoryForm.defaultProps = { - submitError: null, -}; - export default FederatedInventoryForm; diff --git a/awx/ui/src/screens/Inventory/shared/InventoryForm.js b/awx/ui/src/screens/Inventory/shared/InventoryForm.js index 29e7aaab0..b91fcc9c8 100644 --- a/awx/ui/src/screens/Inventory/shared/InventoryForm.js +++ b/awx/ui/src/screens/Inventory/shared/InventoryForm.js @@ -120,8 +120,8 @@ function InventoryForm({ inventory = {}, onSubmit, onCancel, - submitError, - instanceGroups, + submitError = null, + instanceGroups = [], ...rest }) { const initialValues = { @@ -167,10 +167,4 @@ InventoryForm.propType = { submitError: shape(), }; -InventoryForm.defaultProps = { - inventory: {}, - instanceGroups: [], - submitError: null, -}; - export default InventoryForm; diff --git a/awx/ui/src/screens/Inventory/shared/InventoryGroupsDeleteModal.js b/awx/ui/src/screens/Inventory/shared/InventoryGroupsDeleteModal.js index 95a62baf1..14c73c0f5 100644 --- a/awx/ui/src/screens/Inventory/shared/InventoryGroupsDeleteModal.js +++ b/awx/ui/src/screens/Inventory/shared/InventoryGroupsDeleteModal.js @@ -16,7 +16,11 @@ const ListItem = styled.li` color: var(--pf-global--danger-color--100); `; -const InventoryGroupsDeleteModal = ({ onAfterDelete, isDisabled, groups }) => { +const InventoryGroupsDeleteModal = ({ + onAfterDelete, + isDisabled, + groups = [], +}) => { const { t } = useLingui(); const [radioOption, setRadioOption] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); @@ -166,8 +170,4 @@ InventoryGroupsDeleteModal.propTypes = { isDisabled: bool.isRequired, }; -InventoryGroupsDeleteModal.defaultProps = { - groups: [], -}; - export default InventoryGroupsDeleteModal; diff --git a/awx/ui/src/screens/Inventory/shared/InventorySourceForm.js b/awx/ui/src/screens/Inventory/shared/InventorySourceForm.js index 1a3564609..74e6b55e4 100644 --- a/awx/ui/src/screens/Inventory/shared/InventorySourceForm.js +++ b/awx/ui/src/screens/Inventory/shared/InventorySourceForm.js @@ -348,8 +348,4 @@ InventorySourceForm.propTypes = { submitError: shape({}), }; -InventorySourceForm.defaultProps = { - submitError: null, -}; - export default InventorySourceForm; diff --git a/awx/ui/src/screens/Inventory/shared/InventorySourceSyncButton.js b/awx/ui/src/screens/Inventory/shared/InventorySourceSyncButton.js index af089e1e2..0f6d9daf4 100644 --- a/awx/ui/src/screens/Inventory/shared/InventorySourceSyncButton.js +++ b/awx/ui/src/screens/Inventory/shared/InventorySourceSyncButton.js @@ -9,7 +9,7 @@ import AlertModal from 'components/AlertModal/AlertModal'; import ErrorDetail from 'components/ErrorDetail/ErrorDetail'; import { InventorySourcesAPI } from 'api'; -function InventorySourceSyncButton({ source, icon }) { +function InventorySourceSyncButton({ source = {}, icon = true }) { const { t } = useLingui(); const { isLoading: startSyncLoading, @@ -58,11 +58,6 @@ function InventorySourceSyncButton({ source, icon }) { ); } -InventorySourceSyncButton.defaultProps = { - source: {}, - icon: true, -}; - InventorySourceSyncButton.propTypes = { source: PropTypes.shape({}), icon: PropTypes.bool, diff --git a/awx/ui/src/screens/Inventory/shared/SmartInventoryForm.js b/awx/ui/src/screens/Inventory/shared/SmartInventoryForm.js index 794aed440..c30fc4b33 100644 --- a/awx/ui/src/screens/Inventory/shared/SmartInventoryForm.js +++ b/awx/ui/src/screens/Inventory/shared/SmartInventoryForm.js @@ -100,11 +100,11 @@ const SmartInventoryFormFields = ({ inventory }) => { }; function SmartInventoryForm({ - inventory, - instanceGroups, + inventory = {}, + instanceGroups = [], onSubmit, onCancel, - submitError, + submitError = null, }) { const { search } = useLocation(); const queryParams = new URLSearchParams(search); @@ -189,10 +189,4 @@ SmartInventoryForm.propTypes = { submitError: shape({}), }; -SmartInventoryForm.defaultProps = { - instanceGroups: [], - inventory: {}, - submitError: null, -}; - export default SmartInventoryForm; diff --git a/awx/ui/src/screens/Job/JobOutput/HostEventModal.js b/awx/ui/src/screens/Job/JobOutput/HostEventModal.js index eb61a7c28..dc92b3fea 100644 --- a/awx/ui/src/screens/Job/JobOutput/HostEventModal.js +++ b/awx/ui/src/screens/Job/JobOutput/HostEventModal.js @@ -65,7 +65,9 @@ const getStdOutValue = (hostEvent) => { return stdOut; }; -function HostEventModal({ onClose, hostEvent = {}, isOpen = false }) { +const defaultHostEvent = {}; + +function HostEventModal({ onClose, hostEvent = defaultHostEvent, isOpen = false }) { const { t } = useLingui(); const [hostStatus, setHostStatus] = useState(null); const [activeTabKey, setActiveTabKey] = useState(0); @@ -221,8 +223,3 @@ HostEventModal.propTypes = { hostEvent: PropTypes.shape({}), isOpen: PropTypes.bool, }; - -HostEventModal.defaultProps = { - hostEvent: null, - isOpen: false, -}; diff --git a/awx/ui/src/screens/Job/JobOutput/shared/OutputToolbar.js b/awx/ui/src/screens/Job/JobOutput/shared/OutputToolbar.js index 5feb6138c..684eafcdb 100644 --- a/awx/ui/src/screens/Job/JobOutput/shared/OutputToolbar.js +++ b/awx/ui/src/screens/Job/JobOutput/shared/OutputToolbar.js @@ -70,7 +70,12 @@ const OUTPUT_NO_COUNT_JOB_TYPES = [ 'inventory_update', ]; -const OutputToolbar = ({ job, onDelete, isDeleteDisabled, jobStatus }) => { +const OutputToolbar = ({ + job, + onDelete, + isDeleteDisabled = false, + jobStatus, +}) => { const { t } = useLingui(); const [activeJobElapsedTime, setActiveJobElapsedTime] = useState('00:00:00'); const hideCounts = OUTPUT_NO_COUNT_JOB_TYPES.includes(job.type); @@ -254,8 +259,4 @@ OutputToolbar.propTypes = { onDelete: func.isRequired, }; -OutputToolbar.defaultProps = { - isDeleteDisabled: false, -}; - export default OutputToolbar; diff --git a/awx/ui/src/screens/Job/JobTypeRedirect.js b/awx/ui/src/screens/Job/JobTypeRedirect.js index 84dbe02a0..7ee910de3 100644 --- a/awx/ui/src/screens/Job/JobTypeRedirect.js +++ b/awx/ui/src/screens/Job/JobTypeRedirect.js @@ -13,7 +13,7 @@ import { JOB_TYPE_URL_SEGMENTS } from '../../constants'; const NOT_FOUND = 'not found'; -function JobTypeRedirect({ id, view }) { +function JobTypeRedirect({ id, view = 'output' }) { const { t } = useLingui(); const { isLoading, @@ -64,7 +64,4 @@ function JobTypeRedirect({ id, view }) { ); } -JobTypeRedirect.defaultProps = { - view: 'output', -}; export default JobTypeRedirect; diff --git a/awx/ui/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.js b/awx/ui/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.js index e12d856cf..62f941e6c 100644 --- a/awx/ui/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.js +++ b/awx/ui/src/screens/Job/WorkflowOutput/WorkflowOutputToolbar.js @@ -93,7 +93,11 @@ const ActionButton = styled(Button)` color: #fff; } `; -function WorkflowOutputToolbar({ job, onDelete, isDeleteDisabled }) { +function WorkflowOutputToolbar({ + job, + onDelete = () => {}, + isDeleteDisabled = false, +}) { const { t } = useLingui(); const dispatch = useContext(WorkflowDispatchContext); const navigate = useNavigate(); @@ -265,9 +269,4 @@ WorkflowOutputToolbar.propTypes = { isDeleteDisabled: bool, }; -WorkflowOutputToolbar.defaultProps = { - onDelete: () => {}, - isDeleteDisabled: false, -}; - export default WorkflowOutputToolbar; diff --git a/awx/ui/src/screens/NotificationTemplate/shared/NotificationTemplateForm.js b/awx/ui/src/screens/NotificationTemplate/shared/NotificationTemplateForm.js index 39e3f108e..c2541ce16 100644 --- a/awx/ui/src/screens/NotificationTemplate/shared/NotificationTemplateForm.js +++ b/awx/ui/src/screens/NotificationTemplate/shared/NotificationTemplateForm.js @@ -102,11 +102,15 @@ function NotificationTemplateFormFields({ defaultMessages, template }) { } function NotificationTemplateForm({ - template, + template = { + name: '', + description: '', + notification_type: '', + }, defaultMessages, onSubmit, onCancel, - submitError, + submitError = null, }) { const handleSubmit = (values) => { onSubmit( @@ -203,15 +207,6 @@ NotificationTemplateForm.propTypes = { submitError: shape(), }; -NotificationTemplateForm.defaultProps = { - template: { - name: '', - description: '', - notification_type: '', - }, - submitError: null, -}; - export default NotificationTemplateForm; function normalizeFields(values, defaultMessages) { diff --git a/awx/ui/src/screens/NotificationTemplate/shared/TypeInputsSubForm.js b/awx/ui/src/screens/NotificationTemplate/shared/TypeInputsSubForm.js index 92bf0c174..0c7e618f2 100644 --- a/awx/ui/src/screens/NotificationTemplate/shared/TypeInputsSubForm.js +++ b/awx/ui/src/screens/NotificationTemplate/shared/TypeInputsSubForm.js @@ -41,10 +41,6 @@ const editFieldPropTypes = { isEdit: PropTypes.bool, }; -const editFieldDefaultProps = { - isEdit: false, -}; - const TypeFields = { email: EmailFields, grafana: GrafanaFields, @@ -56,7 +52,7 @@ const TypeFields = { twilio: TwilioFields, webhook: WebhookFields, }; -function TypeInputsSubForm({ type, isEdit }) { +function TypeInputsSubForm({ type, isEdit = false }) { const { t } = useLingui(); const Fields = TypeFields[type]; return ( @@ -75,17 +71,13 @@ TypeInputsSubForm.propTypes = { isEdit: PropTypes.bool, }; -TypeInputsSubForm.defaultProps = { - isEdit: false, -}; - export default TypeInputsSubForm; function SecretPasswordField({ id, label, name, - isEdit, + isEdit = false, isRequiredOnCreate = false, }) { const validate = isRequiredOnCreate && !isEdit ? required(null) : undefined; @@ -126,12 +118,7 @@ SecretPasswordField.propTypes = { isRequiredOnCreate: PropTypes.bool, }; -SecretPasswordField.defaultProps = { - isEdit: false, - isRequiredOnCreate: false, -}; - -function EmailFields({ isEdit }) { +function EmailFields({ isEdit = false }) { const { t } = useLingui(); const helpText = useMemo(() => ({ emailRecipients: t`Use one email address per line to create a recipient list for this type of notification.`, @@ -235,7 +222,7 @@ function EmailFields({ isEdit }) { ); } -function GrafanaFields({ isEdit }) { +function GrafanaFields({ isEdit = false }) { const { t } = useLingui(); const helpText = { grafanaUrl: t`The base URL of the Grafana server - the @@ -292,12 +279,8 @@ function GrafanaFields({ isEdit }) { EmailFields.propTypes = editFieldPropTypes; -EmailFields.defaultProps = editFieldDefaultProps; - GrafanaFields.propTypes = editFieldPropTypes; - -GrafanaFields.defaultProps = editFieldDefaultProps; -function IRCFields({ isEdit }) { +function IRCFields({ isEdit = false }) { const { t } = useLingui(); const helpText = { ircTargets: t`Use one IRC channel or username per line. The pound @@ -357,8 +340,6 @@ function IRCFields({ isEdit }) { IRCFields.propTypes = editFieldPropTypes; -IRCFields.defaultProps = editFieldDefaultProps; - function MattermostFields() { const { t } = useLingui(); return ( @@ -399,7 +380,7 @@ function MattermostFields() { ); } -function PagerdutyFields({ isEdit }) { +function PagerdutyFields({ isEdit = false }) { const { t } = useLingui(); return ( <> @@ -440,8 +421,6 @@ function PagerdutyFields({ isEdit }) { PagerdutyFields.propTypes = editFieldPropTypes; -PagerdutyFields.defaultProps = editFieldDefaultProps; - function RocketChatFields() { const { t } = useLingui(); return ( @@ -476,7 +455,7 @@ function RocketChatFields() { ); } -function SlackFields({ isEdit }) { +function SlackFields({ isEdit = false }) { const { t } = useLingui(); const helpText = useMemo(() => ({ slackChannels: ( @@ -523,9 +502,7 @@ function SlackFields({ isEdit }) { SlackFields.propTypes = editFieldPropTypes; -SlackFields.defaultProps = editFieldDefaultProps; - -function TwilioFields({ isEdit }) { +function TwilioFields({ isEdit = false }) { const { t } = useLingui(); const helpText = { twilioSourcePhoneNumber: t`The number associated with the "Messaging @@ -574,9 +551,7 @@ function TwilioFields({ isEdit }) { TwilioFields.propTypes = editFieldPropTypes; -TwilioFields.defaultProps = editFieldDefaultProps; - -function WebhookFields({ isEdit }) { +function WebhookFields({ isEdit = false }) { const { t } = useLingui(); const helpText = { webhookHeaders: t`Specify HTTP Headers in JSON format. Refer to @@ -652,5 +627,3 @@ function WebhookFields({ isEdit }) { } WebhookFields.propTypes = editFieldPropTypes; - -WebhookFields.defaultProps = editFieldDefaultProps; diff --git a/awx/ui/src/screens/Organization/shared/OrganizationForm.js b/awx/ui/src/screens/Organization/shared/OrganizationForm.js index 541b425af..c7fb5cde4 100644 --- a/awx/ui/src/screens/Organization/shared/OrganizationForm.js +++ b/awx/ui/src/screens/Organization/shared/OrganizationForm.js @@ -125,11 +125,17 @@ function OrganizationFormFields({ } function OrganizationForm({ - organization, + organization = { + id: '', + name: '', + description: '', + max_hosts: '0', + default_environment: '', + }, onCancel, onSubmit, - submitError, - defaultGalaxyCredential, + submitError = null, + defaultGalaxyCredential = null, ...rest }) { const [contentError, setContentError] = useState(null); @@ -225,17 +231,5 @@ OrganizationForm.propTypes = { submitError: PropTypes.shape(), }; -OrganizationForm.defaultProps = { - defaultGalaxyCredential: null, - organization: { - id: '', - name: '', - description: '', - max_hosts: '0', - default_environment: '', - }, - submitError: null, -}; - export { OrganizationForm as _OrganizationForm }; export default OrganizationForm; diff --git a/awx/ui/src/screens/Project/shared/ProjectForm.js b/awx/ui/src/screens/Project/shared/ProjectForm.js index 862c77c47..a748301ba 100644 --- a/awx/ui/src/screens/Project/shared/ProjectForm.js +++ b/awx/ui/src/screens/Project/shared/ProjectForm.js @@ -340,7 +340,7 @@ function ProjectFormFields({ ); } -function ProjectForm({ project, submitError, ...props }) { +function ProjectForm({ project = {}, submitError = null, ...props }) { const { handleCancel, handleSubmit } = props; const { summary_fields = {} } = project; const { project_base_dir, project_local_paths } = useConfig(); @@ -483,9 +483,4 @@ ProjectForm.propTypes = { submitError: PropTypes.shape({}), }; -ProjectForm.defaultProps = { - project: {}, - submitError: null, -}; - export default ProjectForm; diff --git a/awx/ui/src/screens/Setting/shared/SharedFields.js b/awx/ui/src/screens/Setting/shared/SharedFields.js index e8edfb077..7399d769c 100644 --- a/awx/ui/src/screens/Setting/shared/SharedFields.js +++ b/awx/ui/src/screens/Setting/shared/SharedFields.js @@ -372,7 +372,12 @@ InputAlertField.propTypes = { config: shape({}).isRequired, }; -const InputField = ({ name, config, type = 'text', isRequired = false }) => { +const InputField = ({ + name, + config = null, + type = 'text', + isRequired = false, +}) => { const { t } = useLingui(); const min_value = config?.min_value ?? Number.MIN_SAFE_INTEGER; const max_value = config?.max_value ?? Number.MAX_SAFE_INTEGER; @@ -414,9 +419,6 @@ InputField.propTypes = { name: string.isRequired, config: shape({}), }; -InputField.defaultProps = { - config: null, -}; const TextAreaField = ({ name, config, isRequired = false }) => { const { t } = useLingui(); diff --git a/awx/ui/src/screens/Team/shared/TeamForm.js b/awx/ui/src/screens/Team/shared/TeamForm.js index 30b81c71f..16111ff7e 100644 --- a/awx/ui/src/screens/Team/shared/TeamForm.js +++ b/awx/ui/src/screens/Team/shared/TeamForm.js @@ -53,9 +53,13 @@ function TeamFormFields({ team }) { ); } -function TeamForm(props) { - const { team, handleCancel, handleSubmit, submitError, ...rest } = props; - +function TeamForm({ + team = {}, + handleCancel, + handleSubmit, + submitError = null, + ...rest +}) { return ( {}, readOnly, updateHelpText, updateNodeHelp, @@ -395,8 +395,4 @@ VisualizerNode.propTypes = { updateNodeHelp: func.isRequired, }; -VisualizerNode.defaultProps = { - onMouseOver: () => {}, -}; - export default VisualizerNode; diff --git a/awx/ui/src/screens/Template/shared/JobTemplateForm.js b/awx/ui/src/screens/Template/shared/JobTemplateForm.js index 51f9a4e58..384d8b49b 100644 --- a/awx/ui/src/screens/Template/shared/JobTemplateForm.js +++ b/awx/ui/src/screens/Template/shared/JobTemplateForm.js @@ -50,15 +50,34 @@ import getHelpText from './JobTemplate.helptext'; const { origin } = document.location; +// Stable default so it doesn't change identity each render (it feeds a +// useCallback dependency below); previously this lived in defaultProps. +const defaultTemplate = { + name: '', + description: '', + job_type: 'run', + inventory: undefined, + project: undefined, + playbook: '', + scm_branch: '', + summary_fields: { + inventory: null, + labels: { results: [] }, + project: null, + credentials: [], + }, + isNew: true, +}; + function JobTemplateForm({ - template, + template = defaultTemplate, handleCancel, handleSubmit, setFieldValue, setFieldTouched, - submitError, + submitError = null, validateField, - isOverrideDisabledLookup, // TODO: this is a confusing variable name + isOverrideDisabledLookup = false, // TODO: this is a confusing variable name }) { const { t } = useLingui(); const helpText = getHelpText(t); @@ -670,27 +689,6 @@ JobTemplateForm.propTypes = { isOverrideDisabledLookup: PropTypes.bool, }; -JobTemplateForm.defaultProps = { - template: { - name: '', - description: '', - job_type: 'run', - inventory: undefined, - project: undefined, - playbook: '', - scm_branch: '', - summary_fields: { - inventory: null, - labels: { results: [] }, - project: null, - credentials: [], - }, - isNew: true, - }, - submitError: null, - isOverrideDisabledLookup: false, -}; - const FormikApp = withFormik({ mapPropsToValues({ resourceValues = null, template = {} }) { const { diff --git a/awx/ui/src/screens/Template/shared/PlaybookSelect.js b/awx/ui/src/screens/Template/shared/PlaybookSelect.js index 2aa087619..2bb55794d 100644 --- a/awx/ui/src/screens/Template/shared/PlaybookSelect.js +++ b/awx/ui/src/screens/Template/shared/PlaybookSelect.js @@ -6,13 +6,15 @@ import { SelectVariant, Select, SelectOption } from '@patternfly/react-core'; import { ProjectsAPI } from 'api'; import useRequest from 'hooks/useRequest'; +const noop = () => {}; + function PlaybookSelect({ - projectId, + projectId = null, isValid, selected, onBlur, onError, - onChange, + onChange = noop, }) { const { t } = useLingui(); const [isDisabled, setIsDisabled] = useState(false); @@ -83,10 +85,5 @@ PlaybookSelect.propTypes = { projectId: oneOfType([number, string]), onChange: func, }; -PlaybookSelect.defaultProps = { - projectId: null, - onChange: () => {}, -}; - export { PlaybookSelect as _PlaybookSelect }; export default PlaybookSelect; diff --git a/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js b/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js index de956e43f..4f7221101 100644 --- a/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js +++ b/awx/ui/src/screens/Template/shared/WorkflowJobTemplateForm.js @@ -34,12 +34,17 @@ import getHelpText from './WorkflowJobTemplate.helptext'; const urlOrigin = window.location.origin; function WorkflowJobTemplateForm({ - template, + template = { + name: '', + description: '', + inventory: undefined, + project: undefined, + }, handleSubmit, handleCancel, - submitError, - isOrgAdmin, - isInventoryDisabled, + submitError = null, + isOrgAdmin = false, + isInventoryDisabled = false, }) { const { t } = useLingui(); const helpText = getHelpText(t); @@ -292,18 +297,6 @@ WorkflowJobTemplateForm.propTypes = { isInventoryDisabled: PropTypes.bool, }; -WorkflowJobTemplateForm.defaultProps = { - submitError: null, - template: { - name: '', - description: '', - inventory: undefined, - project: undefined, - }, - isOrgAdmin: false, - isInventoryDisabled: false, -}; - const FormikApp = withFormik({ mapPropsToValues({ template = {} }) { return { diff --git a/awx/ui/src/screens/User/shared/UserForm.js b/awx/ui/src/screens/User/shared/UserForm.js index 964c4e293..7b8462977 100644 --- a/awx/ui/src/screens/User/shared/UserForm.js +++ b/awx/ui/src/screens/User/shared/UserForm.js @@ -167,7 +167,7 @@ function UserFormFields({ user }) { ); } -function UserForm({ user, handleCancel, handleSubmit, submitError }) { +function UserForm({ user = {}, handleCancel, handleSubmit, submitError }) { const { t } = useLingui(); const handleValidateAndSubmit = (values, { setErrors }) => { if (values.password !== values.confirm_password) { @@ -234,8 +234,4 @@ UserForm.propTypes = { user: PropTypes.shape({}), }; -UserForm.defaultProps = { - user: {}, -}; - export default UserForm; diff --git a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js index 1eb6fd41d..8cbd82964 100644 --- a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js +++ b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalDetail/WorkflowApprovalDetail.js @@ -20,7 +20,6 @@ import { VariablesDetail } from 'components/CodeEditor'; import { formatDateString, secondsToHHMMSS } from 'util/dates'; import { WorkflowApprovalsAPI, WorkflowJobsAPI } from 'api'; import useRequest, { useDismissableError } from 'hooks/useRequest'; -import { WorkflowApproval } from 'types'; import StatusLabel from 'components/StatusLabel'; import JobCancelButton from 'components/JobCancelButton'; import useToast, { AlertVariant } from 'hooks/useToast'; @@ -338,8 +337,4 @@ function WorkflowApprovalDetail({ workflowApproval, fetchWorkflowApproval }) { ); } -WorkflowApprovalDetail.defaultProps = { - workflowApproval: WorkflowApproval.isRequired, -}; - export default WorkflowApprovalDetail; diff --git a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListApproveButton.js b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListApproveButton.js index fb638f6c7..d0daad94c 100644 --- a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListApproveButton.js +++ b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListApproveButton.js @@ -10,7 +10,7 @@ function cannotApprove(item) { return !item.can_approve_or_deny; } -function WorkflowApprovalListApproveButton({ onApprove, selectedItems }) { +function WorkflowApprovalListApproveButton({ onApprove, selectedItems = [] }) { const { t } = useLingui(); const { isKebabified } = useContext(KebabifiedContext); @@ -70,8 +70,4 @@ WorkflowApprovalListApproveButton.propTypes = { selectedItems: PropTypes.arrayOf(WorkflowApproval), }; -WorkflowApprovalListApproveButton.defaultProps = { - selectedItems: [], -}; - export default WorkflowApprovalListApproveButton; diff --git a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListDenyButton.js b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListDenyButton.js index 00cef2cfa..5f7684a3d 100644 --- a/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListDenyButton.js +++ b/awx/ui/src/screens/WorkflowApproval/WorkflowApprovalList/WorkflowApprovalListDenyButton.js @@ -9,7 +9,7 @@ function cannotDeny(item) { return !item.can_approve_or_deny; } -function WorkflowApprovalListDenyButton({ onDeny, selectedItems }) { +function WorkflowApprovalListDenyButton({ onDeny, selectedItems = [] }) { const { t } = useLingui(); const { isKebabified } = useContext(KebabifiedContext); @@ -69,8 +69,4 @@ WorkflowApprovalListDenyButton.propTypes = { selectedItems: PropTypes.arrayOf(WorkflowApproval), }; -WorkflowApprovalListDenyButton.defaultProps = { - selectedItems: [], -}; - export default WorkflowApprovalListDenyButton;