From a57b35a1966266b49d1241474fe3b69523f70474 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 30 Jul 2023 16:23:41 +0300 Subject: [PATCH] Convert store selectors to Typescript --- frontend/src/App/State/AppState.ts | 10 ++++-- frontend/src/App/State/CommandAppState.ts | 6 ++++ frontend/src/App/State/SettingsAppState.ts | 7 +++-- frontend/src/App/State/SystemAppState.ts | 10 ++++++ frontend/src/App/State/TagsAppState.ts | 22 ++++++++++++- .../Overview/SeriesIndexOverviewInfo.tsx | 8 ++--- .../Index/Posters/SeriesIndexPoster.tsx | 2 +- .../Index/Posters/SeriesIndexPosterInfo.tsx | 8 +++-- .../src/Series/Index/Table/SeriesIndexRow.tsx | 2 +- ...Selector.js => createAllSeriesSelector.ts} | 3 +- ...r.js => createCommandExecutingSelector.ts} | 11 +++---- .../Store/Selectors/createCommandSelector.js | 14 --------- .../Store/Selectors/createCommandSelector.ts | 11 +++++++ ...sSelector.js => createCommandsSelector.ts} | 3 +- .../Selectors/createDeepEqualSelector.js | 9 ------ .../Selectors/createDeepEqualSelector.ts | 6 ++++ .../Selectors/createEpisodeFileSelector.js | 17 ---------- .../Selectors/createEpisodeFileSelector.ts | 21 +++++++++++++ ....js => createExecutingCommandsSelector.ts} | 3 +- ...tor.js => createExistingSeriesSelector.ts} | 7 +++-- .../Selectors/createLanguagesSelector.js | 27 ---------------- .../Selectors/createLanguagesSelector.ts | 25 +++++++++++++++ .../Selectors/createProfileInUseSelector.js | 19 ------------ .../Selectors/createProfileInUseSelector.ts | 25 +++++++++++++++ .../Selectors/createQualityProfileSelector.js | 26 ---------------- .../Selectors/createQualityProfileSelector.ts | 24 ++++++++++++++ ...Selector.js => createQueueItemSelector.ts} | 9 +++--- ...lector.js => createSeriesCountSelector.ts} | 9 ++---- .../createSeriesQualityProfileSelector.js | 16 ---------- .../createSeriesQualityProfileSelector.ts | 18 +++++++++++ ...ector.js => createSystemStatusSelector.ts} | 3 +- ...elector.js => createTagDetailsSelector.ts} | 5 +-- ...eTagsSelector.js => createTagsSelector.ts} | 3 +- ...elector.js => createUISettingsSelector.ts} | 3 +- frontend/src/typings/SystemStatus.ts | 31 +++++++++++++++++++ 35 files changed, 250 insertions(+), 173 deletions(-) create mode 100644 frontend/src/App/State/CommandAppState.ts create mode 100644 frontend/src/App/State/SystemAppState.ts rename frontend/src/Store/Selectors/{createAllSeriesSelector.js => createAllSeriesSelector.ts} (71%) rename frontend/src/Store/Selectors/{createCommandExecutingSelector.js => createCommandExecutingSelector.ts} (50%) delete mode 100644 frontend/src/Store/Selectors/createCommandSelector.js create mode 100644 frontend/src/Store/Selectors/createCommandSelector.ts rename frontend/src/Store/Selectors/{createCommandsSelector.js => createCommandsSelector.ts} (71%) delete mode 100644 frontend/src/Store/Selectors/createDeepEqualSelector.js create mode 100644 frontend/src/Store/Selectors/createDeepEqualSelector.ts delete mode 100644 frontend/src/Store/Selectors/createEpisodeFileSelector.js create mode 100644 frontend/src/Store/Selectors/createEpisodeFileSelector.ts rename frontend/src/Store/Selectors/{createExecutingCommandsSelector.js => createExecutingCommandsSelector.ts} (78%) rename frontend/src/Store/Selectors/{createExistingSeriesSelector.js => createExistingSeriesSelector.ts} (62%) delete mode 100644 frontend/src/Store/Selectors/createLanguagesSelector.js create mode 100644 frontend/src/Store/Selectors/createLanguagesSelector.ts delete mode 100644 frontend/src/Store/Selectors/createProfileInUseSelector.js create mode 100644 frontend/src/Store/Selectors/createProfileInUseSelector.ts delete mode 100644 frontend/src/Store/Selectors/createQualityProfileSelector.js create mode 100644 frontend/src/Store/Selectors/createQualityProfileSelector.ts rename frontend/src/Store/Selectors/{createQueueItemSelector.js => createQueueItemSelector.ts} (52%) rename frontend/src/Store/Selectors/{createSeriesCountSelector.js => createSeriesCountSelector.ts} (63%) delete mode 100644 frontend/src/Store/Selectors/createSeriesQualityProfileSelector.js create mode 100644 frontend/src/Store/Selectors/createSeriesQualityProfileSelector.ts rename frontend/src/Store/Selectors/{createSystemStatusSelector.js => createSystemStatusSelector.ts} (70%) rename frontend/src/Store/Selectors/{createTagDetailsSelector.js => createTagDetailsSelector.ts} (62%) rename frontend/src/Store/Selectors/{createTagsSelector.js => createTagsSelector.ts} (68%) rename frontend/src/Store/Selectors/{createUISettingsSelector.js => createUISettingsSelector.ts} (69%) create mode 100644 frontend/src/typings/SystemStatus.ts diff --git a/frontend/src/App/State/AppState.ts b/frontend/src/App/State/AppState.ts index fe8d1d9a3..7c8d3deb5 100644 --- a/frontend/src/App/State/AppState.ts +++ b/frontend/src/App/State/AppState.ts @@ -1,11 +1,13 @@ import InteractiveImportAppState from 'App/State/InteractiveImportAppState'; import CalendarAppState from './CalendarAppState'; +import CommandAppState from './CommandAppState'; import EpisodeFilesAppState from './EpisodeFilesAppState'; import EpisodesAppState from './EpisodesAppState'; import ParseAppState from './ParseAppState'; import QueueAppState from './QueueAppState'; import SeriesAppState, { SeriesIndexAppState } from './SeriesAppState'; import SettingsAppState from './SettingsAppState'; +import SystemAppState from './SystemAppState'; import TagsAppState from './TagsAppState'; interface FilterBuilderPropOption { @@ -42,15 +44,17 @@ export interface CustomFilter { interface AppState { calendar: CalendarAppState; - episodesSelection: EpisodesAppState; + commands: CommandAppState; episodeFiles: EpisodeFilesAppState; + episodesSelection: EpisodesAppState; interactiveImport: InteractiveImportAppState; parse: ParseAppState; + queue: QueueAppState; + series: SeriesAppState; seriesIndex: SeriesIndexAppState; settings: SettingsAppState; - series: SeriesAppState; + system: SystemAppState; tags: TagsAppState; - queue: QueueAppState; } export default AppState; diff --git a/frontend/src/App/State/CommandAppState.ts b/frontend/src/App/State/CommandAppState.ts new file mode 100644 index 000000000..1bde37371 --- /dev/null +++ b/frontend/src/App/State/CommandAppState.ts @@ -0,0 +1,6 @@ +import AppSectionState from 'App/State/AppSectionState'; +import Command from 'Commands/Command'; + +export type CommandAppState = AppSectionState; + +export default CommandAppState; diff --git a/frontend/src/App/State/SettingsAppState.ts b/frontend/src/App/State/SettingsAppState.ts index 6960db2f9..e249f2d20 100644 --- a/frontend/src/App/State/SettingsAppState.ts +++ b/frontend/src/App/State/SettingsAppState.ts @@ -1,5 +1,6 @@ import AppSectionState, { AppSectionDeleteState, + AppSectionItemState, AppSectionSaveState, AppSectionSchemaState, } from 'App/State/AppSectionState'; @@ -35,16 +36,16 @@ export interface QualityProfilesAppState AppSectionSchemaState {} export type LanguageSettingsAppState = AppSectionState; -export type UiSettingsAppState = AppSectionState; +export type UiSettingsAppState = AppSectionItemState; interface SettingsAppState { downloadClients: DownloadClientAppState; importLists: ImportListAppState; indexers: IndexerAppState; + languages: LanguageSettingsAppState; notifications: NotificationAppState; - language: LanguageSettingsAppState; - uiSettings: UiSettingsAppState; qualityProfiles: QualityProfilesAppState; + ui: UiSettingsAppState; } export default SettingsAppState; diff --git a/frontend/src/App/State/SystemAppState.ts b/frontend/src/App/State/SystemAppState.ts new file mode 100644 index 000000000..d43c1d0ee --- /dev/null +++ b/frontend/src/App/State/SystemAppState.ts @@ -0,0 +1,10 @@ +import SystemStatus from 'typings/SystemStatus'; +import { AppSectionItemState } from './AppSectionState'; + +export type SystemStatusAppState = AppSectionItemState; + +interface SystemAppState { + status: SystemStatusAppState; +} + +export default SystemAppState; diff --git a/frontend/src/App/State/TagsAppState.ts b/frontend/src/App/State/TagsAppState.ts index d1f1d5a2f..914df9044 100644 --- a/frontend/src/App/State/TagsAppState.ts +++ b/frontend/src/App/State/TagsAppState.ts @@ -1,12 +1,32 @@ import ModelBase from 'App/ModelBase'; import AppSectionState, { AppSectionDeleteState, + AppSectionSaveState, } from 'App/State/AppSectionState'; export interface Tag extends ModelBase { label: string; } -interface TagsAppState extends AppSectionState, AppSectionDeleteState {} +export interface TagDetail extends ModelBase { + label: string; + autoTagIds: number[]; + delayProfileIds: number[]; + downloadClientIds: []; + importListIds: number[]; + indexerIds: number[]; + notificationIds: number[]; + restrictionIds: number[]; + seriesIds: number[]; +} + +export interface TagDetailAppState + extends AppSectionState, + AppSectionDeleteState, + AppSectionSaveState {} + +interface TagsAppState extends AppSectionState, AppSectionDeleteState { + details: TagDetailAppState; +} export default TagsAppState; diff --git a/frontend/src/Series/Index/Overview/SeriesIndexOverviewInfo.tsx b/frontend/src/Series/Index/Overview/SeriesIndexOverviewInfo.tsx index 13ecc14c6..c947bbc93 100644 --- a/frontend/src/Series/Index/Overview/SeriesIndexOverviewInfo.tsx +++ b/frontend/src/Series/Index/Overview/SeriesIndexOverviewInfo.tsx @@ -4,6 +4,7 @@ import { useSelector } from 'react-redux'; import { icons } from 'Helpers/Props'; import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; import dimensions from 'Styles/Variables/dimensions'; +import QualityProfile from 'typings/QualityProfile'; import { UiSettings } from 'typings/UiSettings'; import formatDateTime from 'Utilities/Date/formatDateTime'; import getRelativeDate from 'Utilities/Date/getRelativeDate'; @@ -36,7 +37,7 @@ interface SeriesIndexOverviewInfoProps { monitored: boolean; nextAiring?: string; network?: string; - qualityProfile: object; + qualityProfile?: QualityProfile; previousAiring?: string; added?: string; seasonCount: number; @@ -115,13 +116,10 @@ function getInfoRowProps( }; } - if (name === 'qualityProfileId') { + if (name === 'qualityProfileId' && !!props.qualityProfile?.name) { return { title: 'Quality Profile', iconName: icons.PROFILE, - // TODO: Type QualityProfile - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore ts(2339) label: props.qualityProfile.name, }; } diff --git a/frontend/src/Series/Index/Posters/SeriesIndexPoster.tsx b/frontend/src/Series/Index/Posters/SeriesIndexPoster.tsx index 162656766..50bf46524 100644 --- a/frontend/src/Series/Index/Posters/SeriesIndexPoster.tsx +++ b/frontend/src/Series/Index/Posters/SeriesIndexPoster.tsx @@ -202,7 +202,7 @@ function SeriesIndexPoster(props: SeriesIndexPosterProps) { ) : null} - {showQualityProfile ? ( + {showQualityProfile && !!qualityProfile?.name ? (
{qualityProfile.name}
diff --git a/frontend/src/Series/Index/Posters/SeriesIndexPosterInfo.tsx b/frontend/src/Series/Index/Posters/SeriesIndexPosterInfo.tsx index 6cdfbcc14..941ad15fa 100644 --- a/frontend/src/Series/Index/Posters/SeriesIndexPosterInfo.tsx +++ b/frontend/src/Series/Index/Posters/SeriesIndexPosterInfo.tsx @@ -11,7 +11,7 @@ interface SeriesIndexPosterInfoProps { originalLanguage?: Language; network?: string; showQualityProfile: boolean; - qualityProfile: QualityProfile; + qualityProfile?: QualityProfile; previousAiring?: string; added?: string; seasonCount: number; @@ -58,7 +58,11 @@ function SeriesIndexPosterInfo(props: SeriesIndexPosterInfoProps) { ); } - if (sortKey === 'qualityProfileId' && !showQualityProfile) { + if ( + sortKey === 'qualityProfileId' && + !showQualityProfile && + !!qualityProfile?.name + ) { return (
{qualityProfile.name} diff --git a/frontend/src/Series/Index/Table/SeriesIndexRow.tsx b/frontend/src/Series/Index/Table/SeriesIndexRow.tsx index 29ccbe043..550554242 100644 --- a/frontend/src/Series/Index/Table/SeriesIndexRow.tsx +++ b/frontend/src/Series/Index/Table/SeriesIndexRow.tsx @@ -242,7 +242,7 @@ function SeriesIndexRow(props: SeriesIndexRowProps) { if (name === 'qualityProfileId') { return ( - {qualityProfile.name} + {qualityProfile?.name ?? ''} ); } diff --git a/frontend/src/Store/Selectors/createAllSeriesSelector.js b/frontend/src/Store/Selectors/createAllSeriesSelector.ts similarity index 71% rename from frontend/src/Store/Selectors/createAllSeriesSelector.js rename to frontend/src/Store/Selectors/createAllSeriesSelector.ts index 6a1abdac4..43a6d8290 100644 --- a/frontend/src/Store/Selectors/createAllSeriesSelector.js +++ b/frontend/src/Store/Selectors/createAllSeriesSelector.ts @@ -1,8 +1,9 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; function createAllSeriesSelector() { return createSelector( - (state) => state.series, + (state: AppState) => state.series, (series) => { return series.items; } diff --git a/frontend/src/Store/Selectors/createCommandExecutingSelector.js b/frontend/src/Store/Selectors/createCommandExecutingSelector.ts similarity index 50% rename from frontend/src/Store/Selectors/createCommandExecutingSelector.js rename to frontend/src/Store/Selectors/createCommandExecutingSelector.ts index 6037d5820..6a80e172b 100644 --- a/frontend/src/Store/Selectors/createCommandExecutingSelector.js +++ b/frontend/src/Store/Selectors/createCommandExecutingSelector.ts @@ -2,13 +2,10 @@ import { createSelector } from 'reselect'; import { isCommandExecuting } from 'Utilities/Command'; import createCommandSelector from './createCommandSelector'; -function createCommandExecutingSelector(name, contraints = {}) { - return createSelector( - createCommandSelector(name, contraints), - (command) => { - return isCommandExecuting(command); - } - ); +function createCommandExecutingSelector(name: string, contraints = {}) { + return createSelector(createCommandSelector(name, contraints), (command) => { + return isCommandExecuting(command); + }); } export default createCommandExecutingSelector; diff --git a/frontend/src/Store/Selectors/createCommandSelector.js b/frontend/src/Store/Selectors/createCommandSelector.js deleted file mode 100644 index 709dfebaf..000000000 --- a/frontend/src/Store/Selectors/createCommandSelector.js +++ /dev/null @@ -1,14 +0,0 @@ -import { createSelector } from 'reselect'; -import { findCommand } from 'Utilities/Command'; -import createCommandsSelector from './createCommandsSelector'; - -function createCommandSelector(name, contraints = {}) { - return createSelector( - createCommandsSelector(), - (commands) => { - return findCommand(commands, { name, ...contraints }); - } - ); -} - -export default createCommandSelector; diff --git a/frontend/src/Store/Selectors/createCommandSelector.ts b/frontend/src/Store/Selectors/createCommandSelector.ts new file mode 100644 index 000000000..cced7b186 --- /dev/null +++ b/frontend/src/Store/Selectors/createCommandSelector.ts @@ -0,0 +1,11 @@ +import { createSelector } from 'reselect'; +import { findCommand } from 'Utilities/Command'; +import createCommandsSelector from './createCommandsSelector'; + +function createCommandSelector(name: string, contraints = {}) { + return createSelector(createCommandsSelector(), (commands) => { + return findCommand(commands, { name, ...contraints }); + }); +} + +export default createCommandSelector; diff --git a/frontend/src/Store/Selectors/createCommandsSelector.js b/frontend/src/Store/Selectors/createCommandsSelector.ts similarity index 71% rename from frontend/src/Store/Selectors/createCommandsSelector.js rename to frontend/src/Store/Selectors/createCommandsSelector.ts index 7b9edffd9..2dd5d24a2 100644 --- a/frontend/src/Store/Selectors/createCommandsSelector.js +++ b/frontend/src/Store/Selectors/createCommandsSelector.ts @@ -1,8 +1,9 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; function createCommandsSelector() { return createSelector( - (state) => state.commands, + (state: AppState) => state.commands, (commands) => { return commands.items; } diff --git a/frontend/src/Store/Selectors/createDeepEqualSelector.js b/frontend/src/Store/Selectors/createDeepEqualSelector.js deleted file mode 100644 index 85562f28b..000000000 --- a/frontend/src/Store/Selectors/createDeepEqualSelector.js +++ /dev/null @@ -1,9 +0,0 @@ -import _ from 'lodash'; -import { createSelectorCreator, defaultMemoize } from 'reselect'; - -const createDeepEqualSelector = createSelectorCreator( - defaultMemoize, - _.isEqual -); - -export default createDeepEqualSelector; diff --git a/frontend/src/Store/Selectors/createDeepEqualSelector.ts b/frontend/src/Store/Selectors/createDeepEqualSelector.ts new file mode 100644 index 000000000..9d4a63d2e --- /dev/null +++ b/frontend/src/Store/Selectors/createDeepEqualSelector.ts @@ -0,0 +1,6 @@ +import { isEqual } from 'lodash'; +import { createSelectorCreator, defaultMemoize } from 'reselect'; + +const createDeepEqualSelector = createSelectorCreator(defaultMemoize, isEqual); + +export default createDeepEqualSelector; diff --git a/frontend/src/Store/Selectors/createEpisodeFileSelector.js b/frontend/src/Store/Selectors/createEpisodeFileSelector.js deleted file mode 100644 index f58f000ff..000000000 --- a/frontend/src/Store/Selectors/createEpisodeFileSelector.js +++ /dev/null @@ -1,17 +0,0 @@ -import { createSelector } from 'reselect'; - -function createEpisodeFileSelector() { - return createSelector( - (state, { episodeFileId }) => episodeFileId, - (state) => state.episodeFiles, - (episodeFileId, episodeFiles) => { - if (!episodeFileId) { - return; - } - - return episodeFiles.items.find((episodeFile) => episodeFile.id === episodeFileId); - } - ); -} - -export default createEpisodeFileSelector; diff --git a/frontend/src/Store/Selectors/createEpisodeFileSelector.ts b/frontend/src/Store/Selectors/createEpisodeFileSelector.ts new file mode 100644 index 000000000..b8c65e4c4 --- /dev/null +++ b/frontend/src/Store/Selectors/createEpisodeFileSelector.ts @@ -0,0 +1,21 @@ +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; + +function createEpisodeFileSelector() { + return createSelector( + (_: AppState, { episodeFileId }: { episodeFileId: number }) => + episodeFileId, + (state: AppState) => state.episodeFiles, + (episodeFileId, episodeFiles) => { + if (!episodeFileId) { + return; + } + + return episodeFiles.items.find( + (episodeFile) => episodeFile.id === episodeFileId + ); + } + ); +} + +export default createEpisodeFileSelector; diff --git a/frontend/src/Store/Selectors/createExecutingCommandsSelector.js b/frontend/src/Store/Selectors/createExecutingCommandsSelector.ts similarity index 78% rename from frontend/src/Store/Selectors/createExecutingCommandsSelector.js rename to frontend/src/Store/Selectors/createExecutingCommandsSelector.ts index 266865a8a..dd16571fc 100644 --- a/frontend/src/Store/Selectors/createExecutingCommandsSelector.js +++ b/frontend/src/Store/Selectors/createExecutingCommandsSelector.ts @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; import { isCommandExecuting } from 'Utilities/Command'; function createExecutingCommandsSelector() { return createSelector( - (state) => state.commands.items, + (state: AppState) => state.commands.items, (commands) => { return commands.filter((command) => isCommandExecuting(command)); } diff --git a/frontend/src/Store/Selectors/createExistingSeriesSelector.js b/frontend/src/Store/Selectors/createExistingSeriesSelector.ts similarity index 62% rename from frontend/src/Store/Selectors/createExistingSeriesSelector.js rename to frontend/src/Store/Selectors/createExistingSeriesSelector.ts index 77d18acee..ad84c3558 100644 --- a/frontend/src/Store/Selectors/createExistingSeriesSelector.js +++ b/frontend/src/Store/Selectors/createExistingSeriesSelector.ts @@ -1,13 +1,14 @@ -import _ from 'lodash'; +import { some } from 'lodash'; import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; import createAllSeriesSelector from './createAllSeriesSelector'; function createExistingSeriesSelector() { return createSelector( - (state, { tvdbId }) => tvdbId, + (_: AppState, { tvdbId }: { tvdbId: number }) => tvdbId, createAllSeriesSelector(), (tvdbId, series) => { - return _.some(series, { tvdbId }); + return some(series, { tvdbId }); } ); } diff --git a/frontend/src/Store/Selectors/createLanguagesSelector.js b/frontend/src/Store/Selectors/createLanguagesSelector.js deleted file mode 100644 index 47840933c..000000000 --- a/frontend/src/Store/Selectors/createLanguagesSelector.js +++ /dev/null @@ -1,27 +0,0 @@ -import { createSelector } from 'reselect'; - -function createLanguagesSelector() { - return createSelector( - (state) => state.settings.languages, - (languages) => { - const { - isFetching, - isPopulated, - error, - items - } = languages; - - const filterItems = ['Any']; - const filteredLanguages = items.filter((lang) => !filterItems.includes(lang.name)); - - return { - isFetching, - isPopulated, - error, - items: filteredLanguages - }; - } - ); -} - -export default createLanguagesSelector; diff --git a/frontend/src/Store/Selectors/createLanguagesSelector.ts b/frontend/src/Store/Selectors/createLanguagesSelector.ts new file mode 100644 index 000000000..831922103 --- /dev/null +++ b/frontend/src/Store/Selectors/createLanguagesSelector.ts @@ -0,0 +1,25 @@ +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; + +function createLanguagesSelector() { + return createSelector( + (state: AppState) => state.settings.languages, + (languages) => { + const { isFetching, isPopulated, error, items } = languages; + + const filterItems = ['Any']; + const filteredLanguages = items.filter( + (lang) => !filterItems.includes(lang.name) + ); + + return { + isFetching, + isPopulated, + error, + items: filteredLanguages, + }; + } + ); +} + +export default createLanguagesSelector; diff --git a/frontend/src/Store/Selectors/createProfileInUseSelector.js b/frontend/src/Store/Selectors/createProfileInUseSelector.js deleted file mode 100644 index 861a89147..000000000 --- a/frontend/src/Store/Selectors/createProfileInUseSelector.js +++ /dev/null @@ -1,19 +0,0 @@ -import { createSelector } from 'reselect'; -import createAllSeriesSelector from './createAllSeriesSelector'; - -function createProfileInUseSelector(profileProp) { - return createSelector( - (state, { id }) => id, - createAllSeriesSelector(), - (state) => state.settings.importLists.items, - (id, series, lists) => { - if (!id) { - return false; - } - - return series.some((s) => s[profileProp] === id) || lists.some((list) => list[profileProp] === id); - } - ); -} - -export default createProfileInUseSelector; diff --git a/frontend/src/Store/Selectors/createProfileInUseSelector.ts b/frontend/src/Store/Selectors/createProfileInUseSelector.ts new file mode 100644 index 000000000..085cee0fc --- /dev/null +++ b/frontend/src/Store/Selectors/createProfileInUseSelector.ts @@ -0,0 +1,25 @@ +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; +import Series from 'Series/Series'; +import ImportList from 'typings/ImportList'; +import createAllSeriesSelector from './createAllSeriesSelector'; + +function createProfileInUseSelector(profileProp: string) { + return createSelector( + (_: AppState, { id }: { id: number }) => id, + createAllSeriesSelector(), + (state: AppState) => state.settings.importLists.items, + (id, series, lists) => { + if (!id) { + return false; + } + + return ( + series.some((s) => s[profileProp as keyof Series] === id) || + lists.some((list) => list[profileProp as keyof ImportList] === id) + ); + } + ); +} + +export default createProfileInUseSelector; diff --git a/frontend/src/Store/Selectors/createQualityProfileSelector.js b/frontend/src/Store/Selectors/createQualityProfileSelector.js deleted file mode 100644 index 611dfc903..000000000 --- a/frontend/src/Store/Selectors/createQualityProfileSelector.js +++ /dev/null @@ -1,26 +0,0 @@ -import { createSelector } from 'reselect'; - -export function createQualityProfileSelectorForHook(qualityProfileId) { - return createSelector( - (state) => state.settings.qualityProfiles.items, - (qualityProfiles) => { - return qualityProfiles.find((profile) => { - return profile.id === qualityProfileId; - }); - } - ); -} - -function createQualityProfileSelector() { - return createSelector( - (state, { qualityProfileId }) => qualityProfileId, - (state) => state.settings.qualityProfiles.items, - (qualityProfileId, qualityProfiles) => { - return qualityProfiles.find((profile) => { - return profile.id === qualityProfileId; - }); - } - ); -} - -export default createQualityProfileSelector; diff --git a/frontend/src/Store/Selectors/createQualityProfileSelector.ts b/frontend/src/Store/Selectors/createQualityProfileSelector.ts new file mode 100644 index 000000000..b913e0c46 --- /dev/null +++ b/frontend/src/Store/Selectors/createQualityProfileSelector.ts @@ -0,0 +1,24 @@ +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; + +export function createQualityProfileSelectorForHook(qualityProfileId: number) { + return createSelector( + (state: AppState) => state.settings.qualityProfiles.items, + (qualityProfiles) => { + return qualityProfiles.find((profile) => profile.id === qualityProfileId); + } + ); +} + +function createQualityProfileSelector() { + return createSelector( + (_: AppState, { qualityProfileId }: { qualityProfileId: number }) => + qualityProfileId, + (state: AppState) => state.settings.qualityProfiles.items, + (qualityProfileId, qualityProfiles) => { + return qualityProfiles.find((profile) => profile.id === qualityProfileId); + } + ); +} + +export default createQualityProfileSelector; diff --git a/frontend/src/Store/Selectors/createQueueItemSelector.js b/frontend/src/Store/Selectors/createQueueItemSelector.ts similarity index 52% rename from frontend/src/Store/Selectors/createQueueItemSelector.js rename to frontend/src/Store/Selectors/createQueueItemSelector.ts index e46a6c9ec..7d033559a 100644 --- a/frontend/src/Store/Selectors/createQueueItemSelector.js +++ b/frontend/src/Store/Selectors/createQueueItemSelector.ts @@ -1,17 +1,16 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; function createQueueItemSelector() { return createSelector( - (state, { episodeId }) => episodeId, - (state) => state.queue.details.items, + (_: AppState, { episodeId }: { episodeId: number }) => episodeId, + (state: AppState) => state.queue.details.items, (episodeId, details) => { if (!episodeId || !details) { return null; } - return details.find((item) => { - return item.episodeId === episodeId; - }); + return details.find((item) => item.episodeId === episodeId); } ); } diff --git a/frontend/src/Store/Selectors/createSeriesCountSelector.js b/frontend/src/Store/Selectors/createSeriesCountSelector.ts similarity index 63% rename from frontend/src/Store/Selectors/createSeriesCountSelector.js rename to frontend/src/Store/Selectors/createSeriesCountSelector.ts index f59d8ce5e..336266ad0 100644 --- a/frontend/src/Store/Selectors/createSeriesCountSelector.js +++ b/frontend/src/Store/Selectors/createSeriesCountSelector.ts @@ -2,12 +2,9 @@ import { createSelector } from 'reselect'; import createAllSeriesSelector from './createAllSeriesSelector'; function createSeriesCountSelector() { - return createSelector( - createAllSeriesSelector(), - (series) => { - return series.length; - } - ); + return createSelector(createAllSeriesSelector(), (series) => { + return series.length; + }); } export default createSeriesCountSelector; diff --git a/frontend/src/Store/Selectors/createSeriesQualityProfileSelector.js b/frontend/src/Store/Selectors/createSeriesQualityProfileSelector.js deleted file mode 100644 index 7622bf684..000000000 --- a/frontend/src/Store/Selectors/createSeriesQualityProfileSelector.js +++ /dev/null @@ -1,16 +0,0 @@ -import { createSelector } from 'reselect'; -import { createSeriesSelectorForHook } from './createSeriesSelector'; - -function createSeriesQualityProfileSelector(seriesId) { - return createSelector( - (state) => state.settings.qualityProfiles.items, - createSeriesSelectorForHook(seriesId), - (qualityProfiles, series = {}) => { - return qualityProfiles.find((profile) => { - return profile.id === series.qualityProfileId; - }); - } - ); -} - -export default createSeriesQualityProfileSelector; diff --git a/frontend/src/Store/Selectors/createSeriesQualityProfileSelector.ts b/frontend/src/Store/Selectors/createSeriesQualityProfileSelector.ts new file mode 100644 index 000000000..48528873a --- /dev/null +++ b/frontend/src/Store/Selectors/createSeriesQualityProfileSelector.ts @@ -0,0 +1,18 @@ +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; +import Series from 'Series/Series'; +import { createSeriesSelectorForHook } from './createSeriesSelector'; + +function createSeriesQualityProfileSelector(seriesId: number) { + return createSelector( + (state: AppState) => state.settings.qualityProfiles.items, + createSeriesSelectorForHook(seriesId), + (qualityProfiles, series = {} as Series) => { + return qualityProfiles.find( + (profile) => profile.id === series.qualityProfileId + ); + } + ); +} + +export default createSeriesQualityProfileSelector; diff --git a/frontend/src/Store/Selectors/createSystemStatusSelector.js b/frontend/src/Store/Selectors/createSystemStatusSelector.ts similarity index 70% rename from frontend/src/Store/Selectors/createSystemStatusSelector.js rename to frontend/src/Store/Selectors/createSystemStatusSelector.ts index df586bbb9..f5e276069 100644 --- a/frontend/src/Store/Selectors/createSystemStatusSelector.js +++ b/frontend/src/Store/Selectors/createSystemStatusSelector.ts @@ -1,8 +1,9 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; function createSystemStatusSelector() { return createSelector( - (state) => state.system.status, + (state: AppState) => state.system.status, (status) => { return status.item; } diff --git a/frontend/src/Store/Selectors/createTagDetailsSelector.js b/frontend/src/Store/Selectors/createTagDetailsSelector.ts similarity index 62% rename from frontend/src/Store/Selectors/createTagDetailsSelector.js rename to frontend/src/Store/Selectors/createTagDetailsSelector.ts index dd178944c..2a271cafe 100644 --- a/frontend/src/Store/Selectors/createTagDetailsSelector.js +++ b/frontend/src/Store/Selectors/createTagDetailsSelector.ts @@ -1,9 +1,10 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; function createTagDetailsSelector() { return createSelector( - (state, { id }) => id, - (state) => state.tags.details.items, + (_: AppState, { id }: { id: number }) => id, + (state: AppState) => state.tags.details.items, (id, tagDetails) => { return tagDetails.find((t) => t.id === id); } diff --git a/frontend/src/Store/Selectors/createTagsSelector.js b/frontend/src/Store/Selectors/createTagsSelector.ts similarity index 68% rename from frontend/src/Store/Selectors/createTagsSelector.js rename to frontend/src/Store/Selectors/createTagsSelector.ts index fbfd91cdb..f653ff6e3 100644 --- a/frontend/src/Store/Selectors/createTagsSelector.js +++ b/frontend/src/Store/Selectors/createTagsSelector.ts @@ -1,8 +1,9 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; function createTagsSelector() { return createSelector( - (state) => state.tags.items, + (state: AppState) => state.tags.items, (tags) => { return tags; } diff --git a/frontend/src/Store/Selectors/createUISettingsSelector.js b/frontend/src/Store/Selectors/createUISettingsSelector.ts similarity index 69% rename from frontend/src/Store/Selectors/createUISettingsSelector.js rename to frontend/src/Store/Selectors/createUISettingsSelector.ts index b256d0e98..ff539679b 100644 --- a/frontend/src/Store/Selectors/createUISettingsSelector.js +++ b/frontend/src/Store/Selectors/createUISettingsSelector.ts @@ -1,8 +1,9 @@ import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; function createUISettingsSelector() { return createSelector( - (state) => state.settings.ui, + (state: AppState) => state.settings.ui, (ui) => { return ui.item; } diff --git a/frontend/src/typings/SystemStatus.ts b/frontend/src/typings/SystemStatus.ts new file mode 100644 index 000000000..e72be2c5c --- /dev/null +++ b/frontend/src/typings/SystemStatus.ts @@ -0,0 +1,31 @@ +interface SystemStatus { + appData: string; + appName: string; + authentication: string; + branch: string; + buildTime: string; + instanceName: string; + isAdmin: boolean; + isDebug: boolean; + isDocker: boolean; + isLinux: boolean; + isNetCore: boolean; + isOsx: boolean; + isProduction: boolean; + isUserInteractive: boolean; + isWindows: boolean; + migrationVersion: number; + mode: string; + osName: string; + osVersion: string; + packageUpdateMechanism: string; + runtimeName: string; + runtimeVersion: string; + sqliteVersion: string; + startTime: string; + startupPath: string; + urlBase: string; + version: string; +} + +export default SystemStatus;