Remove Season Pass
This commit is contained in:
parent
67232290e5
commit
6fce6c2bbc
|
@ -9,7 +9,6 @@ import ImportSeries from 'AddSeries/ImportSeries/ImportSeries';
|
|||
import CalendarPageConnector from 'Calendar/CalendarPageConnector';
|
||||
import NotFound from 'Components/NotFound';
|
||||
import Switch from 'Components/Router/Switch';
|
||||
import SeasonPassConnector from 'SeasonPass/SeasonPassConnector';
|
||||
import SeriesDetailsPageConnector from 'Series/Details/SeriesDetailsPageConnector';
|
||||
import SeriesIndex from 'Series/Index/SeriesIndex';
|
||||
import CustomFormatSettingsConnector from 'Settings/CustomFormats/CustomFormatSettingsConnector';
|
||||
|
@ -95,7 +94,15 @@ function AppRoutes(props) {
|
|||
|
||||
<Route
|
||||
path="/seasonpass"
|
||||
component={SeasonPassConnector}
|
||||
exact={true}
|
||||
render={() => {
|
||||
return (
|
||||
<Redirect
|
||||
to={getPathWithUrlBase('/')}
|
||||
component={app}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Route
|
||||
|
|
|
@ -31,10 +31,6 @@ const links = [
|
|||
{
|
||||
title: 'Library Import',
|
||||
to: '/add/import'
|
||||
},
|
||||
{
|
||||
title: 'Season Pass',
|
||||
to: '/seasonpass'
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -1,217 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
|
||||
import FilterMenu from 'Components/Menu/FilterMenu';
|
||||
import PageContent from 'Components/Page/PageContent';
|
||||
import PageContentBody from 'Components/Page/PageContentBody';
|
||||
import PageToolbar from 'Components/Page/Toolbar/PageToolbar';
|
||||
import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
|
||||
import Table from 'Components/Table/Table';
|
||||
import TableBody from 'Components/Table/TableBody';
|
||||
import { align, sortDirections } from 'Helpers/Props';
|
||||
import NoSeries from 'Series/NoSeries';
|
||||
import getSelectedIds from 'Utilities/Table/getSelectedIds';
|
||||
import selectAll from 'Utilities/Table/selectAll';
|
||||
import toggleSelected from 'Utilities/Table/toggleSelected';
|
||||
import SeasonPassFilterModalConnector from './SeasonPassFilterModalConnector';
|
||||
import SeasonPassFooter from './SeasonPassFooter';
|
||||
import SeasonPassRowConnector from './SeasonPassRowConnector';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
name: 'status',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'sortTitle',
|
||||
label: 'Title',
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'monitored',
|
||||
isVisible: true
|
||||
},
|
||||
{
|
||||
name: 'seasonCount',
|
||||
label: 'Seasons',
|
||||
isSortable: true,
|
||||
isVisible: true
|
||||
}
|
||||
];
|
||||
|
||||
class SeasonPass extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
allSelected: false,
|
||||
allUnselected: false,
|
||||
lastToggled: null,
|
||||
selectedState: {}
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
isSaving,
|
||||
saveError
|
||||
} = this.props;
|
||||
|
||||
if (prevProps.isSaving && !isSaving && !saveError) {
|
||||
this.onSelectAllChange({ value: false });
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Control
|
||||
|
||||
getSelectedIds = () => {
|
||||
return getSelectedIds(this.state.selectedState);
|
||||
};
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onSelectAllChange = ({ value }) => {
|
||||
this.setState(selectAll(this.state.selectedState, value));
|
||||
};
|
||||
|
||||
onSelectedChange = ({ id, value, shiftKey = false }) => {
|
||||
this.setState((state) => {
|
||||
return toggleSelected(state, this.props.items, id, value, shiftKey);
|
||||
});
|
||||
};
|
||||
|
||||
onUpdateSelectedPress = (changes) => {
|
||||
this.props.onUpdateSelectedPress({
|
||||
seriesIds: this.getSelectedIds(),
|
||||
...changes
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
isFetching,
|
||||
isPopulated,
|
||||
error,
|
||||
totalItems,
|
||||
items,
|
||||
selectedFilterKey,
|
||||
filters,
|
||||
customFilters,
|
||||
sortKey,
|
||||
sortDirection,
|
||||
isSaving,
|
||||
saveError,
|
||||
onSortPress,
|
||||
onFilterSelect
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
allSelected,
|
||||
allUnselected,
|
||||
selectedState
|
||||
} = this.state;
|
||||
|
||||
return (
|
||||
<PageContent title="Season Pass">
|
||||
<PageToolbar>
|
||||
<PageToolbarSection />
|
||||
<PageToolbarSection alignContent={align.RIGHT}>
|
||||
<FilterMenu
|
||||
alignMenu={align.RIGHT}
|
||||
selectedFilterKey={selectedFilterKey}
|
||||
filters={filters}
|
||||
customFilters={customFilters}
|
||||
filterModalConnectorComponent={SeasonPassFilterModalConnector}
|
||||
onFilterSelect={onFilterSelect}
|
||||
/>
|
||||
</PageToolbarSection>
|
||||
</PageToolbar>
|
||||
|
||||
<PageContentBody>
|
||||
{
|
||||
isFetching && !isPopulated &&
|
||||
<LoadingIndicator />
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>Unable to load the calendar</div>
|
||||
}
|
||||
|
||||
{
|
||||
!error && isPopulated && !!items.length &&
|
||||
<div>
|
||||
<Table
|
||||
columns={columns}
|
||||
sortKey={sortKey}
|
||||
sortDirection={sortDirection}
|
||||
selectAll={true}
|
||||
allSelected={allSelected}
|
||||
allUnselected={allUnselected}
|
||||
onSortPress={onSortPress}
|
||||
onSelectAllChange={this.onSelectAllChange}
|
||||
>
|
||||
<TableBody>
|
||||
{
|
||||
items.map((item) => {
|
||||
return (
|
||||
<SeasonPassRowConnector
|
||||
key={item.id}
|
||||
seriesId={item.id}
|
||||
isSelected={selectedState[item.id]}
|
||||
onSelectedChange={this.onSelectedChange}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!error && isPopulated && !items.length &&
|
||||
<NoSeries totalItems={totalItems} />
|
||||
}
|
||||
</PageContentBody>
|
||||
|
||||
<SeasonPassFooter
|
||||
selectedCount={this.getSelectedIds().length}
|
||||
isSaving={isSaving}
|
||||
saveError={saveError}
|
||||
onUpdateSelectedPress={this.onUpdateSelectedPress}
|
||||
/>
|
||||
</PageContent>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SeasonPass.propTypes = {
|
||||
isFetching: PropTypes.bool.isRequired,
|
||||
isPopulated: PropTypes.bool.isRequired,
|
||||
error: PropTypes.object,
|
||||
totalItems: PropTypes.number.isRequired,
|
||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
sortKey: PropTypes.string,
|
||||
sortDirection: PropTypes.oneOf(sortDirections.all),
|
||||
selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||
filters: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
customFilters: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
saveError: PropTypes.object,
|
||||
onSortPress: PropTypes.func.isRequired,
|
||||
onFilterSelect: PropTypes.func.isRequired,
|
||||
onUpdateSelectedPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default SeasonPass;
|
|
@ -1,64 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import { saveSeasonPass, setSeasonPassFilter, setSeasonPassSort } from 'Store/Actions/seasonPassActions';
|
||||
import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector';
|
||||
import SeasonPass from './SeasonPass';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createClientSideCollectionSelector('series', 'seasonPass'),
|
||||
(series) => {
|
||||
return {
|
||||
...series
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setSeasonPassSort,
|
||||
setSeasonPassFilter,
|
||||
saveSeasonPass
|
||||
};
|
||||
|
||||
class SeasonPassConnector extends Component {
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onSortPress = (sortKey) => {
|
||||
this.props.setSeasonPassSort({ sortKey });
|
||||
};
|
||||
|
||||
onFilterSelect = (selectedFilterKey) => {
|
||||
this.props.setSeasonPassFilter({ selectedFilterKey });
|
||||
};
|
||||
|
||||
onUpdateSelectedPress = (payload) => {
|
||||
this.props.saveSeasonPass(payload);
|
||||
};
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SeasonPass
|
||||
{...this.props}
|
||||
onSortPress={this.onSortPress}
|
||||
onFilterSelect={this.onFilterSelect}
|
||||
onUpdateSelectedPress={this.onUpdateSelectedPress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SeasonPassConnector.propTypes = {
|
||||
setSeasonPassSort: PropTypes.func.isRequired,
|
||||
setSeasonPassFilter: PropTypes.func.isRequired,
|
||||
saveSeasonPass: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(SeasonPassConnector);
|
|
@ -1,24 +0,0 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { createSelector } from 'reselect';
|
||||
import FilterModal from 'Components/Filter/FilterModal';
|
||||
import { setSeasonPassFilter } from 'Store/Actions/seasonPassActions';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
(state) => state.series.items,
|
||||
(state) => state.seasonPass.filterBuilderProps,
|
||||
(sectionItems, filterBuilderProps) => {
|
||||
return {
|
||||
sectionItems,
|
||||
filterBuilderProps,
|
||||
customFilterType: 'series'
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
dispatchSetFilter: setSeasonPassFilter
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(FilterModal);
|
|
@ -1,14 +0,0 @@
|
|||
.inputContainer {
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-bottom: 3px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.updateSelectedButton {
|
||||
composes: button from '~Components/Link/SpinnerButton.css';
|
||||
|
||||
height: 35px;
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import MonitorEpisodesSelectInput from 'Components/Form/MonitorEpisodesSelectInput';
|
||||
import SelectInput from 'Components/Form/SelectInput';
|
||||
import SpinnerButton from 'Components/Link/SpinnerButton';
|
||||
import PageContentFooter from 'Components/Page/PageContentFooter';
|
||||
import { kinds } from 'Helpers/Props';
|
||||
import styles from './SeasonPassFooter.css';
|
||||
|
||||
const NO_CHANGE = 'noChange';
|
||||
|
||||
class SeasonPassFooter extends Component {
|
||||
|
||||
//
|
||||
// Lifecycle
|
||||
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this.state = {
|
||||
monitored: NO_CHANGE,
|
||||
monitor: NO_CHANGE
|
||||
};
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
const {
|
||||
isSaving,
|
||||
saveError
|
||||
} = prevProps;
|
||||
|
||||
if (prevProps.isSaving && !isSaving && !saveError) {
|
||||
this.setState({
|
||||
monitored: NO_CHANGE,
|
||||
monitor: NO_CHANGE
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onInputChange = ({ name, value }) => {
|
||||
this.setState({ [name]: value });
|
||||
};
|
||||
|
||||
onUpdateSelectedPress = () => {
|
||||
const {
|
||||
monitor,
|
||||
monitored
|
||||
} = this.state;
|
||||
|
||||
const changes = {};
|
||||
|
||||
if (monitored !== NO_CHANGE) {
|
||||
changes.monitored = monitored === 'monitored';
|
||||
}
|
||||
|
||||
if (monitor !== NO_CHANGE) {
|
||||
changes.monitor = monitor;
|
||||
}
|
||||
|
||||
this.props.onUpdateSelectedPress(changes);
|
||||
};
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
selectedCount,
|
||||
isSaving
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
monitored,
|
||||
monitor
|
||||
} = this.state;
|
||||
|
||||
const monitoredOptions = [
|
||||
{ key: NO_CHANGE, value: 'No Change', disabled: true },
|
||||
{ key: 'monitored', value: 'Monitored' },
|
||||
{ key: 'unmonitored', value: 'Unmonitored' }
|
||||
];
|
||||
|
||||
const noChanges = monitored === NO_CHANGE && monitor === NO_CHANGE;
|
||||
|
||||
return (
|
||||
<PageContentFooter>
|
||||
<div className={styles.inputContainer}>
|
||||
<div className={styles.label}>
|
||||
Monitor Series
|
||||
</div>
|
||||
|
||||
<SelectInput
|
||||
name="monitored"
|
||||
value={monitored}
|
||||
values={monitoredOptions}
|
||||
isDisabled={!selectedCount}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.inputContainer}>
|
||||
<div className={styles.label}>
|
||||
Monitor Episodes
|
||||
</div>
|
||||
|
||||
<MonitorEpisodesSelectInput
|
||||
name="monitor"
|
||||
value={monitor}
|
||||
includeNoChange={true}
|
||||
isDisabled={!selectedCount}
|
||||
onChange={this.onInputChange}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className={styles.label}>
|
||||
{selectedCount} Series Selected
|
||||
</div>
|
||||
|
||||
<SpinnerButton
|
||||
className={styles.updateSelectedButton}
|
||||
kind={kinds.PRIMARY}
|
||||
isSpinning={isSaving}
|
||||
isDisabled={!selectedCount || noChanges}
|
||||
onPress={this.onUpdateSelectedPress}
|
||||
>
|
||||
Update Selected
|
||||
</SpinnerButton>
|
||||
</div>
|
||||
</PageContentFooter>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SeasonPassFooter.propTypes = {
|
||||
selectedCount: PropTypes.number.isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
saveError: PropTypes.object,
|
||||
onUpdateSelectedPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default SeasonPassFooter;
|
|
@ -1,20 +0,0 @@
|
|||
.status,
|
||||
.monitored {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.title {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
width: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.seasons {
|
||||
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
|
@ -1,103 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import Icon from 'Components/Icon';
|
||||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||
import TableRow from 'Components/Table/TableRow';
|
||||
import { getSeriesStatusDetails } from 'Series/SeriesStatus';
|
||||
import SeriesTitleLink from 'Series/SeriesTitleLink';
|
||||
import SeasonPassSeason from './SeasonPassSeason';
|
||||
import styles from './SeasonPassRow.css';
|
||||
|
||||
class SeasonPassRow extends Component {
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
seriesId,
|
||||
monitored,
|
||||
status,
|
||||
title,
|
||||
titleSlug,
|
||||
seasons,
|
||||
isSaving,
|
||||
isSelected,
|
||||
onSelectedChange,
|
||||
onSeriesMonitoredPress,
|
||||
onSeasonMonitoredPress
|
||||
} = this.props;
|
||||
|
||||
const statusDetails = getSeriesStatusDetails(status);
|
||||
|
||||
return (
|
||||
<TableRow>
|
||||
<TableSelectCell
|
||||
id={seriesId}
|
||||
isSelected={isSelected}
|
||||
onSelectedChange={onSelectedChange}
|
||||
/>
|
||||
|
||||
<TableRowCell className={styles.status}>
|
||||
<Icon
|
||||
className={styles.statusIcon}
|
||||
name={statusDetails.icon}
|
||||
title={statusDetails.title}
|
||||
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.title}>
|
||||
<SeriesTitleLink
|
||||
titleSlug={titleSlug}
|
||||
title={title}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.monitored}>
|
||||
<MonitorToggleButton
|
||||
monitored={monitored}
|
||||
isSaving={isSaving}
|
||||
onPress={onSeriesMonitoredPress}
|
||||
/>
|
||||
</TableRowCell>
|
||||
|
||||
<TableRowCell className={styles.seasons}>
|
||||
{
|
||||
seasons.map((season) => {
|
||||
return (
|
||||
<SeasonPassSeason
|
||||
key={season.seasonNumber}
|
||||
{...season}
|
||||
onSeasonMonitoredPress={onSeasonMonitoredPress}
|
||||
/>
|
||||
);
|
||||
})
|
||||
}
|
||||
</TableRowCell>
|
||||
</TableRow>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SeasonPassRow.propTypes = {
|
||||
seriesId: PropTypes.number.isRequired,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
status: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
titleSlug: PropTypes.string.isRequired,
|
||||
seasons: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
isSelected: PropTypes.bool,
|
||||
onSelectedChange: PropTypes.func.isRequired,
|
||||
onSeriesMonitoredPress: PropTypes.func.isRequired,
|
||||
onSeasonMonitoredPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
SeasonPassRow.defaultProps = {
|
||||
isSaving: false
|
||||
};
|
||||
|
||||
export default SeasonPassRow;
|
|
@ -1,77 +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 { toggleSeasonMonitored, toggleSeriesMonitored } from 'Store/Actions/seriesActions';
|
||||
import createSeriesSelector from 'Store/Selectors/createSeriesSelector';
|
||||
import SeasonPassRow from './SeasonPassRow';
|
||||
|
||||
function createMapStateToProps() {
|
||||
return createSelector(
|
||||
createSeriesSelector(),
|
||||
(series) => {
|
||||
return _.pick(series, [
|
||||
'status',
|
||||
'titleSlug',
|
||||
'title',
|
||||
'monitored',
|
||||
'seasons',
|
||||
'isSaving'
|
||||
]);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const mapDispatchToProps = {
|
||||
toggleSeriesMonitored,
|
||||
toggleSeasonMonitored
|
||||
};
|
||||
|
||||
class SeasonPassRowConnector extends Component {
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onSeriesMonitoredPress = () => {
|
||||
const {
|
||||
seriesId,
|
||||
monitored
|
||||
} = this.props;
|
||||
|
||||
this.props.toggleSeriesMonitored({
|
||||
seriesId,
|
||||
monitored: !monitored
|
||||
});
|
||||
};
|
||||
|
||||
onSeasonMonitoredPress = (seasonNumber, monitored) => {
|
||||
this.props.toggleSeasonMonitored({
|
||||
seriesId: this.props.seriesId,
|
||||
seasonNumber,
|
||||
monitored
|
||||
});
|
||||
};
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SeasonPassRow
|
||||
{...this.props}
|
||||
onSeriesMonitoredPress={this.onSeriesMonitoredPress}
|
||||
onSeasonMonitoredPress={this.onSeasonMonitoredPress}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SeasonPassRowConnector.propTypes = {
|
||||
seriesId: PropTypes.number.isRequired,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
toggleSeriesMonitored: PropTypes.func.isRequired,
|
||||
toggleSeasonMonitored: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default connect(createMapStateToProps, mapDispatchToProps)(SeasonPassRowConnector);
|
|
@ -1,25 +0,0 @@
|
|||
.season {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
margin: 2px 4px;
|
||||
border: 1px solid var(--borderColor);
|
||||
border-radius: 4px;
|
||||
background-color: var(--seasonBackgroundColor);
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.episodes {
|
||||
padding: 0 4px;
|
||||
background-color: var(--episodesBackgroundColor);
|
||||
color: var(--defaultColor);
|
||||
}
|
||||
|
||||
.allEpisodes {
|
||||
background-color: #e0ffe0;
|
||||
color: var(--darkGray);
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
import classNames from 'classnames';
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import MonitorToggleButton from 'Components/MonitorToggleButton';
|
||||
import padNumber from 'Utilities/Number/padNumber';
|
||||
import styles from './SeasonPassSeason.css';
|
||||
|
||||
class SeasonPassSeason extends Component {
|
||||
|
||||
//
|
||||
// Listeners
|
||||
|
||||
onSeasonMonitoredPress = () => {
|
||||
const {
|
||||
seasonNumber,
|
||||
monitored
|
||||
} = this.props;
|
||||
|
||||
this.props.onSeasonMonitoredPress(seasonNumber, !monitored);
|
||||
};
|
||||
|
||||
//
|
||||
// Render
|
||||
|
||||
render() {
|
||||
const {
|
||||
seasonNumber,
|
||||
monitored,
|
||||
statistics,
|
||||
isSaving
|
||||
} = this.props;
|
||||
|
||||
const {
|
||||
episodeFileCount,
|
||||
totalEpisodeCount,
|
||||
percentOfEpisodes
|
||||
} = statistics;
|
||||
|
||||
return (
|
||||
<div className={styles.season}>
|
||||
<div className={styles.info}>
|
||||
<MonitorToggleButton
|
||||
monitored={monitored}
|
||||
isSaving={isSaving}
|
||||
onPress={this.onSeasonMonitoredPress}
|
||||
/>
|
||||
|
||||
<span>
|
||||
{
|
||||
seasonNumber === 0 ? 'Specials' : `S${padNumber(seasonNumber, 2)}`
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={classNames(
|
||||
styles.episodes,
|
||||
percentOfEpisodes === 100 && styles.allEpisodes
|
||||
)}
|
||||
title={`${episodeFileCount}/${totalEpisodeCount} episodes downloaded`}
|
||||
>
|
||||
{
|
||||
totalEpisodeCount === 0 ? '0/0' : `${episodeFileCount}/${totalEpisodeCount}`
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SeasonPassSeason.propTypes = {
|
||||
seasonNumber: PropTypes.number.isRequired,
|
||||
monitored: PropTypes.bool.isRequired,
|
||||
statistics: PropTypes.object.isRequired,
|
||||
isSaving: PropTypes.bool.isRequired,
|
||||
onSeasonMonitoredPress: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
SeasonPassSeason.defaultProps = {
|
||||
isSaving: false,
|
||||
statistics: {
|
||||
episodeFileCount: 0,
|
||||
totalEpisodeCount: 0,
|
||||
percentOfEpisodes: 0
|
||||
}
|
||||
};
|
||||
|
||||
export default SeasonPassSeason;
|
|
@ -18,7 +18,6 @@ import * as providerOptions from './providerOptionActions';
|
|||
import * as queue from './queueActions';
|
||||
import * as releases from './releaseActions';
|
||||
import * as rootFolders from './rootFolderActions';
|
||||
import * as seasonPass from './seasonPassActions';
|
||||
import * as series from './seriesActions';
|
||||
import * as seriesHistory from './seriesHistoryActions';
|
||||
import * as seriesIndex from './seriesIndexActions';
|
||||
|
@ -48,7 +47,6 @@ export default [
|
|||
queue,
|
||||
releases,
|
||||
rootFolders,
|
||||
seasonPass,
|
||||
series,
|
||||
seriesHistory,
|
||||
seriesIndex,
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
import { createAction } from 'redux-actions';
|
||||
import { sortDirections } from 'Helpers/Props';
|
||||
import { createThunk, handleThunks } from 'Store/thunks';
|
||||
import createAjaxRequest from 'Utilities/createAjaxRequest';
|
||||
import { set } from './baseActions';
|
||||
import createHandleActions from './Creators/createHandleActions';
|
||||
import createSetClientSideCollectionFilterReducer from './Creators/Reducers/createSetClientSideCollectionFilterReducer';
|
||||
import createSetClientSideCollectionSortReducer from './Creators/Reducers/createSetClientSideCollectionSortReducer';
|
||||
import { fetchSeries, filterBuilderProps, filterPredicates, filters } from './seriesActions';
|
||||
|
||||
//
|
||||
// Variables
|
||||
|
||||
export const section = 'seasonPass';
|
||||
|
||||
//
|
||||
// State
|
||||
|
||||
export const defaultState = {
|
||||
isSaving: false,
|
||||
saveError: null,
|
||||
sortKey: 'sortTitle',
|
||||
sortDirection: sortDirections.ASCENDING,
|
||||
secondarySortKey: 'sortTitle',
|
||||
secondarySortDirection: sortDirections.ASCENDING,
|
||||
selectedFilterKey: 'all',
|
||||
filters,
|
||||
filterPredicates,
|
||||
|
||||
filterBuilderProps
|
||||
};
|
||||
|
||||
export const persistState = [
|
||||
'seasonPass.sortKey',
|
||||
'seasonPass.sortDirection',
|
||||
'seasonPass.selectedFilterKey',
|
||||
'seasonPass.customFilters'
|
||||
];
|
||||
|
||||
//
|
||||
// Actions Types
|
||||
|
||||
export const SET_SEASON_PASS_SORT = 'seasonPass/setSeasonPassSort';
|
||||
export const SET_SEASON_PASS_FILTER = 'seasonPass/setSeasonPassFilter';
|
||||
export const SAVE_SEASON_PASS = 'seasonPass/saveSeasonPass';
|
||||
|
||||
//
|
||||
// Action Creators
|
||||
|
||||
export const setSeasonPassSort = createAction(SET_SEASON_PASS_SORT);
|
||||
export const setSeasonPassFilter = createAction(SET_SEASON_PASS_FILTER);
|
||||
export const saveSeasonPass = createThunk(SAVE_SEASON_PASS);
|
||||
|
||||
//
|
||||
// Action Handlers
|
||||
|
||||
export const actionHandlers = handleThunks({
|
||||
|
||||
[SAVE_SEASON_PASS]: function(getState, payload, dispatch) {
|
||||
const {
|
||||
seriesIds,
|
||||
monitored,
|
||||
monitor
|
||||
} = payload;
|
||||
|
||||
const series = [];
|
||||
|
||||
seriesIds.forEach((id) => {
|
||||
const seriesToUpdate = { id };
|
||||
|
||||
if (payload.hasOwnProperty('monitored')) {
|
||||
seriesToUpdate.monitored = monitored;
|
||||
}
|
||||
|
||||
series.push(seriesToUpdate);
|
||||
});
|
||||
|
||||
dispatch(set({
|
||||
section,
|
||||
isSaving: true
|
||||
}));
|
||||
|
||||
const promise = createAjaxRequest({
|
||||
url: '/seasonPass',
|
||||
method: 'POST',
|
||||
data: JSON.stringify({
|
||||
series,
|
||||
monitoringOptions: { monitor }
|
||||
}),
|
||||
dataType: 'json'
|
||||
}).request;
|
||||
|
||||
promise.done((data) => {
|
||||
dispatch(fetchSeries());
|
||||
|
||||
dispatch(set({
|
||||
section,
|
||||
isSaving: false,
|
||||
saveError: null
|
||||
}));
|
||||
});
|
||||
|
||||
promise.fail((xhr) => {
|
||||
dispatch(set({
|
||||
section,
|
||||
isSaving: false,
|
||||
saveError: xhr
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
//
|
||||
// Reducers
|
||||
|
||||
export const reducers = createHandleActions({
|
||||
|
||||
[SET_SEASON_PASS_SORT]: createSetClientSideCollectionSortReducer(section),
|
||||
[SET_SEASON_PASS_FILTER]: createSetClientSideCollectionFilterReducer(section)
|
||||
|
||||
}, defaultState, section);
|
||||
|
Loading…
Reference in New Issue