1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-23 22:25:14 -04:00

Convert Manual Import to Typescript

This commit is contained in:
Qstick
2023-05-02 23:07:12 -05:00
parent d2112f2bdc
commit eeb997430c
130 changed files with 3314 additions and 3161 deletions
@@ -1,169 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import PathInputConnector from 'Components/Form/PathInputConnector';
import Icon from 'Components/Icon';
import Button from 'Components/Link/Button';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons, kinds, sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import RecentFolderRow from './RecentFolderRow';
import styles from './InteractiveImportSelectFolderModalContent.css';
const recentFoldersColumns = [
{
name: 'folder',
label: translate('Folder')
},
{
name: 'lastUsed',
label: translate('LastUsed')
},
{
name: 'actions',
label: ''
}
];
class InteractiveImportSelectFolderModalContent extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
folder: ''
};
}
//
// Listeners
onPathChange = ({ value }) => {
this.setState({ folder: value });
};
onRecentPathPress = (folder) => {
this.setState({ folder });
};
onQuickImportPress = () => {
this.props.onQuickImportPress(this.state.folder);
};
onInteractiveImportPress = () => {
this.props.onInteractiveImportPress(this.state.folder);
};
//
// Render
render() {
const {
recentFolders,
onRemoveRecentFolderPress,
onModalClose
} = this.props;
const folder = this.state.folder;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('ManualImport')} - {translate('SelectFolder')}
</ModalHeader>
<ModalBody>
<PathInputConnector
name="folder"
value={folder}
onChange={this.onPathChange}
/>
{
!!recentFolders.length &&
<div className={styles.recentFoldersContainer}>
<Table
columns={recentFoldersColumns}
>
<TableBody>
{
recentFolders.slice(0).reverse().map((recentFolder) => {
return (
<RecentFolderRow
key={recentFolder.folder}
folder={recentFolder.folder}
lastUsed={recentFolder.lastUsed}
onPress={this.onRecentPathPress}
onRemoveRecentFolderPress={onRemoveRecentFolderPress}
/>
);
})
}
</TableBody>
</Table>
</div>
}
<div className={styles.buttonsContainer}>
<div className={styles.buttonContainer}>
<Button
className={styles.button}
kind={kinds.PRIMARY}
size={sizes.LARGE}
isDisabled={!folder}
onPress={this.onQuickImportPress}
>
<Icon
className={styles.buttonIcon}
name={icons.QUICK}
/>
{translate('QuickImport')}
</Button>
</div>
<div className={styles.buttonContainer}>
<Button
className={styles.button}
kind={kinds.PRIMARY}
size={sizes.LARGE}
isDisabled={!folder}
onPress={this.onInteractiveImportPress}
>
<Icon
className={styles.buttonIcon}
name={icons.INTERACTIVE}
/>
{translate('InteractiveImport')}
</Button>
</div>
</div>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
{translate('Cancel')}
</Button>
</ModalFooter>
</ModalContent>
);
}
}
InteractiveImportSelectFolderModalContent.propTypes = {
recentFolders: PropTypes.arrayOf(PropTypes.object).isRequired,
onQuickImportPress: PropTypes.func.isRequired,
onInteractiveImportPress: PropTypes.func.isRequired,
onRemoveRecentFolderPress: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default InteractiveImportSelectFolderModalContent;
@@ -0,0 +1,172 @@
import React, { useCallback, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import * as commandNames from 'Commands/commandNames';
import PathInputConnector from 'Components/Form/PathInputConnector';
import Icon from 'Components/Icon';
import Button from 'Components/Link/Button';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons, kinds, sizes } from 'Helpers/Props';
import { executeCommand } from 'Store/Actions/commandActions';
import {
addRecentFolder,
removeRecentFolder,
} from 'Store/Actions/interactiveImportActions';
import translate from 'Utilities/String/translate';
import RecentFolderRow from './RecentFolderRow';
import styles from './InteractiveImportSelectFolderModalContent.css';
const recentFoldersColumns = [
{
name: 'folder',
label: translate('Folder'),
},
{
name: 'lastUsed',
label: translate('LastUsed'),
},
{
name: 'actions',
label: '',
},
];
interface InteractiveImportSelectFolderModalContentProps {
modalTitle: string;
onFolderSelect(folder: string): void;
onModalClose(): void;
}
function InteractiveImportSelectFolderModalContent(
props: InteractiveImportSelectFolderModalContentProps
) {
const { modalTitle, onFolderSelect, onModalClose } = props;
const [folder, setFolder] = useState('');
const dispatch = useDispatch();
const recentFolders = useSelector(
createSelector(
(state: AppState) => state.interactiveImport.recentFolders,
(recentFolders) => {
return recentFolders;
}
)
);
const onPathChange = useCallback(
({ value }: { value: string }) => {
setFolder(value);
},
[setFolder]
);
const onRecentPathPress = useCallback(
(value: string) => {
setFolder(value);
},
[setFolder]
);
const onQuickImportPress = useCallback(() => {
dispatch(addRecentFolder({ folder }));
dispatch(
executeCommand({
name: commandNames.DOWNLOADED_MOVIES_SCAN,
path: folder,
})
);
onModalClose();
}, [folder, onModalClose, dispatch]);
const onInteractiveImportPress = useCallback(() => {
dispatch(addRecentFolder({ folder }));
onFolderSelect(folder);
}, [folder, onFolderSelect, dispatch]);
const onRemoveRecentFolderPress = useCallback(
(folderToRemove: string) => {
dispatch(removeRecentFolder({ folder: folderToRemove }));
},
[dispatch]
);
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{modalTitle} - {translate('SelectFolder')}
</ModalHeader>
<ModalBody>
<PathInputConnector
name="folder"
value={folder}
onChange={onPathChange}
/>
{recentFolders.length ? (
<div className={styles.recentFoldersContainer}>
<Table columns={recentFoldersColumns}>
<TableBody>
{recentFolders
.slice(0)
.reverse()
.map((recentFolder) => {
return (
<RecentFolderRow
key={recentFolder.folder}
folder={recentFolder.folder}
lastUsed={recentFolder.lastUsed}
onPress={onRecentPathPress}
onRemoveRecentFolderPress={onRemoveRecentFolderPress}
/>
);
})}
</TableBody>
</Table>
</div>
) : null}
<div className={styles.buttonsContainer}>
<div className={styles.buttonContainer}>
<Button
className={styles.button}
kind={kinds.PRIMARY}
size={sizes.LARGE}
isDisabled={!folder}
onPress={onQuickImportPress}
>
<Icon className={styles.buttonIcon} name={icons.QUICK} />
{translate('MoveAutomatically')}
</Button>
</div>
<div className={styles.buttonContainer}>
<Button
className={styles.button}
kind={kinds.PRIMARY}
size={sizes.LARGE}
isDisabled={!folder}
onPress={onInteractiveImportPress}
>
<Icon className={styles.buttonIcon} name={icons.INTERACTIVE} />
{translate('InteractiveImport')}
</Button>
</div>
</div>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>{translate('Cancel')}</Button>
</ModalFooter>
</ModalContent>
);
}
export default InteractiveImportSelectFolderModalContent;
@@ -1,80 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import * as commandNames from 'Commands/commandNames';
import { executeCommand } from 'Store/Actions/commandActions';
import { addRecentFolder, removeRecentFolder } from 'Store/Actions/interactiveImportActions';
import InteractiveImportSelectFolderModalContent from './InteractiveImportSelectFolderModalContent';
function createMapStateToProps() {
return createSelector(
(state) => state.interactiveImport.recentFolders,
(recentFolders) => {
return {
recentFolders
};
}
);
}
const mapDispatchToProps = {
addRecentFolder,
removeRecentFolder,
executeCommand
};
class InteractiveImportSelectFolderModalContentConnector extends Component {
//
// Listeners
onQuickImportPress = (folder) => {
this.props.addRecentFolder({ folder });
this.props.executeCommand({
name: commandNames.DOWNLOADED_MOVIES_SCAN,
path: folder
});
this.props.onModalClose();
};
onInteractiveImportPress = (folder) => {
this.props.addRecentFolder({ folder });
this.props.onFolderSelect(folder);
};
onRemoveRecentFolderPress = (folder) => {
this.props.removeRecentFolder({ folder });
};
//
// Render
render() {
if (this.path) {
return null;
}
return (
<InteractiveImportSelectFolderModalContent
{...this.props}
onQuickImportPress={this.onQuickImportPress}
onInteractiveImportPress={this.onInteractiveImportPress}
onRemoveRecentFolderPress={this.onRemoveRecentFolderPress}
/>
);
}
}
InteractiveImportSelectFolderModalContentConnector.propTypes = {
path: PropTypes.string,
onFolderSelect: PropTypes.func.isRequired,
onModalClose: PropTypes.func.isRequired,
addRecentFolder: PropTypes.func.isRequired,
removeRecentFolder: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(InteractiveImportSelectFolderModalContentConnector);
@@ -0,0 +1,6 @@
interface RecentFolder {
folder: string;
lastUsed: string;
}
export default RecentFolder;