mirror of
https://github.com/Sonarr/Sonarr.git
synced 2026-04-18 21:35:27 -04:00
Use react-query for Quality Profiles
This commit is contained in:
@@ -7,6 +7,7 @@ import EditQualityProfileModalContent from './EditQualityProfileModalContent';
|
||||
|
||||
interface EditQualityProfileModalProps {
|
||||
id?: number;
|
||||
cloneId?: number;
|
||||
isOpen: boolean;
|
||||
onDeleteQualityProfilePress?: () => void;
|
||||
onModalClose: () => void;
|
||||
@@ -14,6 +15,7 @@ interface EditQualityProfileModalProps {
|
||||
|
||||
function EditQualityProfileModal({
|
||||
id,
|
||||
cloneId,
|
||||
isOpen,
|
||||
onDeleteQualityProfilePress,
|
||||
onModalClose,
|
||||
@@ -44,6 +46,7 @@ function EditQualityProfileModal({
|
||||
>
|
||||
<EditQualityProfileModalContent
|
||||
id={id}
|
||||
cloneId={cloneId}
|
||||
onContentHeightChange={handleContentHeightChange}
|
||||
onDeleteQualityProfilePress={onDeleteQualityProfilePress}
|
||||
onModalClose={handleOnModalClose}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { QualityProfilesAppState } from 'App/State/SettingsAppState';
|
||||
import Alert from 'Components/Alert';
|
||||
import Form from 'Components/Form/Form';
|
||||
import FormGroup from 'Components/Form/FormGroup';
|
||||
@@ -17,18 +15,8 @@ import useMeasure from 'Helpers/Hooks/useMeasure';
|
||||
import usePrevious from 'Helpers/Hooks/usePrevious';
|
||||
import { inputTypes, kinds, sizes } from 'Helpers/Props';
|
||||
import useQualityProfileInUse from 'Settings/Profiles/Quality/useQualityProfileInUse';
|
||||
import {
|
||||
fetchQualityProfileSchema,
|
||||
saveQualityProfile,
|
||||
setQualityProfileValue,
|
||||
} from 'Store/Actions/settingsActions';
|
||||
import { createProviderSettingsSelectorHook } from 'Store/Selectors/createProviderSettingsSelector';
|
||||
import dimensions from 'Styles/Variables/dimensions';
|
||||
import { InputChanged } from 'typings/inputs';
|
||||
import QualityProfile, {
|
||||
QualityProfileGroup,
|
||||
QualityProfileQualityItem,
|
||||
} from 'typings/QualityProfile';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QualityProfileFormatItems from './QualityProfileFormatItems';
|
||||
import { DragMoveState } from './QualityProfileItemDragSource';
|
||||
@@ -36,6 +24,11 @@ import QualityProfileItems, {
|
||||
EditQualityProfileMode,
|
||||
} from './QualityProfileItems';
|
||||
import { SizeChanged } from './QualityProfileItemSize';
|
||||
import {
|
||||
QualityProfileGroup,
|
||||
QualityProfileQualityItem,
|
||||
useManageQualityProfile,
|
||||
} from './useQualityProfiles';
|
||||
import styles from './EditQualityProfileModalContent.css';
|
||||
|
||||
const MODAL_BODY_PADDING = parseInt(dimensions.modalBodyPadding);
|
||||
@@ -52,6 +45,7 @@ function parseIndex(index: string): [number | null, number] {
|
||||
|
||||
interface EditQualityProfileModalContentProps {
|
||||
id?: number;
|
||||
cloneId?: number;
|
||||
onContentHeightChange: (height: number) => void;
|
||||
onDeleteQualityProfilePress?: () => void;
|
||||
onModalClose: () => void;
|
||||
@@ -59,19 +53,21 @@ interface EditQualityProfileModalContentProps {
|
||||
|
||||
function EditQualityProfileModalContent({
|
||||
id,
|
||||
cloneId,
|
||||
onContentHeightChange,
|
||||
onDeleteQualityProfilePress,
|
||||
onModalClose,
|
||||
}: EditQualityProfileModalContentProps) {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const { error, isFetching, isPopulated, isSaving, saveError, item } =
|
||||
useSelector(
|
||||
createProviderSettingsSelectorHook<
|
||||
QualityProfile,
|
||||
QualityProfilesAppState
|
||||
>('qualityProfiles', id)
|
||||
);
|
||||
const {
|
||||
item,
|
||||
isSaving,
|
||||
saveError,
|
||||
isSchemaFetching,
|
||||
isSchemaFetched,
|
||||
schemaError,
|
||||
updateValue,
|
||||
saveProvider,
|
||||
} = useManageQualityProfile(id, cloneId);
|
||||
|
||||
const isInUse = useQualityProfileInUse(id);
|
||||
|
||||
@@ -132,15 +128,15 @@ function EditQualityProfileModalContent({
|
||||
|
||||
const handleInputChange = useCallback(
|
||||
({ name, value }: InputChanged) => {
|
||||
// @ts-expect-error - actions are not typed
|
||||
dispatch(setQualityProfileValue({ name, value }));
|
||||
// @ts-expect-error - change is not yet typed
|
||||
updateValue(name, value);
|
||||
},
|
||||
[dispatch]
|
||||
[updateValue]
|
||||
);
|
||||
|
||||
const handleSavePress = useCallback(() => {
|
||||
dispatch(saveQualityProfile({ id }));
|
||||
}, [id, dispatch]);
|
||||
saveProvider();
|
||||
}, [saveProvider]);
|
||||
|
||||
const handleCutoffChange = useCallback(
|
||||
({ name, value }: InputChanged<number>) => {
|
||||
@@ -153,10 +149,10 @@ function EditQualityProfileModalContent({
|
||||
'id' in cutoffItem ? cutoffItem.id : cutoffItem.quality.id;
|
||||
|
||||
// @ts-expect-error - actions are not typed
|
||||
dispatch(setQualityProfileValue({ name, value: cutoffId }));
|
||||
updateValue(name, cutoffId);
|
||||
}
|
||||
},
|
||||
[items, dispatch]
|
||||
[items, updateValue]
|
||||
);
|
||||
|
||||
const handleItemAllowedChange = useCallback(
|
||||
@@ -172,15 +168,9 @@ function EditQualityProfileModalContent({
|
||||
return item;
|
||||
});
|
||||
|
||||
dispatch(
|
||||
// @ts-expect-error - actions are not typed
|
||||
setQualityProfileValue({
|
||||
name: 'items',
|
||||
value: newItems,
|
||||
})
|
||||
);
|
||||
updateValue('items', newItems);
|
||||
},
|
||||
[items, dispatch]
|
||||
[items, updateValue]
|
||||
);
|
||||
|
||||
const handleGroupAllowedChange = useCallback(
|
||||
@@ -196,15 +186,9 @@ function EditQualityProfileModalContent({
|
||||
return item;
|
||||
});
|
||||
|
||||
dispatch(
|
||||
// @ts-expect-error - actions are not typed
|
||||
setQualityProfileValue({
|
||||
name: 'items',
|
||||
value: newItems,
|
||||
})
|
||||
);
|
||||
updateValue('items', newItems);
|
||||
},
|
||||
[items, dispatch]
|
||||
[items, updateValue]
|
||||
);
|
||||
|
||||
const handleGroupNameChange = useCallback(
|
||||
@@ -220,10 +204,9 @@ function EditQualityProfileModalContent({
|
||||
return item;
|
||||
});
|
||||
|
||||
// @ts-expect-error - actions are not typed
|
||||
dispatch(setQualityProfileValue({ name: 'items', value: newItems }));
|
||||
updateValue('items', newItems);
|
||||
},
|
||||
[items, dispatch]
|
||||
[items, updateValue]
|
||||
);
|
||||
|
||||
const handleSizeChange = useCallback(
|
||||
@@ -253,15 +236,9 @@ function EditQualityProfileModalContent({
|
||||
};
|
||||
});
|
||||
|
||||
dispatch(
|
||||
// @ts-expect-error - actions are not typed
|
||||
setQualityProfileValue({
|
||||
name: 'items',
|
||||
value: newItems,
|
||||
})
|
||||
);
|
||||
updateValue('items', newItems);
|
||||
},
|
||||
[items, dispatch]
|
||||
[items, updateValue]
|
||||
);
|
||||
|
||||
const handleCreateGroupPress = useCallback(
|
||||
@@ -288,10 +265,9 @@ function EditQualityProfileModalContent({
|
||||
return item;
|
||||
});
|
||||
|
||||
// @ts-expect-error - actions are not typed
|
||||
dispatch(setQualityProfileValue({ name: 'items', value: newItems }));
|
||||
updateValue('items', newItems);
|
||||
},
|
||||
[items, dispatch]
|
||||
[items, updateValue]
|
||||
);
|
||||
|
||||
const handleDeleteGroupPress = useCallback(
|
||||
@@ -308,10 +284,9 @@ function EditQualityProfileModalContent({
|
||||
[]
|
||||
);
|
||||
|
||||
// @ts-expect-error - actions are not typed
|
||||
dispatch(setQualityProfileValue({ name: 'items', value: newItems }));
|
||||
updateValue('items', newItems);
|
||||
},
|
||||
[items, dispatch]
|
||||
[items, updateValue]
|
||||
);
|
||||
|
||||
const handleDragMove = useCallback((options: DragMoveState) => {
|
||||
@@ -443,13 +418,7 @@ function EditQualityProfileModalContent({
|
||||
dropGroup.items.splice(dropItemIndex, 0, item);
|
||||
}
|
||||
|
||||
dispatch(
|
||||
// @ts-expect-error - actions are not typed
|
||||
setQualityProfileValue({
|
||||
name: 'items',
|
||||
value: newItems,
|
||||
})
|
||||
);
|
||||
updateValue('items', newItems);
|
||||
}
|
||||
|
||||
setDndState({
|
||||
@@ -458,7 +427,7 @@ function EditQualityProfileModalContent({
|
||||
dropPosition: null,
|
||||
});
|
||||
},
|
||||
[dragQualityIndex, dropQualityIndex, items, dispatch]
|
||||
[dragQualityIndex, dropQualityIndex, items, updateValue]
|
||||
);
|
||||
|
||||
const handleChangeMode = useCallback((newMode: EditQualityProfileMode) => {
|
||||
@@ -478,15 +447,9 @@ function EditQualityProfileModalContent({
|
||||
return formatItem;
|
||||
});
|
||||
|
||||
dispatch(
|
||||
// @ts-expect-error - actions are not typed
|
||||
setQualityProfileValue({
|
||||
name: 'formatItems',
|
||||
value: newFormatItems,
|
||||
})
|
||||
);
|
||||
updateValue('formatItems', newFormatItems);
|
||||
},
|
||||
[formatItems, dispatch]
|
||||
[formatItems, updateValue]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -523,12 +486,6 @@ function EditQualityProfileModalContent({
|
||||
}
|
||||
}, [bodyHeight, mode]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!id && !isPopulated) {
|
||||
dispatch(fetchQualityProfileSchema());
|
||||
}
|
||||
}, [id, isPopulated, dispatch]);
|
||||
|
||||
useEffect(() => {
|
||||
if (wasSaving && !isSaving && !saveError) {
|
||||
onModalClose();
|
||||
@@ -554,11 +511,10 @@ function EditQualityProfileModalContent({
|
||||
cutoffId =
|
||||
'id' in firstAllowed ? firstAllowed.id : firstAllowed.quality.id;
|
||||
|
||||
// @ts-expect-error - actions are not typed
|
||||
dispatch(setQualityProfileValue({ name: 'cutoff', value: cutoffId }));
|
||||
updateValue('cutoff', cutoffId);
|
||||
}
|
||||
}
|
||||
}, [cutoff, items, dispatch]);
|
||||
}, [cutoff, items, updateValue]);
|
||||
|
||||
return (
|
||||
<ModalContent onModalClose={onModalClose}>
|
||||
@@ -568,15 +524,15 @@ function EditQualityProfileModalContent({
|
||||
|
||||
<ModalBody>
|
||||
<div ref={measureBodyRef}>
|
||||
{isPopulated ? null : <LoadingIndicator />}
|
||||
{isSchemaFetched ? null : <LoadingIndicator />}
|
||||
|
||||
{!isFetching && error ? (
|
||||
{!isSchemaFetching && schemaError ? (
|
||||
<Alert kind={kinds.DANGER}>
|
||||
{translate('AddQualityProfileError')}
|
||||
</Alert>
|
||||
) : null}
|
||||
|
||||
{isPopulated && !error ? (
|
||||
{isSchemaFetched && !schemaError ? (
|
||||
<Form>
|
||||
<div className={styles.formGroupsContainer}>
|
||||
<div className={styles.formGroupWrapper}>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import Card from 'Components/Card';
|
||||
import Label from 'Components/Label';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||
import Tooltip from 'Components/Tooltip/Tooltip';
|
||||
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import { deleteQualityProfile } from 'Store/Actions/settingsActions';
|
||||
import { QualityProfileItems } from 'typings/QualityProfile';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditQualityProfileModal from './EditQualityProfileModal';
|
||||
import {
|
||||
QualityProfileItems,
|
||||
useDeleteQualityProfile,
|
||||
} from './useQualityProfiles';
|
||||
import styles from './QualityProfile.css';
|
||||
|
||||
interface QualityProfileProps {
|
||||
@@ -18,7 +19,6 @@ interface QualityProfileProps {
|
||||
upgradeAllowed: boolean;
|
||||
cutoff: number;
|
||||
items: QualityProfileItems;
|
||||
|
||||
isDeleting: boolean;
|
||||
onCloneQualityProfilePress: (id: number) => void;
|
||||
}
|
||||
@@ -32,7 +32,7 @@ function QualityProfile({
|
||||
isDeleting,
|
||||
onCloneQualityProfilePress,
|
||||
}: QualityProfileProps) {
|
||||
const dispatch = useDispatch();
|
||||
const { deleteQualityProfile } = useDeleteQualityProfile(id);
|
||||
|
||||
const [isEditQualityProfileModalOpen, setIsEditQualityProfileModalOpen] =
|
||||
useState(false);
|
||||
@@ -57,8 +57,8 @@ function QualityProfile({
|
||||
}, []);
|
||||
|
||||
const handleConfirmDeleteQualityProfile = useCallback(() => {
|
||||
dispatch(deleteQualityProfile({ id }));
|
||||
}, [id, dispatch]);
|
||||
deleteQualityProfile();
|
||||
}, [deleteQualityProfile]);
|
||||
|
||||
const handleCloneQualityProfilePress = useCallback(() => {
|
||||
onCloneQualityProfilePress(id);
|
||||
|
||||
@@ -4,10 +4,10 @@ import { DragSourceMonitor, useDrag, useDrop, XYCoord } from 'react-dnd';
|
||||
import DragType from 'Helpers/DragType';
|
||||
import useMeasure from 'Helpers/Hooks/useMeasure';
|
||||
import { qualityProfileItemHeight } from 'Styles/Variables/dimensions';
|
||||
import { QualityProfileQualityItem } from 'typings/QualityProfile';
|
||||
import QualityProfileItem from './QualityProfileItem';
|
||||
import QualityProfileItemGroup from './QualityProfileItemGroup';
|
||||
import { SizeChanged } from './QualityProfileItemSize';
|
||||
import { QualityProfileQualityItem } from './useQualityProfiles';
|
||||
import styles from './QualityProfileItemDragSource.css';
|
||||
|
||||
export interface DragMoveState {
|
||||
|
||||
@@ -8,12 +8,12 @@ import Label from 'Components/Label';
|
||||
import IconButton from 'Components/Link/IconButton';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import { InputChanged } from 'typings/inputs';
|
||||
import { QualityProfileQualityItem } from 'typings/QualityProfile';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QualityProfileItemDragSource, {
|
||||
DragMoveState,
|
||||
} from './QualityProfileItemDragSource';
|
||||
import { SizeChanged } from './QualityProfileItemSize';
|
||||
import { QualityProfileQualityItem } from './useQualityProfiles';
|
||||
import styles from './QualityProfileItemGroup.css';
|
||||
|
||||
interface QualityProfileItemGroupProps {
|
||||
|
||||
@@ -7,11 +7,11 @@ import Icon from 'Components/Icon';
|
||||
import Button from 'Components/Link/Button';
|
||||
import { icons, kinds, sizes } from 'Helpers/Props';
|
||||
import { Failure } from 'typings/pending';
|
||||
import { QualityProfileItems as Items } from 'typings/QualityProfile';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import QualityProfileItemDragSource, {
|
||||
QualityProfileItemDragSourceActionProps,
|
||||
} from './QualityProfileItemDragSource';
|
||||
import { QualityProfileItems as Items } from './useQualityProfiles';
|
||||
import styles from './QualityProfileItems.css';
|
||||
|
||||
export type EditQualityProfileMode = 'default' | 'editGroups' | 'editSizes';
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { createQualityProfileSelectorForHook } from 'Store/Selectors/createQualityProfileSelector';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import { useQualityProfile } from './useQualityProfiles';
|
||||
|
||||
interface QualityProfileNameProps {
|
||||
qualityProfileId: number;
|
||||
}
|
||||
|
||||
function QualityProfileName({ qualityProfileId }: QualityProfileNameProps) {
|
||||
const qualityProfile = useSelector(
|
||||
createQualityProfileSelectorForHook(qualityProfileId)
|
||||
);
|
||||
const qualityProfile = useQualityProfile(qualityProfileId);
|
||||
|
||||
return <span>{qualityProfile?.name ?? translate('Unknown')}</span>;
|
||||
}
|
||||
|
||||
@@ -1,55 +1,40 @@
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { QualityProfilesAppState } from 'App/State/SettingsAppState';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import Card from 'Components/Card';
|
||||
import FieldSet from 'Components/FieldSet';
|
||||
import Icon from 'Components/Icon';
|
||||
import PageSectionContent from 'Components/Page/PageSectionContent';
|
||||
import { icons } from 'Helpers/Props';
|
||||
import {
|
||||
cloneQualityProfile,
|
||||
fetchQualityProfiles,
|
||||
} from 'Store/Actions/settingsActions';
|
||||
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
|
||||
import QualityProfileModel from 'typings/QualityProfile';
|
||||
import sortByProp from 'Utilities/Array/sortByProp';
|
||||
import translate from 'Utilities/String/translate';
|
||||
import EditQualityProfileModal from './EditQualityProfileModal';
|
||||
import QualityProfile from './QualityProfile';
|
||||
import { useQualityProfiles } from './useQualityProfiles';
|
||||
import styles from './QualityProfiles.css';
|
||||
|
||||
function QualityProfiles() {
|
||||
const dispatch = useDispatch();
|
||||
const { data, error, isFetching, isFetched } = useQualityProfiles();
|
||||
|
||||
const { error, isFetching, isPopulated, isDeleting, items } = useSelector(
|
||||
createSortedSectionSelector<QualityProfileModel, QualityProfilesAppState>(
|
||||
'settings.qualityProfiles',
|
||||
sortByProp('name')
|
||||
)
|
||||
) as QualityProfilesAppState;
|
||||
// Sort the data by name
|
||||
const sortedItems = data ? data.sort(sortByProp('name')) : [];
|
||||
|
||||
const [isQualityProfileModalOpen, setIsQualityProfileModalOpen] =
|
||||
useState(false);
|
||||
const [cloneProfileId, setCloneProfileId] = useState<number | null>(null);
|
||||
|
||||
const handleEditQualityProfilePress = useCallback(() => {
|
||||
const handleAddQualityProfilePress = useCallback(() => {
|
||||
setCloneProfileId(null);
|
||||
setIsQualityProfileModalOpen(true);
|
||||
}, []);
|
||||
|
||||
const handleEditQualityProfileClosePress = useCallback(() => {
|
||||
const handleAddQualityProfileClosePress = useCallback(() => {
|
||||
setCloneProfileId(null);
|
||||
setIsQualityProfileModalOpen(false);
|
||||
}, []);
|
||||
|
||||
const handleCloneQualityProfilePress = useCallback(
|
||||
(id: number) => {
|
||||
dispatch(cloneQualityProfile({ id }));
|
||||
setIsQualityProfileModalOpen(true);
|
||||
},
|
||||
[dispatch]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchQualityProfiles());
|
||||
}, [dispatch]);
|
||||
const handleCloneQualityProfilePress = useCallback((id: number) => {
|
||||
setCloneProfileId(id);
|
||||
setIsQualityProfileModalOpen(true);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<FieldSet legend={translate('QualityProfiles')}>
|
||||
@@ -57,15 +42,15 @@ function QualityProfiles() {
|
||||
errorMessage={translate('QualityProfilesLoadError')}
|
||||
error={error}
|
||||
isFetching={isFetching}
|
||||
isPopulated={isPopulated}
|
||||
isPopulated={isFetched}
|
||||
>
|
||||
<div className={styles.qualityProfiles}>
|
||||
{items.map((item) => {
|
||||
{sortedItems.map((item) => {
|
||||
return (
|
||||
<QualityProfile
|
||||
key={item.id}
|
||||
{...item}
|
||||
isDeleting={isDeleting}
|
||||
isDeleting={false}
|
||||
onCloneQualityProfilePress={handleCloneQualityProfilePress}
|
||||
/>
|
||||
);
|
||||
@@ -73,7 +58,7 @@ function QualityProfiles() {
|
||||
|
||||
<Card
|
||||
className={styles.addQualityProfile}
|
||||
onPress={handleEditQualityProfilePress}
|
||||
onPress={handleAddQualityProfilePress}
|
||||
>
|
||||
<div className={styles.center}>
|
||||
<Icon name={icons.ADD} size={45} />
|
||||
@@ -83,7 +68,8 @@ function QualityProfiles() {
|
||||
|
||||
<EditQualityProfileModal
|
||||
isOpen={isQualityProfileModalOpen}
|
||||
onModalClose={handleEditQualityProfileClosePress}
|
||||
cloneId={cloneProfileId ?? undefined}
|
||||
onModalClose={handleAddQualityProfileClosePress}
|
||||
/>
|
||||
</PageSectionContent>
|
||||
</FieldSet>
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
import ModelBase from 'App/ModelBase';
|
||||
import useApiQuery from 'Helpers/Hooks/useApiQuery';
|
||||
import Quality from 'Quality/Quality';
|
||||
import {
|
||||
useDeleteProvider,
|
||||
useManageProviderSettings,
|
||||
useProviderSettings,
|
||||
} from 'Settings/useProviderSettings';
|
||||
import { QualityProfileFormatItem } from 'typings/CustomFormat';
|
||||
import translate from 'Utilities/String/translate';
|
||||
|
||||
export interface QualityProfileQualityItem {
|
||||
quality: Quality;
|
||||
allowed: boolean;
|
||||
minSize: number | null;
|
||||
maxSize: number | null;
|
||||
preferredSize: number | null;
|
||||
}
|
||||
|
||||
export interface QualityProfileGroup {
|
||||
id: number;
|
||||
items: QualityProfileQualityItem[];
|
||||
allowed: boolean;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export type QualityProfileItems = (
|
||||
| QualityProfileQualityItem
|
||||
| QualityProfileGroup
|
||||
)[];
|
||||
|
||||
export interface QualityProfileModel extends ModelBase {
|
||||
name: string;
|
||||
upgradeAllowed: boolean;
|
||||
cutoff: number;
|
||||
items: QualityProfileItems;
|
||||
minFormatScore: number;
|
||||
cutoffFormatScore: number;
|
||||
minUpgradeFormatScore: number;
|
||||
formatItems: QualityProfileFormatItem[];
|
||||
}
|
||||
|
||||
const PATH = '/qualityprofile';
|
||||
|
||||
export const useQualityProfile = (id: number | undefined) => {
|
||||
const { data } = useQualityProfiles();
|
||||
|
||||
if (id === undefined) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return data.find((profile) => profile.id === id);
|
||||
};
|
||||
|
||||
export const useQualityProfilesData = () => {
|
||||
const { data } = useQualityProfiles();
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
export const useQualityProfiles = () => {
|
||||
return useProviderSettings<QualityProfileModel>({
|
||||
path: PATH,
|
||||
queryOptions: {
|
||||
gcTime: Infinity,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
export const useManageQualityProfile = (
|
||||
id: number | undefined,
|
||||
cloneId: number | undefined
|
||||
) => {
|
||||
const { schema, isSchemaFetching, isSchemaFetched, schemaError } =
|
||||
useQualityProfileSchema(cloneId == null);
|
||||
|
||||
const profile = useQualityProfile(cloneId);
|
||||
|
||||
if (cloneId && !profile) {
|
||||
throw new Error(`Quality Profile with ID ${cloneId} not found`);
|
||||
}
|
||||
|
||||
const manage = useManageProviderSettings<QualityProfileModel>(
|
||||
id,
|
||||
cloneId && profile
|
||||
? {
|
||||
...profile,
|
||||
id: 0,
|
||||
name: translate('DefaultNameCopiedProfile', {
|
||||
name: profile.name,
|
||||
}),
|
||||
}
|
||||
: schema,
|
||||
PATH
|
||||
);
|
||||
|
||||
return {
|
||||
...manage,
|
||||
isSchemaFetching: cloneId ? false : isSchemaFetching,
|
||||
isSchemaFetched: cloneId ? true : isSchemaFetched,
|
||||
schemaError: cloneId ? undefined : schemaError,
|
||||
};
|
||||
};
|
||||
|
||||
export const useDeleteQualityProfile = (id: number) => {
|
||||
const result = useDeleteProvider<QualityProfileModel>(id, PATH);
|
||||
|
||||
return {
|
||||
...result,
|
||||
deleteQualityProfile: result.deleteProvider,
|
||||
};
|
||||
};
|
||||
|
||||
export const useQualityProfileSchema = (enabled: boolean) => {
|
||||
const { isFetching, isFetched, error, data } =
|
||||
useApiQuery<QualityProfileModel>({
|
||||
path: `${PATH}/schema`,
|
||||
queryOptions: {
|
||||
enabled,
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
isSchemaFetching: isFetching,
|
||||
isSchemaFetched: isFetched,
|
||||
schemaError: error,
|
||||
schema: data ?? ({} as QualityProfileModel),
|
||||
};
|
||||
};
|
||||
@@ -37,7 +37,7 @@ export const useReleaseProfilesWithIds = (ids: number[]) => {
|
||||
};
|
||||
|
||||
export const useReleaseProfiles = () => {
|
||||
return useProviderSettings<ReleaseProfileModel>(PATH);
|
||||
return useProviderSettings<ReleaseProfileModel>({ path: PATH });
|
||||
};
|
||||
|
||||
export const useManageReleaseProfile = (id: number) => {
|
||||
|
||||
Reference in New Issue
Block a user