New: Add root folder to media management settings

This commit is contained in:
Mark McDowall 2019-01-01 17:38:21 -08:00
parent c417239652
commit 647e444a07
10 changed files with 168 additions and 113 deletions

View File

@ -1,48 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { deleteRootFolder } from 'Store/Actions/rootFolderActions';
import ImportSeriesRootFolderRow from './ImportSeriesRootFolderRow';
function createMapStateToProps() {
return createSelector(
() => {
return {
};
}
);
}
const mapDispatchToProps = {
deleteRootFolder
};
class ImportSeriesRootFolderRowConnector extends Component {
//
// Listeners
onDeletePress = () => {
this.props.deleteRootFolder({ id: this.props.id });
}
//
// Render
render() {
return (
<ImportSeriesRootFolderRow
{...this.props}
onDeletePress={this.onDeletePress}
/>
);
}
}
ImportSeriesRootFolderRowConnector.propTypes = {
id: PropTypes.number.isRequired,
deleteRootFolder: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(ImportSeriesRootFolderRowConnector);

View File

@ -2,39 +2,15 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { icons, kinds, sizes } from 'Helpers/Props'; import { icons, kinds, sizes } from 'Helpers/Props';
import Button from 'Components/Link/Button'; import Button from 'Components/Link/Button';
import FieldSet from 'Components/FieldSet';
import Icon from 'Components/Icon'; import Icon from 'Components/Icon';
import FieldSet from 'Components/FieldSet';
import LoadingIndicator from 'Components/Loading/LoadingIndicator'; import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal'; import FileBrowserModal from 'Components/FileBrowser/FileBrowserModal';
import PageContent from 'Components/Page/PageContent'; import PageContent from 'Components/Page/PageContent';
import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector'; import PageContentBodyConnector from 'Components/Page/PageContentBodyConnector';
import Table from 'Components/Table/Table'; import RootFolders from 'RootFolder/RootFolders';
import TableBody from 'Components/Table/TableBody';
import ImportSeriesRootFolderRowConnector from './ImportSeriesRootFolderRowConnector';
import styles from './ImportSeriesSelectFolder.css'; import styles from './ImportSeriesSelectFolder.css';
const rootFolderColumns = [
{
name: 'path',
label: 'Path',
isVisible: true
},
{
name: 'freeSpace',
label: 'Free Space',
isVisible: true
},
{
name: 'unmappedFolders',
label: 'Unmapped Folders',
isVisible: true
},
{
name: 'actions',
isVisible: true
}
];
class ImportSeriesSelectFolder extends Component { class ImportSeriesSelectFolder extends Component {
// //
@ -110,26 +86,13 @@ class ImportSeriesSelectFolder extends Component {
{ {
items.length > 0 ? items.length > 0 ?
<div className={styles.recentFolders}> <div className={styles.recentFolders}>
<FieldSet legend="Recent Folders"> <FieldSet legend="Root Folders">
<Table <RootFolders
columns={rootFolderColumns} isFetching={isFetching}
> isPopulated={isPopulated}
<TableBody> error={error}
{ items={items}
items.map((rootFolder) => { />
return (
<ImportSeriesRootFolderRowConnector
key={rootFolder.id}
id={rootFolder.id}
path={rootFolder.path}
freeSpace={rootFolder.freeSpace}
unmappedFolders={rootFolder.unmappedFolders}
/>
);
})
}
</TableBody>
</Table>
</FieldSet> </FieldSet>
<Button <Button
@ -181,8 +144,7 @@ ImportSeriesSelectFolder.propTypes = {
isPopulated: PropTypes.bool.isRequired, isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object, error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired,
onNewRootFolderSelect: PropTypes.func.isRequired, onNewRootFolderSelect: PropTypes.func.isRequired
onDeleteRootFolderPress: PropTypes.func.isRequired
}; };
export default ImportSeriesSelectFolder; export default ImportSeriesSelectFolder;

View File

@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { push } from 'react-router-redux'; import { push } from 'react-router-redux';
import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector'; import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector';
import { fetchRootFolders, addRootFolder, deleteRootFolder } from 'Store/Actions/rootFolderActions'; import { fetchRootFolders, addRootFolder } from 'Store/Actions/rootFolderActions';
import ImportSeriesSelectFolder from './ImportSeriesSelectFolder'; import ImportSeriesSelectFolder from './ImportSeriesSelectFolder';
function createMapStateToProps() { function createMapStateToProps() {
@ -24,7 +24,6 @@ function createMapStateToProps() {
const mapDispatchToProps = { const mapDispatchToProps = {
fetchRootFolders, fetchRootFolders,
addRootFolder, addRootFolder,
deleteRootFolder,
push push
}; };
@ -60,10 +59,6 @@ class ImportSeriesSelectFolderConnector extends Component {
this.props.addRootFolder({ path }); this.props.addRootFolder({ path });
} }
onDeleteRootFolderPress = (id) => {
this.props.deleteRootFolder({ id });
}
// //
// Render // Render
@ -72,7 +67,6 @@ class ImportSeriesSelectFolderConnector extends Component {
<ImportSeriesSelectFolder <ImportSeriesSelectFolder
{...this.props} {...this.props}
onNewRootFolderSelect={this.onNewRootFolderSelect} onNewRootFolderSelect={this.onNewRootFolderSelect}
onDeleteRootFolderPress={this.onDeleteRootFolderPress}
/> />
); );
} }
@ -84,7 +78,6 @@ ImportSeriesSelectFolderConnector.propTypes = {
items: PropTypes.arrayOf(PropTypes.object).isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired,
fetchRootFolders: PropTypes.func.isRequired, fetchRootFolders: PropTypes.func.isRequired,
addRootFolder: PropTypes.func.isRequired, addRootFolder: PropTypes.func.isRequired,
deleteRootFolder: PropTypes.func.isRequired,
push: PropTypes.func.isRequired push: PropTypes.func.isRequired
}; };

View File

@ -6,9 +6,9 @@ import IconButton from 'Components/Link/IconButton';
import Link from 'Components/Link/Link'; import Link from 'Components/Link/Link';
import TableRow from 'Components/Table/TableRow'; import TableRow from 'Components/Table/TableRow';
import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableRowCell from 'Components/Table/Cells/TableRowCell';
import styles from './ImportSeriesRootFolderRow.css'; import styles from './RootFolderRow.css';
function ImportSeriesRootFolderRow(props) { function RootFolderRow(props) {
const { const {
id, id,
path, path,
@ -49,7 +49,7 @@ function ImportSeriesRootFolderRow(props) {
); );
} }
ImportSeriesRootFolderRow.propTypes = { RootFolderRow.propTypes = {
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
path: PropTypes.string.isRequired, path: PropTypes.string.isRequired,
freeSpace: PropTypes.number.isRequired, freeSpace: PropTypes.number.isRequired,
@ -57,9 +57,9 @@ ImportSeriesRootFolderRow.propTypes = {
onDeletePress: PropTypes.func.isRequired onDeletePress: PropTypes.func.isRequired
}; };
ImportSeriesRootFolderRow.defaultProps = { RootFolderRow.defaultProps = {
freeSpace: 0, freeSpace: 0,
unmappedFolders: [] unmappedFolders: []
}; };
export default ImportSeriesRootFolderRow; export default RootFolderRow;

View File

@ -0,0 +1,13 @@
import { connect } from 'react-redux';
import { deleteRootFolder } from 'Store/Actions/rootFolderActions';
import RootFolderRow from './RootFolderRow';
function createMapDispatchToProps(dispatch, props) {
return {
onDeletePress() {
dispatch(deleteRootFolder({ id: props.id }));
}
};
}
export default connect(null, createMapDispatchToProps)(RootFolderRow);

View File

@ -0,0 +1,80 @@
import PropTypes from 'prop-types';
import React from 'react';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import RootFolderRowConnector from './RootFolderRowConnector';
const rootFolderColumns = [
{
name: 'path',
label: 'Path',
isVisible: true
},
{
name: 'freeSpace',
label: 'Free Space',
isVisible: true
},
{
name: 'unmappedFolders',
label: 'Unmapped Folders',
isVisible: true
},
{
name: 'actions',
isVisible: true
}
];
function RootFolders(props) {
const {
isFetching,
isPopulated,
error,
items
} = props;
if (isFetching && !isPopulated) {
return (
<LoadingIndicator />
);
}
if (!isFetching && !!error) {
return (
<div>Unable to load root folders</div>
);
}
return (
<Table
columns={rootFolderColumns}
>
<TableBody>
{
items.map((rootFolder) => {
return (
<RootFolderRowConnector
key={rootFolder.id}
id={rootFolder.id}
path={rootFolder.path}
freeSpace={rootFolder.freeSpace}
unmappedFolders={rootFolder.unmappedFolders}
/>
);
})
}
</TableBody>
</Table>
);
}
RootFolders.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired
};
export default RootFolders;

View File

@ -0,0 +1,46 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
import RootFolders from './RootFolders';
function createMapStateToProps() {
return createSelector(
(state) => state.rootFolders,
(rootFolders) => {
return rootFolders;
}
);
}
const mapDispatchToProps = {
dispatchFetchRootFolders: fetchRootFolders
};
class RootFoldersConnector extends Component {
//
// Lifecycle
componentDidMount() {
this.props.dispatchFetchRootFolders();
}
//
// Render
render() {
return (
<RootFolders
{...this.props}
/>
);
}
}
RootFoldersConnector.propTypes = {
dispatchFetchRootFolders: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(RootFoldersConnector);

View File

@ -10,6 +10,7 @@ import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup'; import FormGroup from 'Components/Form/FormGroup';
import FormLabel from 'Components/Form/FormLabel'; import FormLabel from 'Components/Form/FormLabel';
import FormInputGroup from 'Components/Form/FormInputGroup'; import FormInputGroup from 'Components/Form/FormInputGroup';
import RootFoldersConnector from 'RootFolder/RootFoldersConnector';
import NamingConnector from './Naming/NamingConnector'; import NamingConnector from './Naming/NamingConnector';
const rescanAfterRefreshOptions = [ const rescanAfterRefreshOptions = [
@ -51,14 +52,20 @@ class MediaManagement extends Component {
/> />
<PageContentBodyConnector> <PageContentBodyConnector>
<NamingConnector />
{ {
isFetching && isFetching &&
<LoadingIndicator /> <FieldSet legend="Naming Settings">
<LoadingIndicator />
</FieldSet>
} }
{ {
!isFetching && error && !isFetching && error &&
<FieldSet legend="Naming Settings">
<div>Unable to load Media Management settings</div> <div>Unable to load Media Management settings</div>
</FieldSet>
} }
{ {
@ -67,8 +74,6 @@ class MediaManagement extends Component {
id="mediaManagementSettings" id="mediaManagementSettings"
{...otherProps} {...otherProps}
> >
<NamingConnector />
{ {
advancedSettings && advancedSettings &&
<FieldSet legend="Folders"> <FieldSet legend="Folders">
@ -363,6 +368,10 @@ class MediaManagement extends Component {
} }
</Form> </Form>
} }
<FieldSet legend="Root Folders">
<RootFoldersConnector />
</FieldSet>
</PageContentBodyConnector> </PageContentBodyConnector>
</PageContent> </PageContent>
); );

View File

@ -21,7 +21,7 @@ function Settings() {
</Link> </Link>
<div className={styles.summary}> <div className={styles.summary}>
Naming and file management settings Naming, file management settings and root folders
</div> </div>
<Link <Link