mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
More Cleanup
This commit is contained in:
@@ -17,8 +17,6 @@ import NumberInput from './NumberInput';
|
||||
import OAuthInputConnector from './OAuthInputConnector';
|
||||
import PasswordInput from './PasswordInput';
|
||||
import PathInputConnector from './PathInputConnector';
|
||||
import QualityProfileSelectInputConnector from './QualityProfileSelectInputConnector';
|
||||
import RootFolderSelectInputConnector from './RootFolderSelectInputConnector';
|
||||
import TagInputConnector from './TagInputConnector';
|
||||
import TagSelectInputConnector from './TagSelectInputConnector';
|
||||
import TextArea from './TextArea';
|
||||
@@ -58,15 +56,9 @@ function getComponent(type) {
|
||||
case inputTypes.PATH:
|
||||
return PathInputConnector;
|
||||
|
||||
case inputTypes.QUALITY_PROFILE_SELECT:
|
||||
return QualityProfileSelectInputConnector;
|
||||
|
||||
case inputTypes.MOVIE_MONITORED_SELECT:
|
||||
return MovieMonitoredSelectInput;
|
||||
|
||||
case inputTypes.ROOT_FOLDER_SELECT:
|
||||
return RootFolderSelectInputConnector;
|
||||
|
||||
case inputTypes.INDEXER_FLAGS_SELECT:
|
||||
return IndexerFlagsSelectInputConnector;
|
||||
|
||||
|
@@ -1,99 +0,0 @@
|
||||
import _ from 'lodash';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
||||
import sortByName from 'Utilities/Array/sortByName';
|
||||
import SelectInput from './SelectInput';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createSortedSectionSelector('settings.qualityProfiles', sortByName),
|
||||
(state, { includeNoChange }) => includeNoChange,
|
||||
(state, { includeMixed }) => includeMixed,
|
||||
(qualityProfiles, includeNoChange, includeMixed) => {
|
||||
const values = _.map(qualityProfiles.items, (qualityProfile) => {
|
||||
return {
|
||||
key: qualityProfile.id,
|
||||
value: qualityProfile.name
|
||||
};
|
||||
});
|
||||
|
||||
if (includeNoChange) {
|
||||
values.unshift({
|
||||
key: 'noChange',
|
||||
value: 'No Change',
|
||||
disabled: true
|
||||
});
|
||||
}
|
||||
|
||||
if (includeMixed) {
|
||||
values.unshift({
|
||||
key: 'mixed',
|
||||
value: '(Mixed)',
|
||||
disabled: true
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
values
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
class QualityProfileSelectInputConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
name,
|
||||
value,
|
||||
values
|
||||
} = this.props;
|
||||
|
||||
if (!value || !values.some((v) => v.key === value) ) {
|
||||
const firstValue = _.find(values, (option) => !isNaN(parseInt(option.key)));
|
||||
|
||||
if (firstValue) {
|
||||
this.onChange({ name, value: firstValue.key });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onChange = ({ name, value }) => {
|
||||
this.props.onChange({ name, value: parseInt(value) });
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SelectInput
|
||||
{...this.props}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
QualityProfileSelectInputConnector.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
includeNoChange: PropTypes.bool.isRequired,
|
||||
onChange: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
QualityProfileSelectInputConnector.defaultProps = {
|
||||
includeNoChange: false
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps)(QualityProfileSelectInputConnector);
|
@@ -1,109 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
|
||||
import EnhancedSelectInput from './EnhancedSelectInput';
|
||||
import RootFolderSelectInputOption from './RootFolderSelectInputOption';
|
||||
import RootFolderSelectInputSelectedValue from './RootFolderSelectInputSelectedValue';
|
||||
|
||||
class RootFolderSelectInput extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
isAddNewRootFolderModalOpen: false,
|
||||
newRootFolderPath: ''
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
name,
|
||||
isSaving,
|
||||
saveError,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
const newRootFolderPath = this.state.newRootFolderPath;
|
||||
|
||||
if (
|
||||
prevProps.isSaving &&
|
||||
!isSaving &&
|
||||
!saveError &&
|
||||
newRootFolderPath
|
||||
) {
|
||||
onChange({ name, value: newRootFolderPath });
|
||||
this.setState({ newRootFolderPath: '' });
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onChange = ({ name, value }) => {
|
||||
if (value === 'addNew') {
|
||||
this.setState({ isAddNewRootFolderModalOpen: true });
|
||||
} else {
|
||||
this.props.onChange({ name, value });
|
||||
}
|
||||
}
|
||||
|
||||
onNewRootFolderSelect = ({ value }) => {
|
||||
this.setState({ newRootFolderPath: value }, () => {
|
||||
this.props.onNewRootFolderSelect(value);
|
||||
});
|
||||
}
|
||||
|
||||
onAddRootFolderModalClose = () => {
|
||||
this.setState({ isAddNewRootFolderModalOpen: false });
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
includeNoChange,
|
||||
onNewRootFolderSelect,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<EnhancedSelectInput
|
||||
{...otherProps}
|
||||
selectedValueComponent={RootFolderSelectInputSelectedValue}
|
||||
optionComponent={RootFolderSelectInputOption}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
|
||||
<FileBrowserModal
|
||||
isOpen={this.state.isAddNewRootFolderModalOpen}
|
||||
name="rootFolderPath"
|
||||
value=""
|
||||
onChange={this.onNewRootFolderSelect}
|
||||
onModalClose={this.onAddRootFolderModalClose}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RootFolderSelectInput.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
saveError: PropTypes.object,
|
||||
includeNoChange: PropTypes.bool.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onNewRootFolderSelect: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
RootFolderSelectInput.defaultProps = {
|
||||
includeNoChange: false
|
||||
};
|
||||
|
||||
export default RootFolderSelectInput;
|
@@ -1,157 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { addRootFolder } from 'Store/Actions/rootFolderActions';
|
||||
import RootFolderSelectInput from './RootFolderSelectInput';
|
||||
|
||||
const ADD_NEW_KEY = 'addNew';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.rootFolders,
|
||||
(state, { includeNoChange }) => includeNoChange,
|
||||
(rootFolders, includeNoChange) => {
|
||||
const values = rootFolders.items.map((rootFolder) => {
|
||||
return {
|
||||
key: rootFolder.path,
|
||||
value: rootFolder.path,
|
||||
freeSpace: rootFolder.freeSpace
|
||||
};
|
||||
});
|
||||
|
||||
if (includeNoChange) {
|
||||
values.unshift({
|
||||
key: 'noChange',
|
||||
value: 'No Change',
|
||||
isDisabled: true
|
||||
});
|
||||
}
|
||||
|
||||
if (!values.length) {
|
||||
values.push({
|
||||
key: '',
|
||||
value: '',
|
||||
isDisabled: true,
|
||||
isHidden: true
|
||||
});
|
||||
}
|
||||
|
||||
values.push({
|
||||
key: ADD_NEW_KEY,
|
||||
value: 'Add a new path'
|
||||
});
|
||||
|
||||
return {
|
||||
values,
|
||||
isSaving: rootFolders.isSaving,
|
||||
saveError: rootFolders.saveError
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function createMapDispatchToProps(dispatch, props) {
|
||||
return {
|
||||
dispatchAddRootFolder(path) {
|
||||
dispatch(addRootFolder({ path }));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
class RootFolderSelectInputConnector extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
const {
|
||||
value,
|
||||
values,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
if (value == null && values[0].key === '') {
|
||||
onChange({ name, value: '' });
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const {
|
||||
name,
|
||||
value,
|
||||
values,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
if (!value || !values.some((v) => v.key === value) || value === ADD_NEW_KEY) {
|
||||
const defaultValue = values[0];
|
||||
|
||||
if (defaultValue.key === ADD_NEW_KEY) {
|
||||
onChange({ name, value: '' });
|
||||
} else {
|
||||
onChange({ name, value: defaultValue.key });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
name,
|
||||
value,
|
||||
values,
|
||||
onChange
|
||||
} = this.props;
|
||||
|
||||
if (prevProps.values === values) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!value && values.length && values.some((v) => !!v.key && v.key !== ADD_NEW_KEY)) {
|
||||
const defaultValue = values[0];
|
||||
|
||||
if (defaultValue.key !== ADD_NEW_KEY) {
|
||||
onChange({ name, value: defaultValue.key });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onNewRootFolderSelect = (path) => {
|
||||
this.props.dispatchAddRootFolder(path);
|
||||
}
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
dispatchAddRootFolder,
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
<RootFolderSelectInput
|
||||
{...otherProps}
|
||||
onNewRootFolderSelect={this.onNewRootFolderSelect}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
RootFolderSelectInputConnector.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
value: PropTypes.string,
|
||||
values: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
includeNoChange: PropTypes.bool.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
dispatchAddRootFolder: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
RootFolderSelectInputConnector.defaultProps = {
|
||||
includeNoChange: false
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, createMapDispatchToProps)(RootFolderSelectInputConnector);
|
@@ -1,31 +0,0 @@
|
||||
.optionText {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex: 1 0 0;
|
||||
|
||||
&.isMobile {
|
||||
display: block;
|
||||
|
||||
.freeSpace {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.value {
|
||||
display: flex;
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
.movieFolder {
|
||||
@add-mixin truncate;
|
||||
|
||||
color: $disabledColor;
|
||||
}
|
||||
|
||||
.freeSpace {
|
||||
margin-left: 15px;
|
||||
color: $darkGray;
|
||||
font-size: $smallFontSize;
|
||||
}
|
@@ -1,65 +0,0 @@
|
||||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import EnhancedSelectInputOption from './EnhancedSelectInputOption';
|
||||
import styles from './RootFolderSelectInputOption.css';
|
||||
|
||||
function RootFolderSelectInputOption(props) {
|
||||
const {
|
||||
id,
|
||||
value,
|
||||
freeSpace,
|
||||
movieFolder,
|
||||
isMobile,
|
||||
isWindows,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const slashCharacter = isWindows ? '\\' : '/';
|
||||
|
||||
return (
|
||||
<EnhancedSelectInputOption
|
||||
id={id}
|
||||
isMobile={isMobile}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={classNames(
|
||||
styles.optionText,
|
||||
isMobile && styles.isMobile
|
||||
)}
|
||||
>
|
||||
<div className={styles.value}>
|
||||
{value}
|
||||
|
||||
{
|
||||
movieFolder && id !== 'addNew' ?
|
||||
<div className={styles.movieFolder}>
|
||||
{slashCharacter}
|
||||
{movieFolder}
|
||||
</div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
|
||||
{
|
||||
freeSpace != null &&
|
||||
<div className={styles.freeSpace}>
|
||||
{formatBytes(freeSpace)} Free
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</EnhancedSelectInputOption>
|
||||
);
|
||||
}
|
||||
|
||||
RootFolderSelectInputOption.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
freeSpace: PropTypes.number,
|
||||
movieFolder: PropTypes.string,
|
||||
isMobile: PropTypes.bool.isRequired,
|
||||
isWindows: PropTypes.bool
|
||||
};
|
||||
|
||||
export default RootFolderSelectInputOption;
|
@@ -1,32 +0,0 @@
|
||||
.selectedValue {
|
||||
composes: selectedValue from '~./EnhancedSelectInputSelectedValue.css';
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.pathContainer {
|
||||
@add-mixin truncate;
|
||||
display: flex;
|
||||
flex: 1 0 0;
|
||||
}
|
||||
|
||||
.path {
|
||||
flex: 0 1 auto;
|
||||
}
|
||||
|
||||
.movieFolder {
|
||||
@add-mixin truncate;
|
||||
flex: 0 1 auto;
|
||||
color: $disabledColor;
|
||||
}
|
||||
|
||||
.freeSpace {
|
||||
flex: 0 0 auto;
|
||||
margin-left: 15px;
|
||||
color: $gray;
|
||||
text-align: right;
|
||||
font-size: $smallFontSize;
|
||||
}
|
@@ -1,61 +0,0 @@
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import formatBytes from 'Utilities/Number/formatBytes';
|
||||
import EnhancedSelectInputSelectedValue from './EnhancedSelectInputSelectedValue';
|
||||
import styles from './RootFolderSelectInputSelectedValue.css';
|
||||
|
||||
function RootFolderSelectInputSelectedValue(props) {
|
||||
const {
|
||||
value,
|
||||
freeSpace,
|
||||
movieFolder,
|
||||
includeFreeSpace,
|
||||
isWindows,
|
||||
...otherProps
|
||||
} = props;
|
||||
|
||||
const slashCharacter = isWindows ? '\\' : '/';
|
||||
|
||||
return (
|
||||
<EnhancedSelectInputSelectedValue
|
||||
className={styles.selectedValue}
|
||||
{...otherProps}
|
||||
>
|
||||
<div className={styles.pathContainer}>
|
||||
<div className={styles.path}>
|
||||
{value}
|
||||
</div>
|
||||
|
||||
{
|
||||
movieFolder ?
|
||||
<div className={styles.movieFolder}>
|
||||
{slashCharacter}
|
||||
{movieFolder}
|
||||
</div> :
|
||||
null
|
||||
}
|
||||
</div>
|
||||
|
||||
{
|
||||
freeSpace != null && includeFreeSpace &&
|
||||
<div className={styles.freeSpace}>
|
||||
{formatBytes(freeSpace)} Free
|
||||
</div>
|
||||
}
|
||||
</EnhancedSelectInputSelectedValue>
|
||||
);
|
||||
}
|
||||
|
||||
RootFolderSelectInputSelectedValue.propTypes = {
|
||||
value: PropTypes.string,
|
||||
freeSpace: PropTypes.number,
|
||||
movieFolder: PropTypes.string,
|
||||
isWindows: PropTypes.bool,
|
||||
includeFreeSpace: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
RootFolderSelectInputSelectedValue.defaultProps = {
|
||||
includeFreeSpace: true
|
||||
};
|
||||
|
||||
export default RootFolderSelectInputSelectedValue;
|
Reference in New Issue
Block a user