From 6fce6c2bbcb1395a48f89d41d209b0ebe96042ee Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 30 Jan 2023 19:15:40 -0800 Subject: [PATCH] Remove Season Pass --- frontend/src/App/AppRoutes.js | 11 +- .../Components/Page/Sidebar/PageSidebar.js | 4 - frontend/src/SeasonPass/SeasonPass.js | 217 ------------------ .../src/SeasonPass/SeasonPassConnector.js | 64 ------ .../SeasonPassFilterModalConnector.js | 24 -- frontend/src/SeasonPass/SeasonPassFooter.css | 14 -- frontend/src/SeasonPass/SeasonPassFooter.js | 145 ------------ frontend/src/SeasonPass/SeasonPassRow.css | 20 -- frontend/src/SeasonPass/SeasonPassRow.js | 103 --------- .../src/SeasonPass/SeasonPassRowConnector.js | 77 ------- frontend/src/SeasonPass/SeasonPassSeason.css | 25 -- frontend/src/SeasonPass/SeasonPassSeason.js | 88 ------- frontend/src/Store/Actions/index.js | 2 - .../src/Store/Actions/seasonPassActions.js | 123 ---------- 14 files changed, 9 insertions(+), 908 deletions(-) delete mode 100644 frontend/src/SeasonPass/SeasonPass.js delete mode 100644 frontend/src/SeasonPass/SeasonPassConnector.js delete mode 100644 frontend/src/SeasonPass/SeasonPassFilterModalConnector.js delete mode 100644 frontend/src/SeasonPass/SeasonPassFooter.css delete mode 100644 frontend/src/SeasonPass/SeasonPassFooter.js delete mode 100644 frontend/src/SeasonPass/SeasonPassRow.css delete mode 100644 frontend/src/SeasonPass/SeasonPassRow.js delete mode 100644 frontend/src/SeasonPass/SeasonPassRowConnector.js delete mode 100644 frontend/src/SeasonPass/SeasonPassSeason.css delete mode 100644 frontend/src/SeasonPass/SeasonPassSeason.js delete mode 100644 frontend/src/Store/Actions/seasonPassActions.js diff --git a/frontend/src/App/AppRoutes.js b/frontend/src/App/AppRoutes.js index f60d202b3..123212461 100644 --- a/frontend/src/App/AppRoutes.js +++ b/frontend/src/App/AppRoutes.js @@ -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) { { + return ( + + ); + }} /> { - 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 ( - - - - - - - - - - { - isFetching && !isPopulated && - - } - - { - !isFetching && !!error && -
Unable to load the calendar
- } - - { - !error && isPopulated && !!items.length && -
- - - { - items.map((item) => { - return ( - - ); - }) - } - -
-
- } - - { - !error && isPopulated && !items.length && - - } -
- - -
- ); - } -} - -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; diff --git a/frontend/src/SeasonPass/SeasonPassConnector.js b/frontend/src/SeasonPass/SeasonPassConnector.js deleted file mode 100644 index cd578ea9d..000000000 --- a/frontend/src/SeasonPass/SeasonPassConnector.js +++ /dev/null @@ -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 ( - - ); - } -} - -SeasonPassConnector.propTypes = { - setSeasonPassSort: PropTypes.func.isRequired, - setSeasonPassFilter: PropTypes.func.isRequired, - saveSeasonPass: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(SeasonPassConnector); diff --git a/frontend/src/SeasonPass/SeasonPassFilterModalConnector.js b/frontend/src/SeasonPass/SeasonPassFilterModalConnector.js deleted file mode 100644 index 54c4955ae..000000000 --- a/frontend/src/SeasonPass/SeasonPassFilterModalConnector.js +++ /dev/null @@ -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); diff --git a/frontend/src/SeasonPass/SeasonPassFooter.css b/frontend/src/SeasonPass/SeasonPassFooter.css deleted file mode 100644 index 11ea5496a..000000000 --- a/frontend/src/SeasonPass/SeasonPassFooter.css +++ /dev/null @@ -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; -} diff --git a/frontend/src/SeasonPass/SeasonPassFooter.js b/frontend/src/SeasonPass/SeasonPassFooter.js deleted file mode 100644 index d5bb79e58..000000000 --- a/frontend/src/SeasonPass/SeasonPassFooter.js +++ /dev/null @@ -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 ( - -
-
- Monitor Series -
- - -
- -
-
- Monitor Episodes -
- - -
- -
-
- {selectedCount} Series Selected -
- - - Update Selected - -
-
- ); - } -} - -SeasonPassFooter.propTypes = { - selectedCount: PropTypes.number.isRequired, - isSaving: PropTypes.bool.isRequired, - saveError: PropTypes.object, - onUpdateSelectedPress: PropTypes.func.isRequired -}; - -export default SeasonPassFooter; diff --git a/frontend/src/SeasonPass/SeasonPassRow.css b/frontend/src/SeasonPass/SeasonPassRow.css deleted file mode 100644 index 35d97d3c2..000000000 --- a/frontend/src/SeasonPass/SeasonPassRow.css +++ /dev/null @@ -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; -} diff --git a/frontend/src/SeasonPass/SeasonPassRow.js b/frontend/src/SeasonPass/SeasonPassRow.js deleted file mode 100644 index e71800437..000000000 --- a/frontend/src/SeasonPass/SeasonPassRow.js +++ /dev/null @@ -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 ( - - - - - - - - - - - - - - - - - { - seasons.map((season) => { - return ( - - ); - }) - } - - - ); - } -} - -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; diff --git a/frontend/src/SeasonPass/SeasonPassRowConnector.js b/frontend/src/SeasonPass/SeasonPassRowConnector.js deleted file mode 100644 index 5f90013f4..000000000 --- a/frontend/src/SeasonPass/SeasonPassRowConnector.js +++ /dev/null @@ -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 ( - - ); - } -} - -SeasonPassRowConnector.propTypes = { - seriesId: PropTypes.number.isRequired, - monitored: PropTypes.bool.isRequired, - toggleSeriesMonitored: PropTypes.func.isRequired, - toggleSeasonMonitored: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(SeasonPassRowConnector); diff --git a/frontend/src/SeasonPass/SeasonPassSeason.css b/frontend/src/SeasonPass/SeasonPassSeason.css deleted file mode 100644 index 77c4abdad..000000000 --- a/frontend/src/SeasonPass/SeasonPassSeason.css +++ /dev/null @@ -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); -} diff --git a/frontend/src/SeasonPass/SeasonPassSeason.js b/frontend/src/SeasonPass/SeasonPassSeason.js deleted file mode 100644 index c3f465b3f..000000000 --- a/frontend/src/SeasonPass/SeasonPassSeason.js +++ /dev/null @@ -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 ( -
-
- - - - { - seasonNumber === 0 ? 'Specials' : `S${padNumber(seasonNumber, 2)}` - } - -
- -
- { - totalEpisodeCount === 0 ? '0/0' : `${episodeFileCount}/${totalEpisodeCount}` - } -
-
- ); - } -} - -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; diff --git a/frontend/src/Store/Actions/index.js b/frontend/src/Store/Actions/index.js index 59e86fb35..d69f19b11 100644 --- a/frontend/src/Store/Actions/index.js +++ b/frontend/src/Store/Actions/index.js @@ -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, diff --git a/frontend/src/Store/Actions/seasonPassActions.js b/frontend/src/Store/Actions/seasonPassActions.js deleted file mode 100644 index 4cc16127c..000000000 --- a/frontend/src/Store/Actions/seasonPassActions.js +++ /dev/null @@ -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); -