Mass Editor size and options
New: Option to show size in Mass Editor New: Size on Disk in Mass Editor custom filters Closes #3273
This commit is contained in:
parent
3586d7042b
commit
069fc5cd33
|
@ -3,13 +3,16 @@ import React, { Component } from 'react';
|
||||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||||
import selectAll from 'Utilities/Table/selectAll';
|
import selectAll from 'Utilities/Table/selectAll';
|
||||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||||
import { align, sortDirections } from 'Helpers/Props';
|
import { align, icons, sortDirections } from 'Helpers/Props';
|
||||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||||
import PageContent from 'Components/Page/PageContent';
|
import PageContent from 'Components/Page/PageContent';
|
||||||
import PageContentBody from 'Components/Page/PageContentBody';
|
import PageContentBody from 'Components/Page/PageContentBody';
|
||||||
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
|
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
|
||||||
|
import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton';
|
||||||
|
import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator';
|
||||||
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
||||||
import FilterMenu from 'Components/Menu/FilterMenu';
|
import FilterMenu from 'Components/Menu/FilterMenu';
|
||||||
|
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper';
|
||||||
import Table from 'Components/Table/Table';
|
import Table from 'Components/Table/Table';
|
||||||
import TableBody from 'Components/Table/TableBody';
|
import TableBody from 'Components/Table/TableBody';
|
||||||
import NoSeries from 'Series/NoSeries';
|
import NoSeries from 'Series/NoSeries';
|
||||||
|
@ -18,58 +21,6 @@ import SeriesEditorRowConnector from './SeriesEditorRowConnector';
|
||||||
import SeriesEditorFooter from './SeriesEditorFooter';
|
import SeriesEditorFooter from './SeriesEditorFooter';
|
||||||
import SeriesEditorFilterModalConnector from './SeriesEditorFilterModalConnector';
|
import SeriesEditorFilterModalConnector from './SeriesEditorFilterModalConnector';
|
||||||
|
|
||||||
function getColumns(showLanguageProfile) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: 'status',
|
|
||||||
isSortable: true,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'sortTitle',
|
|
||||||
label: 'Title',
|
|
||||||
isSortable: true,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'qualityProfileId',
|
|
||||||
label: 'Quality Profile',
|
|
||||||
isSortable: true,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'languageProfileId',
|
|
||||||
label: 'Language Profile',
|
|
||||||
isSortable: true,
|
|
||||||
isVisible: showLanguageProfile
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'seriesType',
|
|
||||||
label: 'Series Type',
|
|
||||||
isSortable: false,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'seasonFolder',
|
|
||||||
label: 'Season Folder',
|
|
||||||
isSortable: true,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'path',
|
|
||||||
label: 'Path',
|
|
||||||
isSortable: true,
|
|
||||||
isVisible: true
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'tags',
|
|
||||||
label: 'Tags',
|
|
||||||
isSortable: false,
|
|
||||||
isVisible: true
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
class SeriesEditor extends Component {
|
class SeriesEditor extends Component {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -83,8 +34,7 @@ class SeriesEditor extends Component {
|
||||||
allUnselected: false,
|
allUnselected: false,
|
||||||
lastToggled: null,
|
lastToggled: null,
|
||||||
selectedState: {},
|
selectedState: {},
|
||||||
isOrganizingSeriesModalOpen: false,
|
isOrganizingSeriesModalOpen: false
|
||||||
columns: getColumns(props.showLanguageProfile)
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +102,7 @@ class SeriesEditor extends Component {
|
||||||
error,
|
error,
|
||||||
totalItems,
|
totalItems,
|
||||||
items,
|
items,
|
||||||
|
columns,
|
||||||
selectedFilterKey,
|
selectedFilterKey,
|
||||||
filters,
|
filters,
|
||||||
customFilters,
|
customFilters,
|
||||||
|
@ -162,7 +113,7 @@ class SeriesEditor extends Component {
|
||||||
isDeleting,
|
isDeleting,
|
||||||
deleteError,
|
deleteError,
|
||||||
isOrganizingSeries,
|
isOrganizingSeries,
|
||||||
showLanguageProfile,
|
onTableOptionChange,
|
||||||
onSortPress,
|
onSortPress,
|
||||||
onFilterSelect
|
onFilterSelect
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -170,8 +121,7 @@ class SeriesEditor extends Component {
|
||||||
const {
|
const {
|
||||||
allSelected,
|
allSelected,
|
||||||
allUnselected,
|
allUnselected,
|
||||||
selectedState,
|
selectedState
|
||||||
columns
|
|
||||||
} = this.state;
|
} = this.state;
|
||||||
|
|
||||||
const selectedSeriesIds = this.getSelectedIds();
|
const selectedSeriesIds = this.getSelectedIds();
|
||||||
|
@ -181,6 +131,18 @@ class SeriesEditor extends Component {
|
||||||
<PageToolbar>
|
<PageToolbar>
|
||||||
<PageToolbarSection />
|
<PageToolbarSection />
|
||||||
<PageToolbarSection alignContent={align.RIGHT}>
|
<PageToolbarSection alignContent={align.RIGHT}>
|
||||||
|
<TableOptionsModalWrapper
|
||||||
|
columns={columns}
|
||||||
|
onTableOptionChange={onTableOptionChange}
|
||||||
|
>
|
||||||
|
<PageToolbarButton
|
||||||
|
label="Options"
|
||||||
|
iconName={icons.TABLE}
|
||||||
|
/>
|
||||||
|
</TableOptionsModalWrapper>
|
||||||
|
|
||||||
|
<PageToolbarSeparator />
|
||||||
|
|
||||||
<FilterMenu
|
<FilterMenu
|
||||||
alignMenu={align.RIGHT}
|
alignMenu={align.RIGHT}
|
||||||
selectedFilterKey={selectedFilterKey}
|
selectedFilterKey={selectedFilterKey}
|
||||||
|
@ -249,7 +211,8 @@ class SeriesEditor extends Component {
|
||||||
isDeleting={isDeleting}
|
isDeleting={isDeleting}
|
||||||
deleteError={deleteError}
|
deleteError={deleteError}
|
||||||
isOrganizingSeries={isOrganizingSeries}
|
isOrganizingSeries={isOrganizingSeries}
|
||||||
showLanguageProfile={showLanguageProfile}
|
columns={columns}
|
||||||
|
showLanguageProfile={columns.find((column) => column.name === 'languageProfileId').isVisible}
|
||||||
onSaveSelected={this.onSaveSelected}
|
onSaveSelected={this.onSaveSelected}
|
||||||
onOrganizeSeriesPress={this.onOrganizeSeriesPress}
|
onOrganizeSeriesPress={this.onOrganizeSeriesPress}
|
||||||
/>
|
/>
|
||||||
|
@ -270,6 +233,7 @@ SeriesEditor.propTypes = {
|
||||||
error: PropTypes.object,
|
error: PropTypes.object,
|
||||||
totalItems: PropTypes.number.isRequired,
|
totalItems: PropTypes.number.isRequired,
|
||||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
sortKey: PropTypes.string,
|
sortKey: PropTypes.string,
|
||||||
sortDirection: PropTypes.oneOf(sortDirections.all),
|
sortDirection: PropTypes.oneOf(sortDirections.all),
|
||||||
selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||||
|
@ -280,7 +244,7 @@ SeriesEditor.propTypes = {
|
||||||
isDeleting: PropTypes.bool.isRequired,
|
isDeleting: PropTypes.bool.isRequired,
|
||||||
deleteError: PropTypes.object,
|
deleteError: PropTypes.object,
|
||||||
isOrganizingSeries: PropTypes.bool.isRequired,
|
isOrganizingSeries: PropTypes.bool.isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
onTableOptionChange: PropTypes.func.isRequired,
|
||||||
onSortPress: PropTypes.func.isRequired,
|
onSortPress: PropTypes.func.isRequired,
|
||||||
onFilterSelect: PropTypes.func.isRequired,
|
onFilterSelect: PropTypes.func.isRequired,
|
||||||
onSaveSelected: PropTypes.func.isRequired
|
onSaveSelected: PropTypes.func.isRequired
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { connect } from 'react-redux';
|
||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||||
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
|
||||||
import { setSeriesEditorSort, setSeriesEditorFilter, saveSeriesEditor } from 'Store/Actions/seriesEditorActions';
|
import { setSeriesEditorSort, setSeriesEditorFilter, setSeriesEditorTableOption, saveSeriesEditor } from 'Store/Actions/seriesEditorActions';
|
||||||
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
|
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
|
||||||
import { executeCommand } from 'Store/Actions/commandActions';
|
import { executeCommand } from 'Store/Actions/commandActions';
|
||||||
import * as commandNames from 'Commands/commandNames';
|
import * as commandNames from 'Commands/commandNames';
|
||||||
|
@ -12,13 +12,11 @@ import SeriesEditor from './SeriesEditor';
|
||||||
|
|
||||||
function createMapStateToProps() {
|
function createMapStateToProps() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state) => state.settings.languageProfiles,
|
|
||||||
createClientSideCollectionSelector('series', 'seriesEditor'),
|
createClientSideCollectionSelector('series', 'seriesEditor'),
|
||||||
createCommandExecutingSelector(commandNames.RENAME_SERIES),
|
createCommandExecutingSelector(commandNames.RENAME_SERIES),
|
||||||
(languageProfiles, series, isOrganizingSeries) => {
|
(series, isOrganizingSeries) => {
|
||||||
return {
|
return {
|
||||||
isOrganizingSeries,
|
isOrganizingSeries,
|
||||||
showLanguageProfile: languageProfiles.items.length > 1,
|
|
||||||
...series
|
...series
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -28,6 +26,7 @@ function createMapStateToProps() {
|
||||||
const mapDispatchToProps = {
|
const mapDispatchToProps = {
|
||||||
dispatchSetSeriesEditorSort: setSeriesEditorSort,
|
dispatchSetSeriesEditorSort: setSeriesEditorSort,
|
||||||
dispatchSetSeriesEditorFilter: setSeriesEditorFilter,
|
dispatchSetSeriesEditorFilter: setSeriesEditorFilter,
|
||||||
|
dispatchSetSeriesEditorTableOption: setSeriesEditorTableOption,
|
||||||
dispatchSaveSeriesEditor: saveSeriesEditor,
|
dispatchSaveSeriesEditor: saveSeriesEditor,
|
||||||
dispatchFetchRootFolders: fetchRootFolders,
|
dispatchFetchRootFolders: fetchRootFolders,
|
||||||
dispatchExecuteCommand: executeCommand
|
dispatchExecuteCommand: executeCommand
|
||||||
|
@ -53,6 +52,10 @@ class SeriesEditorConnector extends Component {
|
||||||
this.props.dispatchSetSeriesEditorFilter({ selectedFilterKey });
|
this.props.dispatchSetSeriesEditorFilter({ selectedFilterKey });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onTableOptionChange = (payload) => {
|
||||||
|
this.props.dispatchSetSeriesEditorTableOption(payload);
|
||||||
|
}
|
||||||
|
|
||||||
onSaveSelected = (payload) => {
|
onSaveSelected = (payload) => {
|
||||||
this.props.dispatchSaveSeriesEditor(payload);
|
this.props.dispatchSaveSeriesEditor(payload);
|
||||||
}
|
}
|
||||||
|
@ -74,6 +77,7 @@ class SeriesEditorConnector extends Component {
|
||||||
onSortPress={this.onSortPress}
|
onSortPress={this.onSortPress}
|
||||||
onFilterSelect={this.onFilterSelect}
|
onFilterSelect={this.onFilterSelect}
|
||||||
onSaveSelected={this.onSaveSelected}
|
onSaveSelected={this.onSaveSelected}
|
||||||
|
onTableOptionChange={this.onTableOptionChange}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -82,6 +86,7 @@ class SeriesEditorConnector extends Component {
|
||||||
SeriesEditorConnector.propTypes = {
|
SeriesEditorConnector.propTypes = {
|
||||||
dispatchSetSeriesEditorSort: PropTypes.func.isRequired,
|
dispatchSetSeriesEditorSort: PropTypes.func.isRequired,
|
||||||
dispatchSetSeriesEditorFilter: PropTypes.func.isRequired,
|
dispatchSetSeriesEditorFilter: PropTypes.func.isRequired,
|
||||||
|
dispatchSetSeriesEditorTableOption: PropTypes.func.isRequired,
|
||||||
dispatchSaveSeriesEditor: PropTypes.func.isRequired,
|
dispatchSaveSeriesEditor: PropTypes.func.isRequired,
|
||||||
dispatchFetchRootFolders: PropTypes.func.isRequired,
|
dispatchFetchRootFolders: PropTypes.func.isRequired,
|
||||||
dispatchExecuteCommand: PropTypes.func.isRequired
|
dispatchExecuteCommand: PropTypes.func.isRequired
|
||||||
|
|
|
@ -145,7 +145,7 @@ class SeriesEditorFooter extends Component {
|
||||||
isSaving,
|
isSaving,
|
||||||
isDeleting,
|
isDeleting,
|
||||||
isOrganizingSeries,
|
isOrganizingSeries,
|
||||||
showLanguageProfile,
|
columns,
|
||||||
onOrganizeSeriesPress
|
onOrganizeSeriesPress
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
|
@ -192,85 +192,130 @@ class SeriesEditorFooter extends Component {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
|
||||||
<SeriesEditorFooterLabel
|
|
||||||
label="Quality Profile"
|
|
||||||
isSaving={isSaving && qualityProfileId !== NO_CHANGE}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<QualityProfileSelectInputConnector
|
|
||||||
name="qualityProfileId"
|
|
||||||
value={qualityProfileId}
|
|
||||||
includeNoChange={true}
|
|
||||||
isDisabled={!selectedCount}
|
|
||||||
onChange={this.onInputChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
showLanguageProfile &&
|
columns.map((column) => {
|
||||||
<div className={styles.inputContainer}>
|
const {
|
||||||
<SeriesEditorFooterLabel
|
name,
|
||||||
label="Language Profile"
|
isVisible
|
||||||
isSaving={isSaving && languageProfileId !== NO_CHANGE}
|
} = column;
|
||||||
/>
|
|
||||||
|
|
||||||
<LanguageProfileSelectInputConnector
|
if (!isVisible) {
|
||||||
name="languageProfileId"
|
return null;
|
||||||
value={languageProfileId}
|
}
|
||||||
includeNoChange={true}
|
|
||||||
isDisabled={!selectedCount}
|
if (name === 'qualityProfileId') {
|
||||||
onChange={this.onInputChange}
|
return (
|
||||||
/>
|
<div
|
||||||
</div>
|
key={name}
|
||||||
|
className={styles.inputContainer}
|
||||||
|
>
|
||||||
|
<SeriesEditorFooterLabel
|
||||||
|
label="Quality Profile"
|
||||||
|
isSaving={isSaving && qualityProfileId !== NO_CHANGE}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<QualityProfileSelectInputConnector
|
||||||
|
name="qualityProfileId"
|
||||||
|
value={qualityProfileId}
|
||||||
|
includeNoChange={true}
|
||||||
|
isDisabled={!selectedCount}
|
||||||
|
onChange={this.onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'languageProfileId') {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={name}
|
||||||
|
className={styles.inputContainer}
|
||||||
|
>
|
||||||
|
<SeriesEditorFooterLabel
|
||||||
|
label="Language Profile"
|
||||||
|
isSaving={isSaving && languageProfileId !== NO_CHANGE}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<LanguageProfileSelectInputConnector
|
||||||
|
name="languageProfileId"
|
||||||
|
value={languageProfileId}
|
||||||
|
includeNoChange={true}
|
||||||
|
isDisabled={!selectedCount}
|
||||||
|
onChange={this.onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'seriesType') {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={name}
|
||||||
|
className={styles.inputContainer}
|
||||||
|
>
|
||||||
|
<SeriesEditorFooterLabel
|
||||||
|
label="Series Type"
|
||||||
|
isSaving={isSaving && seriesType !== NO_CHANGE}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SeriesTypeSelectInput
|
||||||
|
name="seriesType"
|
||||||
|
value={seriesType}
|
||||||
|
includeNoChange={true}
|
||||||
|
isDisabled={!selectedCount}
|
||||||
|
onChange={this.onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'seasonFolder') {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={name}
|
||||||
|
className={styles.inputContainer}
|
||||||
|
>
|
||||||
|
<SeriesEditorFooterLabel
|
||||||
|
label="Season Folder"
|
||||||
|
isSaving={isSaving && seasonFolder !== NO_CHANGE}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SelectInput
|
||||||
|
name="seasonFolder"
|
||||||
|
value={seasonFolder}
|
||||||
|
values={seasonFolderOptions}
|
||||||
|
isDisabled={!selectedCount}
|
||||||
|
onChange={this.onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'path') {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={name}
|
||||||
|
className={styles.inputContainer}
|
||||||
|
>
|
||||||
|
<SeriesEditorFooterLabel
|
||||||
|
label="Root Folder"
|
||||||
|
isSaving={isSaving && rootFolderPath !== NO_CHANGE}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<RootFolderSelectInputConnector
|
||||||
|
name="rootFolderPath"
|
||||||
|
value={rootFolderPath}
|
||||||
|
includeNoChange={true}
|
||||||
|
isDisabled={!selectedCount}
|
||||||
|
selectedValueOptions={{ includeFreeSpace: false }}
|
||||||
|
onChange={this.onInputChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
|
||||||
<SeriesEditorFooterLabel
|
|
||||||
label="Series Type"
|
|
||||||
isSaving={isSaving && seriesType !== NO_CHANGE}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SeriesTypeSelectInput
|
|
||||||
name="seriesType"
|
|
||||||
value={seriesType}
|
|
||||||
includeNoChange={true}
|
|
||||||
isDisabled={!selectedCount}
|
|
||||||
onChange={this.onInputChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
|
||||||
<SeriesEditorFooterLabel
|
|
||||||
label="Season Folder"
|
|
||||||
isSaving={isSaving && seasonFolder !== NO_CHANGE}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<SelectInput
|
|
||||||
name="seasonFolder"
|
|
||||||
value={seasonFolder}
|
|
||||||
values={seasonFolderOptions}
|
|
||||||
isDisabled={!selectedCount}
|
|
||||||
onChange={this.onInputChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.inputContainer}>
|
|
||||||
<SeriesEditorFooterLabel
|
|
||||||
label="Root Folder"
|
|
||||||
isSaving={isSaving && rootFolderPath !== NO_CHANGE}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<RootFolderSelectInputConnector
|
|
||||||
name="rootFolderPath"
|
|
||||||
value={rootFolderPath}
|
|
||||||
includeNoChange={true}
|
|
||||||
isDisabled={!selectedCount}
|
|
||||||
selectedValueOptions={{ includeFreeSpace: false }}
|
|
||||||
onChange={this.onInputChange}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className={styles.buttonContainer}>
|
<div className={styles.buttonContainer}>
|
||||||
<div className={styles.buttonContainerContent}>
|
<div className={styles.buttonContainerContent}>
|
||||||
<SeriesEditorFooterLabel
|
<SeriesEditorFooterLabel
|
||||||
|
@ -346,6 +391,7 @@ SeriesEditorFooter.propTypes = {
|
||||||
deleteError: PropTypes.object,
|
deleteError: PropTypes.object,
|
||||||
isOrganizingSeries: PropTypes.bool.isRequired,
|
isOrganizingSeries: PropTypes.bool.isRequired,
|
||||||
showLanguageProfile: PropTypes.bool.isRequired,
|
showLanguageProfile: PropTypes.bool.isRequired,
|
||||||
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
onSaveSelected: PropTypes.func.isRequired,
|
onSaveSelected: PropTypes.func.isRequired,
|
||||||
onOrganizeSeriesPress: PropTypes.func.isRequired
|
onOrganizeSeriesPress: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import _ from 'lodash';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import titleCase from 'Utilities/String/titleCase';
|
import titleCase from 'Utilities/String/titleCase';
|
||||||
|
import formatBytes from 'Utilities/Number/formatBytes';
|
||||||
import TagListConnector from 'Components/TagListConnector';
|
import TagListConnector from 'Components/TagListConnector';
|
||||||
import CheckInput from 'Components/Form/CheckInput';
|
import CheckInput from 'Components/Form/CheckInput';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
|
@ -36,6 +36,7 @@ class SeriesEditorRow extends Component {
|
||||||
seriesType,
|
seriesType,
|
||||||
seasonFolder,
|
seasonFolder,
|
||||||
path,
|
path,
|
||||||
|
statistics,
|
||||||
tags,
|
tags,
|
||||||
columns,
|
columns,
|
||||||
isSelected,
|
isSelected,
|
||||||
|
@ -50,51 +51,109 @@ class SeriesEditorRow extends Component {
|
||||||
onSelectedChange={onSelectedChange}
|
onSelectedChange={onSelectedChange}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SeriesStatusCell
|
|
||||||
monitored={monitored}
|
|
||||||
status={status}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TableRowCell className={styles.title}>
|
|
||||||
<SeriesTitleLink
|
|
||||||
titleSlug={titleSlug}
|
|
||||||
title={title}
|
|
||||||
/>
|
|
||||||
</TableRowCell>
|
|
||||||
|
|
||||||
<TableRowCell>
|
|
||||||
{qualityProfile.name}
|
|
||||||
</TableRowCell>
|
|
||||||
|
|
||||||
{
|
{
|
||||||
_.find(columns, { name: 'languageProfileId' }).isVisible &&
|
columns.map((column) => {
|
||||||
<TableRowCell>
|
const {
|
||||||
{languageProfile.name}
|
name,
|
||||||
</TableRowCell>
|
isVisible
|
||||||
|
} = column;
|
||||||
|
|
||||||
|
if (!isVisible) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'status') {
|
||||||
|
return (
|
||||||
|
<SeriesStatusCell
|
||||||
|
key={name}
|
||||||
|
monitored={monitored}
|
||||||
|
status={status}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'sortTitle') {
|
||||||
|
return (
|
||||||
|
<TableRowCell
|
||||||
|
key={name}
|
||||||
|
className={styles.title}
|
||||||
|
>
|
||||||
|
<SeriesTitleLink
|
||||||
|
|
||||||
|
titleSlug={titleSlug}
|
||||||
|
title={title}
|
||||||
|
/>
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'qualityProfileId') {
|
||||||
|
return (
|
||||||
|
<TableRowCell key={name}>
|
||||||
|
{qualityProfile.name}
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'languageProfileId') {
|
||||||
|
return (
|
||||||
|
<TableRowCell key={name}>
|
||||||
|
{languageProfile.name}
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'seriesType') {
|
||||||
|
return (
|
||||||
|
<TableRowCell key={name}>
|
||||||
|
{titleCase(seriesType)}
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'seasonFolder') {
|
||||||
|
return (
|
||||||
|
<TableRowCell
|
||||||
|
key={name}
|
||||||
|
className={styles.seasonFolder}
|
||||||
|
>
|
||||||
|
<CheckInput
|
||||||
|
name="seasonFolder"
|
||||||
|
value={seasonFolder}
|
||||||
|
isDisabled={true}
|
||||||
|
onChange={this.onSeasonFolderChange}
|
||||||
|
/>
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'path') {
|
||||||
|
return (
|
||||||
|
<TableRowCell key={name}>
|
||||||
|
{path}
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'sizeOnDisk') {
|
||||||
|
return (
|
||||||
|
<TableRowCell key={name}>
|
||||||
|
{formatBytes(statistics.sizeOnDisk)}
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (name === 'tags') {
|
||||||
|
return (
|
||||||
|
<TableRowCell key={name}>
|
||||||
|
<TagListConnector
|
||||||
|
tags={tags}
|
||||||
|
/>
|
||||||
|
</TableRowCell>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
<TableRowCell>
|
|
||||||
{titleCase(seriesType)}
|
|
||||||
</TableRowCell>
|
|
||||||
|
|
||||||
<TableRowCell className={styles.seasonFolder}>
|
|
||||||
<CheckInput
|
|
||||||
name="seasonFolder"
|
|
||||||
value={seasonFolder}
|
|
||||||
isDisabled={true}
|
|
||||||
onChange={this.onSeasonFolderChange}
|
|
||||||
/>
|
|
||||||
</TableRowCell>
|
|
||||||
|
|
||||||
<TableRowCell>
|
|
||||||
{path}
|
|
||||||
</TableRowCell>
|
|
||||||
|
|
||||||
<TableRowCell>
|
|
||||||
<TagListConnector
|
|
||||||
tags={tags}
|
|
||||||
/>
|
|
||||||
</TableRowCell>
|
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -111,6 +170,7 @@ SeriesEditorRow.propTypes = {
|
||||||
seriesType: PropTypes.string.isRequired,
|
seriesType: PropTypes.string.isRequired,
|
||||||
seasonFolder: PropTypes.bool.isRequired,
|
seasonFolder: PropTypes.bool.isRequired,
|
||||||
path: PropTypes.string.isRequired,
|
path: PropTypes.string.isRequired,
|
||||||
|
statistics: PropTypes.object.isRequired,
|
||||||
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
tags: PropTypes.arrayOf(PropTypes.number).isRequired,
|
||||||
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
isSelected: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
|
|
|
@ -140,6 +140,12 @@ export const sortPredicates = {
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
sizeOnDisk: function(item) {
|
||||||
|
const { statistics = {} } = item;
|
||||||
|
|
||||||
|
return statistics.sizeOnDisk;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { batchActions } from 'redux-batched-actions';
|
||||||
import createAjaxRequest from 'Utilities/createAjaxRequest';
|
import createAjaxRequest from 'Utilities/createAjaxRequest';
|
||||||
import { filterBuilderTypes, filterBuilderValueTypes, sortDirections } from 'Helpers/Props';
|
import { filterBuilderTypes, filterBuilderValueTypes, sortDirections } from 'Helpers/Props';
|
||||||
import { createThunk, handleThunks } from 'Store/thunks';
|
import { createThunk, handleThunks } from 'Store/thunks';
|
||||||
|
import createSetTableOptionReducer from './Creators/Reducers/createSetTableOptionReducer';
|
||||||
import createSetClientSideCollectionSortReducer from './Creators/Reducers/createSetClientSideCollectionSortReducer';
|
import createSetClientSideCollectionSortReducer from './Creators/Reducers/createSetClientSideCollectionSortReducer';
|
||||||
import createSetClientSideCollectionFilterReducer from './Creators/Reducers/createSetClientSideCollectionFilterReducer';
|
import createSetClientSideCollectionFilterReducer from './Creators/Reducers/createSetClientSideCollectionFilterReducer';
|
||||||
import createHandleActions from './Creators/createHandleActions';
|
import createHandleActions from './Creators/createHandleActions';
|
||||||
|
@ -30,6 +31,65 @@ export const defaultState = {
|
||||||
filters,
|
filters,
|
||||||
filterPredicates,
|
filterPredicates,
|
||||||
|
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
name: 'status',
|
||||||
|
columnLabel: 'Status',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true,
|
||||||
|
isModifiable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sortTitle',
|
||||||
|
label: 'Series Title',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true,
|
||||||
|
isModifiable: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'qualityProfileId',
|
||||||
|
label: 'Quality Profile',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'languageProfileId',
|
||||||
|
label: 'Language Profile',
|
||||||
|
isSortable: false,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'seriesType',
|
||||||
|
label: 'Type',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'seasonFolder',
|
||||||
|
label: 'Season Folder',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'path',
|
||||||
|
label: 'Path',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'sizeOnDisk',
|
||||||
|
label: 'Size on Disk',
|
||||||
|
isSortable: true,
|
||||||
|
isVisible: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'tags',
|
||||||
|
label: 'Tags',
|
||||||
|
isSortable: false,
|
||||||
|
isVisible: true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
filterBuilderProps: [
|
filterBuilderProps: [
|
||||||
{
|
{
|
||||||
name: 'monitored',
|
name: 'monitored',
|
||||||
|
@ -70,6 +130,12 @@ export const defaultState = {
|
||||||
label: 'Root Folder Path',
|
label: 'Root Folder Path',
|
||||||
type: filterBuilderTypes.EXACT
|
type: filterBuilderTypes.EXACT
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: 'sizeOnDisk',
|
||||||
|
label: 'Size on Disk',
|
||||||
|
type: filterBuilderTypes.NUMBER,
|
||||||
|
valueType: filterBuilderValueTypes.BYTES
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'tags',
|
name: 'tags',
|
||||||
label: 'Tags',
|
label: 'Tags',
|
||||||
|
@ -95,6 +161,8 @@ export const SET_SERIES_EDITOR_SORT = 'seriesEditor/setSeriesEditorSort';
|
||||||
export const SET_SERIES_EDITOR_FILTER = 'seriesEditor/setSeriesEditorFilter';
|
export const SET_SERIES_EDITOR_FILTER = 'seriesEditor/setSeriesEditorFilter';
|
||||||
export const SAVE_SERIES_EDITOR = 'seriesEditor/saveSeriesEditor';
|
export const SAVE_SERIES_EDITOR = 'seriesEditor/saveSeriesEditor';
|
||||||
export const BULK_DELETE_SERIES = 'seriesEditor/bulkDeleteSeries';
|
export const BULK_DELETE_SERIES = 'seriesEditor/bulkDeleteSeries';
|
||||||
|
export const SET_SERIES_EDITOR_TABLE_OPTION = 'seriesIndex/setSeriesEditorTableOption';
|
||||||
|
|
||||||
//
|
//
|
||||||
// Action Creators
|
// Action Creators
|
||||||
|
|
||||||
|
@ -102,6 +170,8 @@ export const setSeriesEditorSort = createAction(SET_SERIES_EDITOR_SORT);
|
||||||
export const setSeriesEditorFilter = createAction(SET_SERIES_EDITOR_FILTER);
|
export const setSeriesEditorFilter = createAction(SET_SERIES_EDITOR_FILTER);
|
||||||
export const saveSeriesEditor = createThunk(SAVE_SERIES_EDITOR);
|
export const saveSeriesEditor = createThunk(SAVE_SERIES_EDITOR);
|
||||||
export const bulkDeleteSeries = createThunk(BULK_DELETE_SERIES);
|
export const bulkDeleteSeries = createThunk(BULK_DELETE_SERIES);
|
||||||
|
export const setSeriesEditorTableOption = createAction(SET_SERIES_EDITOR_TABLE_OPTION);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Action Handlers
|
// Action Handlers
|
||||||
|
|
||||||
|
@ -184,6 +254,7 @@ export const actionHandlers = handleThunks({
|
||||||
|
|
||||||
export const reducers = createHandleActions({
|
export const reducers = createHandleActions({
|
||||||
|
|
||||||
|
[SET_SERIES_EDITOR_TABLE_OPTION]: createSetTableOptionReducer(section),
|
||||||
[SET_SERIES_EDITOR_SORT]: createSetClientSideCollectionSortReducer(section),
|
[SET_SERIES_EDITOR_SORT]: createSetClientSideCollectionSortReducer(section),
|
||||||
[SET_SERIES_EDITOR_FILTER]: createSetClientSideCollectionFilterReducer(section)
|
[SET_SERIES_EDITOR_FILTER]: createSetClientSideCollectionFilterReducer(section)
|
||||||
|
|
||||||
|
|
|
@ -236,12 +236,6 @@ export const defaultState = {
|
||||||
return statistics.seasonCount;
|
return statistics.seasonCount;
|
||||||
},
|
},
|
||||||
|
|
||||||
sizeOnDisk: function(item) {
|
|
||||||
const { statistics = {} } = item;
|
|
||||||
|
|
||||||
return statistics.sizeOnDisk;
|
|
||||||
},
|
|
||||||
|
|
||||||
ratings: function(item) {
|
ratings: function(item) {
|
||||||
const { ratings = {} } = item;
|
const { ratings = {} } = item;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue