mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
Fixed: Backend Updates from Sonarr
Co-Authored-By: Mark McDowall <markus101@users.noreply.github.com> Co-Authored-By: taloth <taloth@users.noreply.github.com>
This commit is contained in:
@@ -2,13 +2,13 @@ import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { fetchDevices, clearDevices } from 'Store/Actions/deviceActions';
|
||||
import { fetchOptions, clearOptions } from 'Store/Actions/providerOptionActions';
|
||||
import DeviceInput from './DeviceInput';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state, { value }) => value,
|
||||
(state) => state.devices,
|
||||
(state) => state.providerOptions,
|
||||
(value, devices) => {
|
||||
|
||||
return {
|
||||
@@ -37,8 +37,8 @@ function createMapStateToProps() {
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchFetchDevices: fetchDevices,
|
||||
dispatchClearDevices: clearDevices
|
||||
dispatchFetchOptions: fetchOptions,
|
||||
dispatchClearOptions: clearOptions
|
||||
};
|
||||
|
||||
class DeviceInputConnector extends Component {
|
||||
@@ -51,7 +51,7 @@ class DeviceInputConnector extends Component {
|
||||
}
|
||||
|
||||
componentWillUnmount = () => {
|
||||
// this.props.dispatchClearDevices();
|
||||
this.props.dispatchClearOptions();
|
||||
}
|
||||
|
||||
//
|
||||
@@ -61,10 +61,14 @@ class DeviceInputConnector extends Component {
|
||||
const {
|
||||
provider,
|
||||
providerData,
|
||||
dispatchFetchDevices
|
||||
dispatchFetchOptions
|
||||
} = this.props;
|
||||
|
||||
dispatchFetchDevices({ provider, providerData });
|
||||
dispatchFetchOptions({
|
||||
action: 'getDevices',
|
||||
provider,
|
||||
providerData
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
@@ -92,8 +96,8 @@ DeviceInputConnector.propTypes = {
|
||||
providerData: PropTypes.object.isRequired,
|
||||
name: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
dispatchFetchDevices: PropTypes.func.isRequired,
|
||||
dispatchClearDevices: PropTypes.func.isRequired
|
||||
dispatchFetchOptions: PropTypes.func.isRequired,
|
||||
dispatchClearOptions: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(DeviceInputConnector);
|
||||
|
@@ -6,7 +6,7 @@ import classNames from 'classnames';
|
||||
import getUniqueElememtId from 'Utilities/getUniqueElementId';
|
||||
import isMobileUtil from 'Utilities/isMobile';
|
||||
import * as keyCodes from 'Utilities/Constants/keyCodes';
|
||||
import { icons, scrollDirections } from 'Helpers/Props';
|
||||
import { icons, sizes, scrollDirections } from 'Helpers/Props';
|
||||
import Icon from 'Components/Icon';
|
||||
import Portal from 'Components/Portal';
|
||||
import Link from 'Components/Link/Link';
|
||||
@@ -14,8 +14,8 @@ import Measure from 'Components/Measure';
|
||||
import Modal from 'Components/Modal/Modal';
|
||||
import ModalBody from 'Components/Modal/ModalBody';
|
||||
import Scroller from 'Components/Scroller/Scroller';
|
||||
import EnhancedSelectInputSelectedValue from './EnhancedSelectInputSelectedValue';
|
||||
import EnhancedSelectInputOption from './EnhancedSelectInputOption';
|
||||
import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue';
|
||||
import HintedSelectInputOption from './HintedSelectInputOption';
|
||||
import styles from './EnhancedSelectInput.css';
|
||||
|
||||
function isArrowKey(keyCode) {
|
||||
@@ -150,9 +150,11 @@ class EnhancedSelectInput extends Component {
|
||||
}
|
||||
|
||||
onBlur = () => {
|
||||
this.setState({
|
||||
selectedIndex: getSelectedIndex(this.props)
|
||||
});
|
||||
// Calling setState without this check prevents the click event from being properly handled on Chrome (it is on firefox)
|
||||
const origIndex = getSelectedIndex(this.props);
|
||||
if (origIndex !== this.state.selectedIndex) {
|
||||
this.setState({ selectedIndex: origIndex });
|
||||
}
|
||||
}
|
||||
|
||||
onKeyDown = (event) => {
|
||||
@@ -385,6 +387,7 @@ class EnhancedSelectInput extends Component {
|
||||
isMobile &&
|
||||
<Modal
|
||||
className={styles.optionsModal}
|
||||
size={sizes.EXTRA_SMALL}
|
||||
isOpen={isOpen}
|
||||
onModalClose={this.onOptionsModalClose}
|
||||
>
|
||||
@@ -439,8 +442,8 @@ EnhancedSelectInput.defaultProps = {
|
||||
disabledClassName: styles.isDisabled,
|
||||
isDisabled: false,
|
||||
selectedValueOptions: {},
|
||||
selectedValueComponent: EnhancedSelectInputSelectedValue,
|
||||
optionComponent: EnhancedSelectInputOption
|
||||
selectedValueComponent: HintedSelectInputSelectedValue,
|
||||
optionComponent: HintedSelectInputOption
|
||||
};
|
||||
|
||||
export default EnhancedSelectInput;
|
||||
|
@@ -7,13 +7,17 @@
|
||||
cursor: default;
|
||||
|
||||
&:hover {
|
||||
background-color: #f9f9f9;
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
|
||||
.isSelected {
|
||||
background-color: #e2e2e2;
|
||||
|
||||
&:hover {
|
||||
background-color: #e2e2e2;
|
||||
}
|
||||
|
||||
&.isMobile {
|
||||
background-color: inherit;
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
.inputGroupContainer {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.inputGroup {
|
||||
@@ -11,6 +12,7 @@
|
||||
.inputContainer {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.inputUnit {
|
||||
|
@@ -14,7 +14,7 @@ import PathInputConnector from './PathInputConnector';
|
||||
import QualityProfileSelectInputConnector from './QualityProfileSelectInputConnector';
|
||||
import RootFolderSelectInputConnector from './RootFolderSelectInputConnector';
|
||||
import MovieMonitoredSelectInput from './MovieMonitoredSelectInput';
|
||||
import SelectInput from './SelectInput';
|
||||
import EnhancedSelectInput from './EnhancedSelectInput';
|
||||
import TagInputConnector from './TagInputConnector';
|
||||
import TextTagInputConnector from './TextTagInputConnector';
|
||||
import TextInput from './TextInput';
|
||||
@@ -60,7 +60,7 @@ function getComponent(type) {
|
||||
return RootFolderSelectInputConnector;
|
||||
|
||||
case inputTypes.SELECT:
|
||||
return SelectInput;
|
||||
return EnhancedSelectInput;
|
||||
|
||||
case inputTypes.TAG:
|
||||
return TagInputConnector;
|
||||
|
23
frontend/src/Components/Form/HintedSelectInputOption.css
Normal file
23
frontend/src/Components/Form/HintedSelectInputOption.css
Normal file
@@ -0,0 +1,23 @@
|
||||
.optionText {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex: 1 0 0;
|
||||
min-width: 0;
|
||||
|
||||
&.isMobile {
|
||||
display: block;
|
||||
|
||||
.hintText {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hintText {
|
||||
@add-mixin truncate;
|
||||
|
||||
margin-left: 15px;
|
||||
color: $darkGray;
|
||||
font-size: $smallFontSize;
|
||||
}
|
44
frontend/src/Components/Form/HintedSelectInputOption.js
Normal file
44
frontend/src/Components/Form/HintedSelectInputOption.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import EnhancedSelectInputOption from './EnhancedSelectInputOption';
|
||||
import styles from './HintedSelectInputOption.css';
|
||||
|
||||
function HintedSelectInputOption(props) {
|
||||
const {
|
||||
value,
|
||||
hint,
|
||||
isMobile,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<EnhancedSelectInputOption
|
||||
isMobile={isMobile}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={classNames(
|
||||
styles.optionText,
|
||||
isMobile && styles.isMobile
|
||||
)}
|
||||
>
|
||||
<div>{value}</div>
|
||||
|
||||
{
|
||||
hint != null &&
|
||||
<div className={styles.hintText}>
|
||||
{hint}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</EnhancedSelectInputOption>
|
||||
);
|
||||
}
|
||||
|
||||
HintedSelectInputOption.propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
hint: PropTypes.node,
|
||||
isMobile: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
export default HintedSelectInputOption;
|
@@ -0,0 +1,24 @@
|
||||
.selectedValue {
|
||||
composes: selectedValue from '~./EnhancedSelectInputSelectedValue.css';
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.valueText {
|
||||
@add-mixin truncate;
|
||||
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.hintText {
|
||||
@add-mixin truncate;
|
||||
|
||||
flex: 1 10 0;
|
||||
margin-left: 15px;
|
||||
color: $gray;
|
||||
text-align: right;
|
||||
font-size: $smallFontSize;
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import EnhancedSelectInputSelectedValue from './EnhancedSelectInputSelectedValue';
|
||||
import styles from './HintedSelectInputSelectedValue.css';
|
||||
|
||||
function HintedSelectInputSelectedValue(props) {
|
||||
const {
|
||||
value,
|
||||
hint,
|
||||
includeHint,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<EnhancedSelectInputSelectedValue
|
||||
className={styles.selectedValue}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={styles.valueText}>
|
||||
{value}
|
||||
</div>
|
||||
|
||||
{
|
||||
hint != null && includeHint &&
|
||||
<div className={styles.hintText}>
|
||||
{hint}
|
||||
</div>
|
||||
}
|
||||
</EnhancedSelectInputSelectedValue>
|
||||
);
|
||||
}
|
||||
|
||||
HintedSelectInputSelectedValue.propTypes = {
|
||||
value: PropTypes.string,
|
||||
hint: PropTypes.string,
|
||||
includeHint: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
HintedSelectInputSelectedValue.defaultProps = {
|
||||
includeHint: true
|
||||
};
|
||||
|
||||
export default HintedSelectInputSelectedValue;
|
@@ -20,7 +20,7 @@ function getType(type) {
|
||||
return inputTypes.NUMBER;
|
||||
case 'path':
|
||||
return inputTypes.PATH;
|
||||
case 'filepath':
|
||||
case 'filePath':
|
||||
return inputTypes.PATH;
|
||||
case 'select':
|
||||
return inputTypes.SELECT;
|
||||
@@ -60,6 +60,7 @@ function ProviderFieldFormGroup(props) {
|
||||
value,
|
||||
type,
|
||||
advanced,
|
||||
hidden,
|
||||
pending,
|
||||
errors,
|
||||
warnings,
|
||||
@@ -68,6 +69,13 @@ function ProviderFieldFormGroup(props) {
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
if (
|
||||
hidden === 'hidden' ||
|
||||
(hidden === 'hiddenIfNotSet' && !value)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<FormGroup
|
||||
advancedSettings={advancedSettings}
|
||||
@@ -86,7 +94,7 @@ function ProviderFieldFormGroup(props) {
|
||||
errors={errors}
|
||||
warnings={warnings}
|
||||
pending={pending}
|
||||
includeFiles={type === 'filepath' ? true : undefined}
|
||||
includeFiles={type === 'filePath' ? true : undefined}
|
||||
onChange={onChange}
|
||||
{...otherProps}
|
||||
/>
|
||||
@@ -108,6 +116,7 @@ ProviderFieldFormGroup.propTypes = {
|
||||
value: PropTypes.any,
|
||||
type: PropTypes.string.isRequired,
|
||||
advanced: PropTypes.bool.isRequired,
|
||||
hidden: PropTypes.string,
|
||||
pending: PropTypes.bool.isRequired,
|
||||
errors: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
warnings: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
|
@@ -1,7 +1,6 @@
|
||||
.input {
|
||||
composes: input from '~./AutoSuggestInput.css';
|
||||
|
||||
position: relative;
|
||||
padding: 0;
|
||||
min-height: 35px;
|
||||
height: auto;
|
||||
|
@@ -1,5 +1,4 @@
|
||||
.inputContainer {
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
right: -1px;
|
||||
bottom: -1px;
|
||||
|
@@ -128,6 +128,8 @@ class TextInput extends Component {
|
||||
hasWarning,
|
||||
hasButton,
|
||||
step,
|
||||
min,
|
||||
max,
|
||||
onBlur
|
||||
} = this.props;
|
||||
|
||||
@@ -148,6 +150,8 @@ class TextInput extends Component {
|
||||
name={name}
|
||||
value={value}
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
onChange={this.onChange}
|
||||
onFocus={this.onFocus}
|
||||
onBlur={onBlur}
|
||||
@@ -171,6 +175,8 @@ TextInput.propTypes = {
|
||||
hasWarning: PropTypes.bool,
|
||||
hasButton: PropTypes.bool,
|
||||
step: PropTypes.number,
|
||||
min: PropTypes.number,
|
||||
max: PropTypes.number,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onFocus: PropTypes.func,
|
||||
onBlur: PropTypes.func,
|
||||
|
Reference in New Issue
Block a user