mirror of
https://github.com/Prowlarr/Prowlarr.git
synced 2025-09-17 17:14:18 +02:00
Convert store selectors to Typescript
This commit is contained in:
@@ -5,6 +5,7 @@ import IndexerAppState, {
|
|||||||
} from './IndexerAppState';
|
} from './IndexerAppState';
|
||||||
import IndexerStatsAppState from './IndexerStatsAppState';
|
import IndexerStatsAppState from './IndexerStatsAppState';
|
||||||
import SettingsAppState from './SettingsAppState';
|
import SettingsAppState from './SettingsAppState';
|
||||||
|
import SystemAppState from './SystemAppState';
|
||||||
import TagsAppState from './TagsAppState';
|
import TagsAppState from './TagsAppState';
|
||||||
|
|
||||||
interface FilterBuilderPropOption {
|
interface FilterBuilderPropOption {
|
||||||
@@ -46,6 +47,7 @@ interface AppState {
|
|||||||
indexerStatus: IndexerStatusAppState;
|
indexerStatus: IndexerStatusAppState;
|
||||||
indexers: IndexerAppState;
|
indexers: IndexerAppState;
|
||||||
settings: SettingsAppState;
|
settings: SettingsAppState;
|
||||||
|
system: SystemAppState;
|
||||||
tags: TagsAppState;
|
tags: TagsAppState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,7 +28,9 @@ export interface IndexerIndexAppState {
|
|||||||
interface IndexerAppState
|
interface IndexerAppState
|
||||||
extends AppSectionState<Indexer>,
|
extends AppSectionState<Indexer>,
|
||||||
AppSectionDeleteState,
|
AppSectionDeleteState,
|
||||||
AppSectionSaveState {}
|
AppSectionSaveState {
|
||||||
|
itemMap: Record<number, number>;
|
||||||
|
}
|
||||||
|
|
||||||
export type IndexerStatusAppState = AppSectionState<IndexerStatus>;
|
export type IndexerStatusAppState = AppSectionState<IndexerStatus>;
|
||||||
|
|
||||||
|
10
frontend/src/App/State/ReleaseAppState.ts
Normal file
10
frontend/src/App/State/ReleaseAppState.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import AppSectionState, {
|
||||||
|
AppSectionDeleteState,
|
||||||
|
} from 'App/State/AppSectionState';
|
||||||
|
import Release from 'typings/Release';
|
||||||
|
|
||||||
|
interface ReleaseAppState
|
||||||
|
extends AppSectionState<Release>,
|
||||||
|
AppSectionDeleteState {}
|
||||||
|
|
||||||
|
export default ReleaseAppState;
|
@@ -1,5 +1,6 @@
|
|||||||
import AppSectionState, {
|
import AppSectionState, {
|
||||||
AppSectionDeleteState,
|
AppSectionDeleteState,
|
||||||
|
AppSectionItemState,
|
||||||
AppSectionSaveState,
|
AppSectionSaveState,
|
||||||
} from 'App/State/AppSectionState';
|
} from 'App/State/AppSectionState';
|
||||||
import Application from 'typings/Application';
|
import Application from 'typings/Application';
|
||||||
@@ -26,14 +27,14 @@ export interface NotificationAppState
|
|||||||
extends AppSectionState<Notification>,
|
extends AppSectionState<Notification>,
|
||||||
AppSectionDeleteState {}
|
AppSectionDeleteState {}
|
||||||
|
|
||||||
export type UiSettingsAppState = AppSectionState<UiSettings>;
|
export type UiSettingsAppState = AppSectionItemState<UiSettings>;
|
||||||
|
|
||||||
interface SettingsAppState {
|
interface SettingsAppState {
|
||||||
appProfiles: AppProfileAppState;
|
appProfiles: AppProfileAppState;
|
||||||
applications: ApplicationAppState;
|
applications: ApplicationAppState;
|
||||||
downloadClients: DownloadClientAppState;
|
downloadClients: DownloadClientAppState;
|
||||||
notifications: NotificationAppState;
|
notifications: NotificationAppState;
|
||||||
uiSettings: UiSettingsAppState;
|
ui: UiSettingsAppState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SettingsAppState;
|
export default SettingsAppState;
|
||||||
|
10
frontend/src/App/State/SystemAppState.ts
Normal file
10
frontend/src/App/State/SystemAppState.ts
Normal file
@@ -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,28 @@
|
|||||||
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;
|
||||||
|
applicationIds: number[];
|
||||||
|
indexerIds: number[];
|
||||||
|
indexerProxyIds: number[];
|
||||||
|
notificationIds: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TagDetailAppState
|
||||||
|
extends AppSectionState<TagDetail>,
|
||||||
|
AppSectionDeleteState,
|
||||||
|
AppSectionSaveState {}
|
||||||
|
|
||||||
|
interface TagsAppState extends AppSectionState<Tag>, AppSectionDeleteState {
|
||||||
|
details: TagDetailAppState;
|
||||||
|
}
|
||||||
|
|
||||||
export default TagsAppState;
|
export default TagsAppState;
|
||||||
|
@@ -6,6 +6,7 @@ import ModalContent from 'Components/Modal/ModalContent';
|
|||||||
import ModalFooter from 'Components/Modal/ModalFooter';
|
import ModalFooter from 'Components/Modal/ModalFooter';
|
||||||
import ModalHeader from 'Components/Modal/ModalHeader';
|
import ModalHeader from 'Components/Modal/ModalHeader';
|
||||||
import { kinds } from 'Helpers/Props';
|
import { kinds } from 'Helpers/Props';
|
||||||
|
import Indexer from 'Indexer/Indexer';
|
||||||
import { deleteIndexer } from 'Store/Actions/indexerActions';
|
import { deleteIndexer } from 'Store/Actions/indexerActions';
|
||||||
import { createIndexerSelectorForHook } from 'Store/Selectors/createIndexerSelector';
|
import { createIndexerSelectorForHook } from 'Store/Selectors/createIndexerSelector';
|
||||||
import translate from 'Utilities/String/translate';
|
import translate from 'Utilities/String/translate';
|
||||||
@@ -18,7 +19,9 @@ interface DeleteIndexerModalContentProps {
|
|||||||
function DeleteIndexerModalContent(props: DeleteIndexerModalContentProps) {
|
function DeleteIndexerModalContent(props: DeleteIndexerModalContentProps) {
|
||||||
const { indexerId, onModalClose } = props;
|
const { indexerId, onModalClose } = props;
|
||||||
|
|
||||||
const { name } = useSelector(createIndexerSelectorForHook(indexerId));
|
const { name } = useSelector(
|
||||||
|
createIndexerSelectorForHook(indexerId)
|
||||||
|
) as Indexer;
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const onConfirmDelete = useCallback(() => {
|
const onConfirmDelete = useCallback(() => {
|
||||||
|
@@ -12,6 +12,7 @@ import { icons } from 'Helpers/Props';
|
|||||||
import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal';
|
import DeleteIndexerModal from 'Indexer/Delete/DeleteIndexerModal';
|
||||||
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
|
import EditIndexerModalConnector from 'Indexer/Edit/EditIndexerModalConnector';
|
||||||
import createIndexerIndexItemSelector from 'Indexer/Index/createIndexerIndexItemSelector';
|
import createIndexerIndexItemSelector from 'Indexer/Index/createIndexerIndexItemSelector';
|
||||||
|
import Indexer from 'Indexer/Indexer';
|
||||||
import IndexerTitleLink from 'Indexer/IndexerTitleLink';
|
import IndexerTitleLink from 'Indexer/IndexerTitleLink';
|
||||||
import { SelectStateInputProps } from 'typings/props';
|
import { SelectStateInputProps } from 'typings/props';
|
||||||
import firstCharToUpper from 'Utilities/String/firstCharToUpper';
|
import firstCharToUpper from 'Utilities/String/firstCharToUpper';
|
||||||
@@ -47,7 +48,7 @@ function IndexerIndexRow(props: IndexerIndexRowProps) {
|
|||||||
fields,
|
fields,
|
||||||
added,
|
added,
|
||||||
capabilities,
|
capabilities,
|
||||||
} = indexer;
|
} = indexer as Indexer;
|
||||||
|
|
||||||
const baseUrl =
|
const baseUrl =
|
||||||
fields.find((field) => field.name === 'baseUrl')?.value ??
|
fields.find((field) => field.name === 'baseUrl')?.value ??
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import Indexer from 'Indexer/Indexer';
|
|
||||||
import createIndexerAppProfileSelector from 'Store/Selectors/createIndexerAppProfileSelector';
|
import createIndexerAppProfileSelector from 'Store/Selectors/createIndexerAppProfileSelector';
|
||||||
import { createIndexerSelectorForHook } from 'Store/Selectors/createIndexerSelector';
|
import { createIndexerSelectorForHook } from 'Store/Selectors/createIndexerSelector';
|
||||||
import createIndexerStatusSelector from 'Store/Selectors/createIndexerStatusSelector';
|
import createIndexerStatusSelector from 'Store/Selectors/createIndexerStatusSelector';
|
||||||
@@ -11,7 +10,7 @@ function createIndexerIndexItemSelector(indexerId: number) {
|
|||||||
createIndexerAppProfileSelector(indexerId),
|
createIndexerAppProfileSelector(indexerId),
|
||||||
createIndexerStatusSelector(indexerId),
|
createIndexerStatusSelector(indexerId),
|
||||||
createUISettingsSelector(),
|
createUISettingsSelector(),
|
||||||
(indexer: Indexer, appProfile, status, uiSettings) => {
|
(indexer, appProfile, status, uiSettings) => {
|
||||||
return {
|
return {
|
||||||
indexer,
|
indexer,
|
||||||
appProfile,
|
appProfile,
|
||||||
|
@@ -25,11 +25,13 @@ export interface IndexerCapabilities extends ModelBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IndexerField extends ModelBase {
|
export interface IndexerField extends ModelBase {
|
||||||
|
order: number;
|
||||||
name: string;
|
name: string;
|
||||||
label: string;
|
label: string;
|
||||||
advanced: boolean;
|
advanced: boolean;
|
||||||
type: string;
|
type: string;
|
||||||
value: string;
|
value: string;
|
||||||
|
privacy: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Indexer extends ModelBase {
|
interface Indexer extends ModelBase {
|
||||||
@@ -54,6 +56,11 @@ interface Indexer extends ModelBase {
|
|||||||
capabilities: IndexerCapabilities;
|
capabilities: IndexerCapabilities;
|
||||||
indexerUrls: string[];
|
indexerUrls: string[];
|
||||||
legacyUrls: string[];
|
legacyUrls: string[];
|
||||||
|
appProfileId: number;
|
||||||
|
implementationName: string;
|
||||||
|
implementation: string;
|
||||||
|
configContract: string;
|
||||||
|
infoLink: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Indexer;
|
export default Indexer;
|
||||||
|
@@ -29,7 +29,7 @@ import styles from './IndexerInfoModalContent.css';
|
|||||||
function createIndexerInfoItemSelector(indexerId: number) {
|
function createIndexerInfoItemSelector(indexerId: number) {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
createIndexerSelectorForHook(indexerId),
|
createIndexerSelectorForHook(indexerId),
|
||||||
(indexer: Indexer) => {
|
(indexer?: Indexer) => {
|
||||||
return {
|
return {
|
||||||
indexer,
|
indexer,
|
||||||
};
|
};
|
||||||
@@ -58,7 +58,7 @@ function IndexerInfoModalContent(props: IndexerInfoModalContentProps) {
|
|||||||
tags,
|
tags,
|
||||||
protocol,
|
protocol,
|
||||||
capabilities,
|
capabilities,
|
||||||
} = indexer;
|
} = indexer as Indexer;
|
||||||
|
|
||||||
const { onModalClose } = props;
|
const { onModalClose } = props;
|
||||||
|
|
||||||
|
@@ -1,15 +0,0 @@
|
|||||||
import { createSelector } from 'reselect';
|
|
||||||
|
|
||||||
function createAppProfileSelector() {
|
|
||||||
return createSelector(
|
|
||||||
(state, { appProfileId }) => appProfileId,
|
|
||||||
(state) => state.settings.appProfiles.items,
|
|
||||||
(appProfileId, appProfiles) => {
|
|
||||||
return appProfiles.find((profile) => {
|
|
||||||
return profile.id === appProfileId;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default createAppProfileSelector;
|
|
14
frontend/src/Store/Selectors/createAppProfileSelector.ts
Normal file
14
frontend/src/Store/Selectors/createAppProfileSelector.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import AppState from 'App/State/AppState';
|
||||||
|
|
||||||
|
function createAppProfileSelector() {
|
||||||
|
return createSelector(
|
||||||
|
(_: AppState, { appProfileId }: { appProfileId: number }) => appProfileId,
|
||||||
|
(state: AppState) => state.settings.appProfiles.items,
|
||||||
|
(appProfileId, appProfiles) => {
|
||||||
|
return appProfiles.find((profile) => profile.id === appProfileId);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createAppProfileSelector;
|
@@ -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),
|
|
||||||
(command) => {
|
|
||||||
return isCommandExecuting(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;
|
|
11
frontend/src/Store/Selectors/createCommandSelector.ts
Normal file
11
frontend/src/Store/Selectors/createCommandSelector.ts
Normal file
@@ -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,9 +0,0 @@
|
|||||||
import _ from 'lodash';
|
|
||||||
import { createSelectorCreator, defaultMemoize } from 'reselect';
|
|
||||||
|
|
||||||
const createDeepEqualSelector = createSelectorCreator(
|
|
||||||
defaultMemoize,
|
|
||||||
_.isEqual
|
|
||||||
);
|
|
||||||
|
|
||||||
export default createDeepEqualSelector;
|
|
6
frontend/src/Store/Selectors/createDeepEqualSelector.ts
Normal file
6
frontend/src/Store/Selectors/createDeepEqualSelector.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { isEqual } from 'lodash';
|
||||||
|
import { createSelectorCreator, defaultMemoize } from 'reselect';
|
||||||
|
|
||||||
|
const createDeepEqualSelector = createSelectorCreator(defaultMemoize, isEqual);
|
||||||
|
|
||||||
|
export default createDeepEqualSelector;
|
@@ -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 createAllIndexersSelector from './createAllIndexersSelector';
|
import createAllIndexersSelector from './createAllIndexersSelector';
|
||||||
|
|
||||||
function createExistingIndexerSelector() {
|
function createExistingIndexerSelector() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state, { definitionName }) => definitionName,
|
(_: AppState, { definitionName }: { definitionName: string }) =>
|
||||||
|
definitionName,
|
||||||
createAllIndexersSelector(),
|
createAllIndexersSelector(),
|
||||||
(definitionName, indexers) => {
|
(definitionName, indexers) => {
|
||||||
return _.some(indexers, { definitionName });
|
return some(indexers, { definitionName });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
@@ -1,15 +1,14 @@
|
|||||||
import { createSelector } from 'reselect';
|
import { createSelector } from 'reselect';
|
||||||
import AppState from 'App/State/AppState';
|
import AppState from 'App/State/AppState';
|
||||||
|
import Indexer from 'Indexer/Indexer';
|
||||||
import { createIndexerSelectorForHook } from './createIndexerSelector';
|
import { createIndexerSelectorForHook } from './createIndexerSelector';
|
||||||
|
|
||||||
function createIndexerAppProfileSelector(indexerId: number) {
|
function createIndexerAppProfileSelector(indexerId: number) {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state: AppState) => state.settings.appProfiles.items,
|
(state: AppState) => state.settings.appProfiles.items,
|
||||||
createIndexerSelectorForHook(indexerId),
|
createIndexerSelectorForHook(indexerId),
|
||||||
(appProfiles, indexer = {}) => {
|
(appProfiles, indexer = {} as Indexer) => {
|
||||||
return appProfiles.find((profile) => {
|
return appProfiles.find((profile) => profile.id === indexer.appProfileId);
|
||||||
return profile.id === indexer.appProfileId;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@@ -1,24 +0,0 @@
|
|||||||
import { createSelector } from 'reselect';
|
|
||||||
|
|
||||||
export function createIndexerSelectorForHook(indexerId) {
|
|
||||||
return createSelector(
|
|
||||||
(state) => state.indexers.itemMap,
|
|
||||||
(state) => state.indexers.items,
|
|
||||||
(itemMap, allIndexers) => {
|
|
||||||
return indexerId ? allIndexers[itemMap[indexerId]]: undefined;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createIndexerSelector() {
|
|
||||||
return createSelector(
|
|
||||||
(state, { indexerId }) => indexerId,
|
|
||||||
(state) => state.indexers.itemMap,
|
|
||||||
(state) => state.indexers.items,
|
|
||||||
(indexerId, itemMap, allIndexers) => {
|
|
||||||
return allIndexers[itemMap[indexerId]];
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default createIndexerSelector;
|
|
25
frontend/src/Store/Selectors/createIndexerSelector.ts
Normal file
25
frontend/src/Store/Selectors/createIndexerSelector.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import AppState from 'App/State/AppState';
|
||||||
|
|
||||||
|
export function createIndexerSelectorForHook(indexerId: number) {
|
||||||
|
return createSelector(
|
||||||
|
(state: AppState) => state.indexers.itemMap,
|
||||||
|
(state: AppState) => state.indexers.items,
|
||||||
|
(itemMap, allIndexers) => {
|
||||||
|
return indexerId ? allIndexers[itemMap[indexerId]] : undefined;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function createIndexerSelector() {
|
||||||
|
return createSelector(
|
||||||
|
(_: AppState, { indexerId }: { indexerId: number }) => indexerId,
|
||||||
|
(state: AppState) => state.indexers.itemMap,
|
||||||
|
(state: AppState) => state.indexers.items,
|
||||||
|
(indexerId, itemMap, allIndexers) => {
|
||||||
|
return allIndexers[itemMap[indexerId]];
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createIndexerSelector;
|
@@ -1,24 +0,0 @@
|
|||||||
import _ from 'lodash';
|
|
||||||
import { createSelector } from 'reselect';
|
|
||||||
import createAllIndexersSelector from './createAllIndexersSelector';
|
|
||||||
|
|
||||||
function createProfileInUseSelector(profileProp) {
|
|
||||||
return createSelector(
|
|
||||||
(state, { id }) => id,
|
|
||||||
(state) => state.settings.appProfiles.items,
|
|
||||||
createAllIndexersSelector(),
|
|
||||||
(id, profiles, indexers) => {
|
|
||||||
if (!id) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_.some(indexers, { [profileProp]: id }) || profiles.length <= 1) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default createProfileInUseSelector;
|
|
21
frontend/src/Store/Selectors/createProfileInUseSelector.ts
Normal file
21
frontend/src/Store/Selectors/createProfileInUseSelector.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { some } from 'lodash';
|
||||||
|
import { createSelector } from 'reselect';
|
||||||
|
import AppState from 'App/State/AppState';
|
||||||
|
import createAllIndexersSelector from './createAllIndexersSelector';
|
||||||
|
|
||||||
|
function createProfileInUseSelector(profileProp: string) {
|
||||||
|
return createSelector(
|
||||||
|
(_: AppState, { id }: { id: number }) => id,
|
||||||
|
(state: AppState) => state.settings.appProfiles.items,
|
||||||
|
createAllIndexersSelector(),
|
||||||
|
(id, profiles, indexers) => {
|
||||||
|
if (!id) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return some(indexers, { [profileProp]: id }) || profiles.length <= 1;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default createProfileInUseSelector;
|
@@ -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 createUISettingsSelector() {
|
function createUISettingsSelector() {
|
||||||
return createSelector(
|
return createSelector(
|
||||||
(state) => state.settings.ui,
|
(state: AppState) => state.settings.ui,
|
||||||
(ui) => {
|
(ui) => {
|
||||||
return ui.item;
|
return ui.item;
|
||||||
}
|
}
|
@@ -1,27 +0,0 @@
|
|||||||
import ModelBase from 'App/ModelBase';
|
|
||||||
|
|
||||||
export interface Field {
|
|
||||||
order: number;
|
|
||||||
name: string;
|
|
||||||
label: string;
|
|
||||||
value: boolean | number | string;
|
|
||||||
type: string;
|
|
||||||
advanced: boolean;
|
|
||||||
privacy: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Indexer extends ModelBase {
|
|
||||||
enable: boolean;
|
|
||||||
appProfileId: number;
|
|
||||||
protocol: string;
|
|
||||||
priority: number;
|
|
||||||
name: string;
|
|
||||||
fields: Field[];
|
|
||||||
implementationName: string;
|
|
||||||
implementation: string;
|
|
||||||
configContract: string;
|
|
||||||
infoLink: string;
|
|
||||||
tags: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Indexer;
|
|
28
frontend/src/typings/Release.ts
Normal file
28
frontend/src/typings/Release.ts
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import ModelBase from 'App/ModelBase';
|
||||||
|
import { IndexerCategory } from 'Indexer/Indexer';
|
||||||
|
|
||||||
|
interface Release extends ModelBase {
|
||||||
|
guid: string;
|
||||||
|
categories: IndexerCategory[];
|
||||||
|
protocol: string;
|
||||||
|
title: string;
|
||||||
|
sortTitle: string;
|
||||||
|
fileName: string;
|
||||||
|
infoUrl: string;
|
||||||
|
downloadUrl?: string;
|
||||||
|
magnetUrl?: string;
|
||||||
|
indexerId: number;
|
||||||
|
indexer: string;
|
||||||
|
age: number;
|
||||||
|
ageHours: number;
|
||||||
|
ageMinutes: number;
|
||||||
|
publishDate: string;
|
||||||
|
size?: number;
|
||||||
|
files?: number;
|
||||||
|
grabs?: number;
|
||||||
|
seeders?: number;
|
||||||
|
leechers?: number;
|
||||||
|
indexerFlags: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Release;
|
31
frontend/src/typings/SystemStatus.ts
Normal file
31
frontend/src/typings/SystemStatus.ts
Normal file
@@ -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;
|
Reference in New Issue
Block a user