diff --git a/frontend/src/App/AppRoutes.js b/frontend/src/App/AppRoutes.js index bf08d82b1..0df7d2a49 100644 --- a/frontend/src/App/AppRoutes.js +++ b/frontend/src/App/AppRoutes.js @@ -4,7 +4,7 @@ import { Redirect, Route } from 'react-router-dom'; import NotFound from 'Components/NotFound'; import Switch from 'Components/Router/Switch'; import HistoryConnector from 'History/HistoryConnector'; -import IndexerIndexConnector from 'Indexer/Index/IndexerIndexConnector'; +import IndexerIndex from 'Indexer/Index/IndexerIndex'; import StatsConnector from 'Indexer/Stats/StatsConnector'; import SearchIndexConnector from 'Search/SearchIndexConnector'; import ApplicationSettingsConnector from 'Settings/Applications/ApplicationSettingsConnector'; @@ -38,7 +38,7 @@ function AppRoutes(props) { { diff --git a/frontend/src/App/AppUpdatedModalContent.css.d.ts b/frontend/src/App/AppUpdatedModalContent.css.d.ts new file mode 100644 index 000000000..70ddbf6a1 --- /dev/null +++ b/frontend/src/App/AppUpdatedModalContent.css.d.ts @@ -0,0 +1,9 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'changes': string; + 'maintenance': string; + 'version': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/App/ConnectionLostModal.css.d.ts b/frontend/src/App/ConnectionLostModal.css.d.ts new file mode 100644 index 000000000..027f2a9a3 --- /dev/null +++ b/frontend/src/App/ConnectionLostModal.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'automatic': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/App/ModelBase.ts b/frontend/src/App/ModelBase.ts new file mode 100644 index 000000000..187b12fb2 --- /dev/null +++ b/frontend/src/App/ModelBase.ts @@ -0,0 +1,5 @@ +interface ModelBase { + id: number; +} + +export default ModelBase; diff --git a/frontend/src/App/SelectContext.tsx b/frontend/src/App/SelectContext.tsx new file mode 100644 index 000000000..6980129c1 --- /dev/null +++ b/frontend/src/App/SelectContext.tsx @@ -0,0 +1,163 @@ +import { cloneDeep } from 'lodash'; +import React, { useEffect } from 'react'; +import areAllSelected from 'Utilities/Table/areAllSelected'; +import selectAll from 'Utilities/Table/selectAll'; +import toggleSelected from 'Utilities/Table/toggleSelected'; +import ModelBase from './ModelBase'; + +export enum SelectActionType { + Reset, + SelectAll, + UnselectAll, + ToggleSelected, + RemoveItem, + UpdateItems, +} + +type SelectedState = Record; + +interface SelectState { + selectedState: SelectedState; + lastToggled: number | null; + allSelected: boolean; + allUnselected: boolean; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + items: any[]; +} + +type SelectAction = + | { type: SelectActionType.Reset } + | { type: SelectActionType.SelectAll } + | { type: SelectActionType.UnselectAll } + | { + type: SelectActionType.ToggleSelected; + id: number; + isSelected: boolean; + shiftKey: boolean; + } + | { + type: SelectActionType.RemoveItem; + id: number; + } + | { + type: SelectActionType.UpdateItems; + items: ModelBase[]; + }; + +type Dispatch = (action: SelectAction) => void; + +const initialState = { + selectedState: {}, + lastToggled: null, + allSelected: false, + allUnselected: true, + items: [], +}; + +interface SelectProviderOptions { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + children: any; + items: Array; +} + +function getSelectedState(items: ModelBase[], existingState: SelectedState) { + return items.reduce((acc: SelectedState, item) => { + const id = item.id; + + acc[id] = existingState[id] ?? false; + + return acc; + }, {}); +} + +// TODO: Can this be reused? + +const SelectContext = React.createContext<[SelectState, Dispatch] | undefined>( + cloneDeep(undefined) +); + +function selectReducer(state: SelectState, action: SelectAction): SelectState { + const { items, selectedState } = state; + + switch (action.type) { + case SelectActionType.Reset: { + return cloneDeep(initialState); + } + case SelectActionType.SelectAll: { + return { + items, + ...selectAll(selectedState, true), + }; + } + case SelectActionType.UnselectAll: { + return { + items, + ...selectAll(selectedState, false), + }; + } + case SelectActionType.ToggleSelected: { + const result = { + items, + ...toggleSelected( + state, + items, + action.id, + action.isSelected, + action.shiftKey + ), + }; + + return result; + } + case SelectActionType.UpdateItems: { + const nextSelectedState = getSelectedState(action.items, selectedState); + + return { + ...state, + ...areAllSelected(nextSelectedState), + selectedState: nextSelectedState, + items: action.items, + }; + } + default: { + throw new Error(`Unhandled action type: ${action.type}`); + } + } +} + +export function SelectProvider( + props: SelectProviderOptions +) { + const { items } = props; + const selectedState = getSelectedState(items, {}); + + const [state, dispatch] = React.useReducer(selectReducer, { + selectedState, + lastToggled: null, + allSelected: false, + allUnselected: true, + items, + }); + + const value: [SelectState, Dispatch] = [state, dispatch]; + + useEffect(() => { + dispatch({ type: SelectActionType.UpdateItems, items }); + }, [items]); + + return ( + + {props.children} + + ); +} + +export function useSelect() { + const context = React.useContext(SelectContext); + + if (context === undefined) { + throw new Error('useSelect must be used within a SelectProvider'); + } + + return context; +} diff --git a/frontend/src/Components/Alert.css.d.ts b/frontend/src/Components/Alert.css.d.ts new file mode 100644 index 000000000..daffec2e6 --- /dev/null +++ b/frontend/src/Components/Alert.css.d.ts @@ -0,0 +1,11 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'alert': string; + 'danger': string; + 'info': string; + 'success': string; + 'warning': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Alert.js b/frontend/src/Components/Alert.js index 10f124c78..418cbf5e6 100644 --- a/frontend/src/Components/Alert.js +++ b/frontend/src/Components/Alert.js @@ -4,7 +4,9 @@ import React from 'react'; import { kinds } from 'Helpers/Props'; import styles from './Alert.css'; -function Alert({ className, kind, children, ...otherProps }) { +function Alert(props) { + const { className, kind, children, ...otherProps } = props; + return (
-
- {message} -
- -
- -
- -
- { - error && -
- {error.toString()} -
- } - -
- {info.componentStack} -
-
-
- ); -} - -ErrorBoundaryError.propTypes = { - className: PropTypes.string.isRequired, - messageClassName: PropTypes.string.isRequired, - detailsClassName: PropTypes.string.isRequired, - message: PropTypes.string.isRequired, - error: PropTypes.object.isRequired, - info: PropTypes.object.isRequired -}; - -ErrorBoundaryError.defaultProps = { - className: styles.container, - messageClassName: styles.message, - detailsClassName: styles.details, - message: 'There was an error loading this content' -}; - -export default ErrorBoundaryError; diff --git a/frontend/src/Components/Error/ErrorBoundaryError.tsx b/frontend/src/Components/Error/ErrorBoundaryError.tsx new file mode 100644 index 000000000..b3db237b1 --- /dev/null +++ b/frontend/src/Components/Error/ErrorBoundaryError.tsx @@ -0,0 +1,74 @@ +import React, { useEffect, useState } from 'react'; +import StackTrace from 'stacktrace-js'; +import styles from './ErrorBoundaryError.css'; + +interface ErrorBoundaryErrorProps { + className: string; + messageClassName: string; + detailsClassName: string; + message: string; + error: Error; + info: { + componentStack: string; + }; +} + +function ErrorBoundaryError(props: ErrorBoundaryErrorProps) { + const { + className = styles.container, + messageClassName = styles.message, + detailsClassName = styles.details, + message = 'There was an error loading this content', + error, + info, + } = props; + + const [detailedError, setDetailedError] = useState(null); + + useEffect(() => { + if (error) { + StackTrace.fromError(error).then((de) => { + setDetailedError(de); + }); + } else { + setDetailedError(null); + } + }, [error, setDetailedError]); + + return ( +
+
{message}
+ +
+ +
+ +
+ {error ?
{error.message}
: null} + + {detailedError ? ( + detailedError.map((d, index) => { + return ( +
+ {` at ${d.functionName} (${d.fileName}:${d.lineNumber}:${d.columnNumber})`} +
+ ); + }) + ) : ( +
{info.componentStack}
+ )} + + { +
+ Version: {window.Prowlarr.version} +
+ } +
+
+ ); +} + +export default ErrorBoundaryError; diff --git a/frontend/src/Components/FieldSet.css.d.ts b/frontend/src/Components/FieldSet.css.d.ts new file mode 100644 index 000000000..b669ac6d0 --- /dev/null +++ b/frontend/src/Components/FieldSet.css.d.ts @@ -0,0 +1,8 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'fieldSet': string; + 'legend': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/FileBrowser/FileBrowserModal.css.d.ts b/frontend/src/Components/FileBrowser/FileBrowserModal.css.d.ts new file mode 100644 index 000000000..5d00cca7e --- /dev/null +++ b/frontend/src/Components/FileBrowser/FileBrowserModal.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'modal': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/FileBrowser/FileBrowserModalContent.css.d.ts b/frontend/src/Components/FileBrowser/FileBrowserModalContent.css.d.ts new file mode 100644 index 000000000..e83c13075 --- /dev/null +++ b/frontend/src/Components/FileBrowser/FileBrowserModalContent.css.d.ts @@ -0,0 +1,12 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'faqLink': string; + 'loading': string; + 'mappedDrivesWarning': string; + 'modalBody': string; + 'pathInput': string; + 'scroller': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/FileBrowser/FileBrowserRow.css.d.ts b/frontend/src/Components/FileBrowser/FileBrowserRow.css.d.ts new file mode 100644 index 000000000..127d00928 --- /dev/null +++ b/frontend/src/Components/FileBrowser/FileBrowserRow.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'type': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Filter/Builder/DateFilterBuilderRowValue.css.d.ts b/frontend/src/Components/Filter/Builder/DateFilterBuilderRowValue.css.d.ts new file mode 100644 index 000000000..d391a1f30 --- /dev/null +++ b/frontend/src/Components/Filter/Builder/DateFilterBuilderRowValue.css.d.ts @@ -0,0 +1,9 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'container': string; + 'numberInput': string; + 'selectInput': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Filter/Builder/FilterBuilderModalContent.css.d.ts b/frontend/src/Components/Filter/Builder/FilterBuilderModalContent.css.d.ts new file mode 100644 index 000000000..033d2edca --- /dev/null +++ b/frontend/src/Components/Filter/Builder/FilterBuilderModalContent.css.d.ts @@ -0,0 +1,10 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'label': string; + 'labelContainer': string; + 'labelInputContainer': string; + 'rows': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Filter/Builder/FilterBuilderRow.css.d.ts b/frontend/src/Components/Filter/Builder/FilterBuilderRow.css.d.ts new file mode 100644 index 000000000..aba698af4 --- /dev/null +++ b/frontend/src/Components/Filter/Builder/FilterBuilderRow.css.d.ts @@ -0,0 +1,10 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'actionsContainer': string; + 'filterRow': string; + 'inputContainer': string; + 'valueInputContainer': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Filter/Builder/FilterBuilderRowValueTag.css.d.ts b/frontend/src/Components/Filter/Builder/FilterBuilderRowValueTag.css.d.ts new file mode 100644 index 000000000..80bcf1464 --- /dev/null +++ b/frontend/src/Components/Filter/Builder/FilterBuilderRowValueTag.css.d.ts @@ -0,0 +1,10 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'isLastTag': string; + 'label': string; + 'or': string; + 'tag': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Filter/CustomFilters/CustomFilter.css.d.ts b/frontend/src/Components/Filter/CustomFilters/CustomFilter.css.d.ts new file mode 100644 index 000000000..af5bfa967 --- /dev/null +++ b/frontend/src/Components/Filter/CustomFilters/CustomFilter.css.d.ts @@ -0,0 +1,9 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'actions': string; + 'customFilter': string; + 'label': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Filter/CustomFilters/CustomFiltersModalContent.css.d.ts b/frontend/src/Components/Filter/CustomFilters/CustomFiltersModalContent.css.d.ts new file mode 100644 index 000000000..b505d0767 --- /dev/null +++ b/frontend/src/Components/Filter/CustomFilters/CustomFiltersModalContent.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'addButtonContainer': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/AutoSuggestInput.css.d.ts b/frontend/src/Components/Form/AutoSuggestInput.css.d.ts new file mode 100644 index 000000000..2b8f51924 --- /dev/null +++ b/frontend/src/Components/Form/AutoSuggestInput.css.d.ts @@ -0,0 +1,15 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'hasError': string; + 'hasWarning': string; + 'input': string; + 'inputContainer': string; + 'suggestion': string; + 'suggestionHighlighted': string; + 'suggestionsContainer': string; + 'suggestionsContainerOpen': string; + 'suggestionsList': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/CaptchaInput.css.d.ts b/frontend/src/Components/Form/CaptchaInput.css.d.ts new file mode 100644 index 000000000..b6844144e --- /dev/null +++ b/frontend/src/Components/Form/CaptchaInput.css.d.ts @@ -0,0 +1,12 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'captchaInputWrapper': string; + 'hasButton': string; + 'hasError': string; + 'hasWarning': string; + 'input': string; + 'recaptchaWrapper': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/CheckInput.css.d.ts b/frontend/src/Components/Form/CheckInput.css.d.ts new file mode 100644 index 000000000..bba6b63bb --- /dev/null +++ b/frontend/src/Components/Form/CheckInput.css.d.ts @@ -0,0 +1,18 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'checkbox': string; + 'container': string; + 'dangerIsChecked': string; + 'helpText': string; + 'input': string; + 'isDisabled': string; + 'isIndeterminate': string; + 'isNotChecked': string; + 'label': string; + 'primaryIsChecked': string; + 'successIsChecked': string; + 'warningIsChecked': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/DeviceInput.css.d.ts b/frontend/src/Components/Form/DeviceInput.css.d.ts new file mode 100644 index 000000000..e44e3fce0 --- /dev/null +++ b/frontend/src/Components/Form/DeviceInput.css.d.ts @@ -0,0 +1,8 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'deviceInputWrapper': string; + 'input': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/EnhancedSelectInput.css.d.ts b/frontend/src/Components/Form/EnhancedSelectInput.css.d.ts new file mode 100644 index 000000000..edcf0079b --- /dev/null +++ b/frontend/src/Components/Form/EnhancedSelectInput.css.d.ts @@ -0,0 +1,22 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'dropdownArrowContainer': string; + 'dropdownArrowContainerDisabled': string; + 'dropdownArrowContainerEditable': string; + 'editableContainer': string; + 'enhancedSelect': string; + 'hasError': string; + 'hasWarning': string; + 'isDisabled': string; + 'loading': string; + 'mobileCloseButton': string; + 'mobileCloseButtonContainer': string; + 'options': string; + 'optionsContainer': string; + 'optionsModal': string; + 'optionsModalBody': string; + 'optionsModalScroller': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/EnhancedSelectInput.js b/frontend/src/Components/Form/EnhancedSelectInput.js index fd8e48b9b..4df54092c 100644 --- a/frontend/src/Components/Form/EnhancedSelectInput.js +++ b/frontend/src/Components/Form/EnhancedSelectInput.js @@ -12,9 +12,9 @@ import ModalBody from 'Components/Modal/ModalBody'; import Portal from 'Components/Portal'; import Scroller from 'Components/Scroller/Scroller'; import { icons, scrollDirections, sizes } from 'Helpers/Props'; +import { isMobile as isMobileUtil } from 'Utilities/browser'; import * as keyCodes from 'Utilities/Constants/keyCodes'; import getUniqueElememtId from 'Utilities/getUniqueElementId'; -import { isMobile as isMobileUtil } from 'Utilities/mobile'; import HintedSelectInputOption from './HintedSelectInputOption'; import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue'; import TextInput from './TextInput'; @@ -113,10 +113,12 @@ class EnhancedSelectInput extends Component { this._scheduleUpdate(); } - if (!Array.isArray(this.props.value) && prevProps.value !== this.props.value) { - this.setState({ - selectedIndex: getSelectedIndex(this.props) - }); + if (!Array.isArray(this.props.value)) { + if (prevProps.value !== this.props.value || prevProps.values !== this.props.values) { + this.setState({ + selectedIndex: getSelectedIndex(this.props) + }); + } } } @@ -332,6 +334,11 @@ class EnhancedSelectInput extends Component { const isMultiSelect = Array.isArray(value); const selectedOption = getSelectedOption(selectedIndex, values); + let selectedValue = value; + + if (!values.length) { + selectedValue = isMultiSelect ? [] : ''; + } return (
@@ -372,15 +379,17 @@ class EnhancedSelectInput extends Component { onPress={this.onPress} > { - isFetching && + isFetching ? + /> : + null } { - !isFetching && + isFetching ? + null : @@ -400,7 +409,7 @@ class EnhancedSelectInput extends Component { onPress={this.onPress} > { - isFetching && + isFetching ? + /> : + null } { - !isFetching && + isFetching ? + null : @@ -505,7 +516,7 @@ class EnhancedSelectInput extends Component { { - isMobile && + isMobile ? - + : + null }
); diff --git a/frontend/src/Components/Form/EnhancedSelectInputOption.css.d.ts b/frontend/src/Components/Form/EnhancedSelectInputOption.css.d.ts new file mode 100644 index 000000000..59675cd91 --- /dev/null +++ b/frontend/src/Components/Form/EnhancedSelectInputOption.css.d.ts @@ -0,0 +1,14 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'iconContainer': string; + 'isDisabled': string; + 'isHidden': string; + 'isMobile': string; + 'isSelected': string; + 'option': string; + 'optionCheck': string; + 'optionCheckInput': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/EnhancedSelectInputSelectedValue.css.d.ts b/frontend/src/Components/Form/EnhancedSelectInputSelectedValue.css.d.ts new file mode 100644 index 000000000..5377239a8 --- /dev/null +++ b/frontend/src/Components/Form/EnhancedSelectInputSelectedValue.css.d.ts @@ -0,0 +1,8 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'isDisabled': string; + 'selectedValue': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/Form.css.d.ts b/frontend/src/Components/Form/Form.css.d.ts new file mode 100644 index 000000000..178f2fec1 --- /dev/null +++ b/frontend/src/Components/Form/Form.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'validationFailures': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/FormGroup.css.d.ts b/frontend/src/Components/Form/FormGroup.css.d.ts new file mode 100644 index 000000000..86145f643 --- /dev/null +++ b/frontend/src/Components/Form/FormGroup.css.d.ts @@ -0,0 +1,11 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'extraSmall': string; + 'group': string; + 'large': string; + 'medium': string; + 'small': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/FormInputButton.css.d.ts b/frontend/src/Components/Form/FormInputButton.css.d.ts new file mode 100644 index 000000000..d469cdfe3 --- /dev/null +++ b/frontend/src/Components/Form/FormInputButton.css.d.ts @@ -0,0 +1,8 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'button': string; + 'middleButton': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/FormInputGroup.css.d.ts b/frontend/src/Components/Form/FormInputGroup.css.d.ts new file mode 100644 index 000000000..267257c44 --- /dev/null +++ b/frontend/src/Components/Form/FormInputGroup.css.d.ts @@ -0,0 +1,14 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'helpLink': string; + 'inputContainer': string; + 'inputGroup': string; + 'inputGroupContainer': string; + 'inputUnit': string; + 'inputUnitNumber': string; + 'pendingChangesContainer': string; + 'pendingChangesIcon': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/FormInputGroup.js b/frontend/src/Components/Form/FormInputGroup.js index 8e39cd36a..f25946f59 100644 --- a/frontend/src/Components/Form/FormInputGroup.js +++ b/frontend/src/Components/Form/FormInputGroup.js @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import Link from 'Components/Link/Link'; -import { inputTypes } from 'Helpers/Props'; +import { inputTypes, kinds } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; import AppProfileSelectInputConnector from './AppProfileSelectInputConnector'; import AutoCompleteInput from './AutoCompleteInput'; @@ -253,16 +253,24 @@ FormInputGroup.propTypes = { className: PropTypes.string.isRequired, containerClassName: PropTypes.string.isRequired, inputClassName: PropTypes.string, + name: PropTypes.string.isRequired, + value: PropTypes.any, + values: PropTypes.arrayOf(PropTypes.any), type: PropTypes.string.isRequired, + kind: PropTypes.oneOf(kinds.all), unit: PropTypes.string, buttons: PropTypes.oneOfType([PropTypes.node, PropTypes.arrayOf(PropTypes.node)]), helpText: PropTypes.string, helpTexts: PropTypes.arrayOf(PropTypes.string), helpTextWarning: PropTypes.string, helpLink: PropTypes.string, + includeNoChange: PropTypes.bool, + includeNoChangeDisabled: PropTypes.bool, + selectedValueOptions: PropTypes.object, pending: PropTypes.bool, errors: PropTypes.arrayOf(PropTypes.object), - warnings: PropTypes.arrayOf(PropTypes.object) + warnings: PropTypes.arrayOf(PropTypes.object), + onChange: PropTypes.func.isRequired }; FormInputGroup.defaultProps = { diff --git a/frontend/src/Components/Form/FormInputHelpText.css.d.ts b/frontend/src/Components/Form/FormInputHelpText.css.d.ts new file mode 100644 index 000000000..0e163f134 --- /dev/null +++ b/frontend/src/Components/Form/FormInputHelpText.css.d.ts @@ -0,0 +1,12 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'details': string; + 'helpText': string; + 'isCheckInput': string; + 'isError': string; + 'isWarning': string; + 'link': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/FormLabel.css.d.ts b/frontend/src/Components/Form/FormLabel.css.d.ts new file mode 100644 index 000000000..c23dd30a4 --- /dev/null +++ b/frontend/src/Components/Form/FormLabel.css.d.ts @@ -0,0 +1,11 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'hasError': string; + 'isAdvanced': string; + 'label': string; + 'large': string; + 'small': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Components/Form/FormLabel.js b/frontend/src/Components/Form/FormLabel.js index d419039b3..d4a4bcffc 100644 --- a/frontend/src/Components/Form/FormLabel.js +++ b/frontend/src/Components/Form/FormLabel.js @@ -4,16 +4,18 @@ import React from 'react'; import { sizes } from 'Helpers/Props'; import styles from './FormLabel.css'; -function FormLabel({ - children, - className, - errorClassName, - size, - name, - hasError, - isAdvanced, - ...otherProps -}) { +function FormLabel(props) { + const { + children, + className, + errorClassName, + size, + name, + hasError, + isAdvanced, + ...otherProps + } = props; + return (