1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-04-18 21:35:27 -04:00
Files
Sonarr/frontend/src/AddSeries/ImportSeries/SelectFolder/ImportSeriesSelectFolder.tsx
T
2025-02-11 19:35:57 -08:00

165 lines
5.3 KiB
TypeScript

import React, { useCallback, useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import AppState from 'App/State/AppState';
import Alert from 'Components/Alert';
import FieldSet from 'Components/FieldSet';
import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
import Icon from 'Components/Icon';
import Button from 'Components/Link/Button';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import InlineMarkdown from 'Components/Markdown/InlineMarkdown';
import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody';
import usePrevious from 'Helpers/Hooks/usePrevious';
import { icons, kinds, sizes } from 'Helpers/Props';
import RootFolders from 'RootFolder/RootFolders';
import {
addRootFolder,
fetchRootFolders,
} from 'Store/Actions/rootFolderActions';
import useIsWindows from 'System/useIsWindows';
import { InputChanged } from 'typings/inputs';
import translate from 'Utilities/String/translate';
import styles from './ImportSeriesSelectFolder.css';
function ImportSeriesSelectFolder() {
const dispatch = useDispatch();
const { isFetching, isPopulated, isSaving, error, saveError, items } =
useSelector((state: AppState) => state.rootFolders);
const isWindows = useIsWindows();
const [isAddNewRootFolderModalOpen, setIsAddNewRootFolderModalOpen] =
useState(false);
const wasSaving = usePrevious(isSaving);
const hasRootFolders = items.length > 0;
const goodFolderExample = isWindows ? 'C:\\tv shows' : '/tv shows';
const badFolderExample = isWindows
? 'C:\\tv shows\\the simpsons'
: '/tv shows/the simpsons';
const handleAddNewRootFolderPress = useCallback(() => {
setIsAddNewRootFolderModalOpen(true);
}, []);
const handleAddRootFolderModalClose = useCallback(() => {
setIsAddNewRootFolderModalOpen(false);
}, []);
const handleNewRootFolderSelect = useCallback(
({ value }: InputChanged<string>) => {
dispatch(addRootFolder({ path: value }));
},
[dispatch]
);
useEffect(() => {
dispatch(fetchRootFolders());
}, [dispatch]);
useEffect(() => {
if (!isSaving && wasSaving && !saveError) {
items.reduce((acc, item) => {
if (item.id > acc) {
return item.id;
}
return acc;
}, 0);
}
}, [isSaving, wasSaving, saveError, items]);
return (
<PageContent title={translate('ImportSeries')}>
<PageContentBody>
{isFetching && !isPopulated ? <LoadingIndicator /> : null}
{!isFetching && error ? (
<Alert kind={kinds.DANGER}>{translate('RootFoldersLoadError')}</Alert>
) : null}
{!error && isPopulated && (
<div>
<div className={styles.header}>
{translate('LibraryImportSeriesHeader')}
</div>
<div className={styles.tips}>
{translate('LibraryImportTips')}
<ul>
<li className={styles.tip}>
<InlineMarkdown
data={translate(
'LibraryImportTipsQualityInEpisodeFilename'
)}
/>
</li>
<li className={styles.tip}>
<InlineMarkdown
data={translate('LibraryImportTipsSeriesUseRootFolder', {
goodFolderExample,
badFolderExample,
})}
/>
</li>
<li className={styles.tip}>
{translate('LibraryImportTipsDontUseDownloadsFolder')}
</li>
</ul>
</div>
{hasRootFolders ? (
<div className={styles.recentFolders}>
<FieldSet legend={translate('RootFolders')}>
<RootFolders />
</FieldSet>
</div>
) : null}
{!isSaving && saveError ? (
<Alert className={styles.addErrorAlert} kind={kinds.DANGER}>
{translate('AddRootFolderError')}
<ul>
{Array.isArray(saveError.responseJSON) ? (
saveError.responseJSON.map((e, index) => {
return <li key={index}>{e.errorMessage}</li>;
})
) : (
<li>{JSON.stringify(saveError.responseJSON)}</li>
)}
</ul>
</Alert>
) : null}
<div className={hasRootFolders ? undefined : styles.startImport}>
<Button
kind={kinds.PRIMARY}
size={sizes.LARGE}
onPress={handleAddNewRootFolderPress}
>
<Icon className={styles.importButtonIcon} name={icons.DRIVE} />
{hasRootFolders
? translate('ChooseAnotherFolder')
: translate('StartImport')}
</Button>
</div>
<FileBrowserModal
isOpen={isAddNewRootFolderModalOpen}
name="rootFolderPath"
value=""
onChange={handleNewRootFolderSelect}
onModalClose={handleAddRootFolderModalClose}
/>
</div>
)}
</PageContentBody>
</PageContent>
);
}
export default ImportSeriesSelectFolder;