Convert store selectors to Typescript

Closes #3937
pull/4686/head
Bogdan 10 months ago
parent bc69fa4842
commit db9e62f79d

@ -28,7 +28,8 @@ module.exports = {
globals: { globals: {
expect: false, expect: false,
chai: false, chai: false,
sinon: false sinon: false,
JSX: true
}, },
parserOptions: { parserOptions: {

@ -5,6 +5,7 @@ import CommandAppState from './CommandAppState';
import HistoryAppState from './HistoryAppState'; import HistoryAppState from './HistoryAppState';
import QueueAppState from './QueueAppState'; import QueueAppState from './QueueAppState';
import SettingsAppState from './SettingsAppState'; import SettingsAppState from './SettingsAppState';
import SystemAppState from './SystemAppState';
import TagsAppState from './TagsAppState'; import TagsAppState from './TagsAppState';
import TrackFilesAppState from './TrackFilesAppState'; import TrackFilesAppState from './TrackFilesAppState';
import TracksAppState from './TracksAppState'; import TracksAppState from './TracksAppState';
@ -62,6 +63,7 @@ interface AppState {
tags: TagsAppState; tags: TagsAppState;
trackFiles: TrackFilesAppState; trackFiles: TrackFilesAppState;
tracksSelection: TracksAppState; tracksSelection: TracksAppState;
system: SystemAppState;
} }
export default AppState; export default AppState;

@ -1,5 +1,6 @@
import AppSectionState, { import AppSectionState, {
AppSectionDeleteState, AppSectionDeleteState,
AppSectionItemState,
AppSectionSaveState, AppSectionSaveState,
AppSectionSchemaState, AppSectionSchemaState,
} from 'App/State/AppSectionState'; } from 'App/State/AppSectionState';
@ -46,7 +47,7 @@ export interface RootFolderAppState
AppSectionSaveState {} AppSectionSaveState {}
export type IndexerFlagSettingsAppState = AppSectionState<IndexerFlag>; export type IndexerFlagSettingsAppState = AppSectionState<IndexerFlag>;
export type UiSettingsAppState = AppSectionState<UiSettings>; export type UiSettingsAppState = AppSectionItemState<UiSettings>;
interface SettingsAppState { interface SettingsAppState {
downloadClients: DownloadClientAppState; downloadClients: DownloadClientAppState;
@ -57,7 +58,7 @@ interface SettingsAppState {
notifications: NotificationAppState; notifications: NotificationAppState;
qualityProfiles: QualityProfilesAppState; qualityProfiles: QualityProfilesAppState;
rootFolders: RootFolderAppState; rootFolders: RootFolderAppState;
uiSettings: UiSettingsAppState; ui: UiSettingsAppState;
} }
export default SettingsAppState; export default SettingsAppState;

@ -0,0 +1,10 @@
import SystemStatus from 'typings/SystemStatus';
import { AppSectionItemState } from './AppSectionState';
export type SystemStatusAppState = AppSectionItemState<SystemStatus>;
interface SystemAppState {
status: SystemStatusAppState;
}
export default SystemAppState;

@ -1,12 +1,32 @@
import ModelBase from 'App/ModelBase'; import ModelBase from 'App/ModelBase';
import AppSectionState, { import AppSectionState, {
AppSectionDeleteState, AppSectionDeleteState,
AppSectionSaveState,
} from 'App/State/AppSectionState'; } from 'App/State/AppSectionState';
export interface Tag extends ModelBase { export interface Tag extends ModelBase {
label: string; label: string;
} }
interface TagsAppState extends AppSectionState<Tag>, AppSectionDeleteState {} export interface TagDetail extends ModelBase {
label: string;
autoTagIds: number[];
delayProfileIds: number[];
downloadClientIds: [];
importListIds: number[];
indexerIds: number[];
notificationIds: number[];
restrictionIds: number[];
artistIds: number[];
}
export interface TagDetailAppState
extends AppSectionState<TagDetail>,
AppSectionDeleteState,
AppSectionSaveState {}
interface TagsAppState extends AppSectionState<Tag>, AppSectionDeleteState {
details: TagDetailAppState;
}
export default TagsAppState; export default TagsAppState;

@ -1,8 +1,9 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createAllArtistSelector() { function createAllArtistSelector() {
return createSelector( return createSelector(
(state) => state.artist, (state: AppState) => state.artist,
(artist) => { (artist) => {
return artist.items; return artist.items;
} }

@ -1,18 +1,19 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import createAllArtistSelector from './createAllArtistSelector'; import createAllArtistSelector from './createAllArtistSelector';
function createArtistCountSelector() { function createArtistCountSelector() {
return createSelector( return createSelector(
createAllArtistSelector(), createAllArtistSelector(),
(state) => state.artist.error, (state: AppState) => state.artist.error,
(state) => state.artist.isFetching, (state: AppState) => state.artist.isFetching,
(state) => state.artist.isPopulated, (state: AppState) => state.artist.isPopulated,
(artists, error, isFetching, isPopulated) => { (artists, error, isFetching, isPopulated) => {
return { return {
count: artists.length, count: artists.length,
error, error,
isFetching, isFetching,
isPopulated isPopulated,
}; };
} }
); );

@ -2,13 +2,10 @@ import { createSelector } from 'reselect';
import { isCommandExecuting } from 'Utilities/Command'; import { isCommandExecuting } from 'Utilities/Command';
import createCommandSelector from './createCommandSelector'; import createCommandSelector from './createCommandSelector';
function createCommandExecutingSelector(name, contraints = {}) { function createCommandExecutingSelector(name: string, contraints = {}) {
return createSelector( return createSelector(createCommandSelector(name, contraints), (command) => {
createCommandSelector(name, contraints), return isCommandExecuting(command);
(command) => { });
return isCommandExecuting(command);
}
);
} }
export default createCommandExecutingSelector; export default createCommandExecutingSelector;

@ -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;

@ -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;

@ -1,8 +1,9 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createCommandsSelector() { function createCommandsSelector() {
return createSelector( return createSelector(
(state) => state.commands, (state: AppState) => state.commands,
(commands) => { (commands) => {
return commands.items; return commands.items;
} }

@ -1,9 +0,0 @@
import _ from 'lodash';
import { createSelectorCreator, defaultMemoize } from 'reselect';
const createDeepEqualSelector = createSelectorCreator(
defaultMemoize,
_.isEqual
);
export default createDeepEqualSelector;

@ -0,0 +1,6 @@
import { isEqual } from 'lodash';
import { createSelectorCreator, defaultMemoize } from 'reselect';
const createDeepEqualSelector = createSelectorCreator(defaultMemoize, isEqual);
export default createDeepEqualSelector;

@ -1,9 +1,10 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import { isCommandExecuting } from 'Utilities/Command'; import { isCommandExecuting } from 'Utilities/Command';
function createExecutingCommandsSelector() { function createExecutingCommandsSelector() {
return createSelector( return createSelector(
(state) => state.commands.items, (state: AppState) => state.commands.items,
(commands) => { (commands) => {
return commands.filter((command) => isCommandExecuting(command)); return commands.filter((command) => isCommandExecuting(command));
} }

@ -1,13 +1,15 @@
import _ from 'lodash'; import { some } from 'lodash';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import createAllArtistSelector from './createAllArtistSelector'; import createAllArtistSelector from './createAllArtistSelector';
function createExistingArtistSelector() { function createExistingArtistSelector() {
return createSelector( return createSelector(
(state, { foreignArtistId }) => foreignArtistId, (_: AppState, { foreignArtistId }: { foreignArtistId: string }) =>
foreignArtistId,
createAllArtistSelector(), createAllArtistSelector(),
(foreignArtistId, artist) => { (foreignArtistId, artist) => {
return _.some(artist, { foreignArtistId }); return some(artist, { foreignArtistId });
} }
); );
} }

@ -1,15 +0,0 @@
import { createSelector } from 'reselect';
function createMetadataProfileSelector() {
return createSelector(
(state, { metadataProfileId }) => metadataProfileId,
(state) => state.settings.metadataProfiles.items,
(metadataProfileId, metadataProfiles) => {
return metadataProfiles.find((profile) => {
return profile.id === metadataProfileId;
});
}
);
}
export default createMetadataProfileSelector;

@ -0,0 +1,17 @@
import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createMetadataProfileSelector() {
return createSelector(
(_: AppState, { metadataProfileId }: { metadataProfileId: number }) =>
metadataProfileId,
(state: AppState) => state.settings.metadataProfiles.items,
(metadataProfileId, metadataProfiles) => {
return metadataProfiles.find(
(profile) => profile.id === metadataProfileId
);
}
);
}
export default createMetadataProfileSelector;

@ -1,24 +0,0 @@
import _ from 'lodash';
import { createSelector } from 'reselect';
import createAllArtistSelector from './createAllArtistSelector';
function createProfileInUseSelector(profileProp) {
return createSelector(
(state, { id }) => id,
createAllArtistSelector(),
(state) => state.settings.importLists.items,
(id, artist, lists) => {
if (!id) {
return false;
}
if (_.some(artist, { [profileProp]: id }) || _.some(lists, { [profileProp]: id })) {
return true;
}
return false;
}
);
}
export default createProfileInUseSelector;

@ -0,0 +1,25 @@
import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import Artist from 'Artist/Artist';
import ImportList from 'typings/ImportList';
import createAllArtistSelector from './createAllArtistSelector';
function createProfileInUseSelector(profileProp: string) {
return createSelector(
(_: AppState, { id }: { id: number }) => id,
createAllArtistSelector(),
(state: AppState) => state.settings.importLists.items,
(id, artists, lists) => {
if (!id) {
return false;
}
return (
artists.some((a) => a[profileProp as keyof Artist] === id) ||
lists.some((list) => list[profileProp as keyof ImportList] === id)
);
}
);
}
export default createProfileInUseSelector;

@ -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;

@ -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;

@ -1,21 +1,16 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createQueueItemSelector() { function createQueueItemSelector() {
return createSelector( return createSelector(
(state, { albumId }) => albumId, (_: AppState, { albumId }: { albumId: number }) => albumId,
(state) => state.queue.details.items, (state: AppState) => state.queue.details.items,
(albumId, details) => { (albumId, details) => {
if (!albumId || !details) { if (!albumId || !details) {
return null; return null;
} }
return details.find((item) => { return details.find((item) => item.albumId === albumId);
if (item.album) {
return item.album.id === albumId;
}
return false;
});
} }
); );
} }

@ -1,8 +1,9 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createSystemStatusSelector() { function createSystemStatusSelector() {
return createSelector( return createSelector(
(state) => state.system.status, (state: AppState) => state.system.status,
(status) => { (status) => {
return status.item; return status.item;
} }

@ -1,9 +1,10 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createTagDetailsSelector() { function createTagDetailsSelector() {
return createSelector( return createSelector(
(state, { id }) => id, (_: AppState, { id }: { id: number }) => id,
(state) => state.tags.details.items, (state: AppState) => state.tags.details.items,
(id, tagDetails) => { (id, tagDetails) => {
return tagDetails.find((t) => t.id === id); return tagDetails.find((t) => t.id === id);
} }

@ -1,8 +1,9 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createTagsSelector() { function createTagsSelector() {
return createSelector( return createSelector(
(state) => state.tags.items, (state: AppState) => state.tags.items,
(tags) => { (tags) => {
return tags; return tags;
} }

@ -1,9 +1,10 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createTrackFileSelector() { function createTrackFileSelector() {
return createSelector( return createSelector(
(state, { trackFileId }) => trackFileId, (_: AppState, { trackFileId }: { trackFileId: number }) => trackFileId,
(state) => state.trackFiles, (state: AppState) => state.trackFiles,
(trackFileId, trackFiles) => { (trackFileId, trackFiles) => {
if (!trackFileId) { if (!trackFileId) {
return; return;

@ -1,8 +1,9 @@
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
function createUISettingsSelector() { function createUISettingsSelector() {
return createSelector( return createSelector(
(state) => state.settings.ui, (state: AppState) => state.settings.ui,
(ui) => { (ui) => {
return ui.item; return ui.item;
} }

@ -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;
Loading…
Cancel
Save