diff --git a/server/entity/OverrideRule.ts b/server/entity/OverrideRule.ts index 394cc429..91d28768 100644 --- a/server/entity/OverrideRule.ts +++ b/server/entity/OverrideRule.ts @@ -26,6 +26,9 @@ class OverrideRule { @Column({ nullable: true }) public language?: string; + @Column({ nullable: true }) + public keywords?: string; + @ManyToMany(() => User) @JoinTable() public users: User[]; diff --git a/server/routes/overrideRule.ts b/server/routes/overrideRule.ts index 6662189d..661e3c1c 100644 --- a/server/routes/overrideRule.ts +++ b/server/routes/overrideRule.ts @@ -29,6 +29,7 @@ overrideRuleRoutes.post< { genre?: string; language?: string; + keywords?: string; profileId?: number; rootFolder?: string; tags?: number[]; @@ -42,6 +43,7 @@ overrideRuleRoutes.post< const rule = new OverrideRule({ genre: req.body.genre, language: req.body.language, + keywords: req.body.keywords, profileId: req.body.profileId, rootFolder: req.body.rootFolder, tags: req.body.tags, @@ -49,9 +51,9 @@ overrideRuleRoutes.post< sonarrServiceId: req.body.sonarrServiceId, }); - const newIssue = await overrideRuleRepository.save(rule); + const newRule = await overrideRuleRepository.save(rule); - return res.status(200).json(newIssue); + return res.status(200).json(newRule); } catch (e) { next({ status: 404, message: e.message }); } @@ -63,6 +65,7 @@ overrideRuleRoutes.put< { genre?: string; language?: string; + keywords?: string; profileId?: number; rootFolder?: string; tags?: number[]; @@ -85,18 +88,45 @@ overrideRuleRoutes.put< rule.genre = req.body.genre; rule.language = req.body.language; + rule.keywords = req.body.keywords; rule.profileId = req.body.profileId; rule.rootFolder = req.body.rootFolder; rule.tags = req.body.tags; rule.radarrServiceId = req.body.radarrServiceId; rule.sonarrServiceId = req.body.sonarrServiceId; - const newIssue = await overrideRuleRepository.save(rule); + const newRule = await overrideRuleRepository.save(rule); - return res.status(200).json(newIssue); + return res.status(200).json(newRule); } catch (e) { next({ status: 404, message: e.message }); } }); +overrideRuleRoutes.delete<{ ruleId: string }, OverrideRule>( + '/:ruleId', + isAuthenticated(Permission.ADMIN), + async (req, res, next) => { + const overrideRuleRepository = getRepository(OverrideRule); + + try { + const rule = await overrideRuleRepository.findOne({ + where: { + id: Number(req.params.ruleId), + }, + }); + + if (!rule) { + return next({ status: 404, message: 'Override Rule not found.' }); + } + + await overrideRuleRepository.remove(rule); + + return res.status(200).json(rule); + } catch (e) { + next({ status: 404, message: e.message }); + } + } +); + export default overrideRuleRoutes; diff --git a/src/components/Settings/OverrideRuleModal.tsx b/src/components/Settings/OverrideRule/OverrideRuleModal.tsx similarity index 84% rename from src/components/Settings/OverrideRuleModal.tsx rename to src/components/Settings/OverrideRule/OverrideRuleModal.tsx index 3220e87c..3aa1e668 100644 --- a/src/components/Settings/OverrideRuleModal.tsx +++ b/src/components/Settings/OverrideRule/OverrideRuleModal.tsx @@ -1,6 +1,6 @@ import Modal from '@app/components/Common/Modal'; import LanguageSelector from '@app/components/LanguageSelector'; -import { GenreSelector } from '@app/components/Selector'; +import { GenreSelector, KeywordSelector } from '@app/components/Selector'; import type { DVRTestResponse } from '@app/components/Settings/SettingsServices'; import useSettings from '@app/hooks/useSettings'; import globalMessages from '@app/i18n/globalMessages'; @@ -16,6 +16,15 @@ const messages = defineMessages('components.Settings.RadarrModal', { createrule: 'New Override Rule', editrule: 'Edit Override Rule', create: 'Create rule', + conditions: 'Conditions', + conditionsDescription: + 'Specifies conditions before applying parameter changes. Each field must be validated for the rules to be applied (AND operation). A field is considered verified if any of its properties match (OR operation).', + settings: 'Settings', + settingsDescription: + 'Specifies which settings will be changed when the above conditions are met.', + genres: 'Genres', + languages: 'Languages', + keywords: 'Keywords', rootfolder: 'Root Folder', selectRootFolder: 'Select root folder', qualityprofile: 'Quality Profile', @@ -67,7 +76,7 @@ const OverrideRuleModal = ({ initialValues={{ genre: rule?.genre, language: rule?.language, - // keywords: [], + keywords: rule?.keywords, profileId: rule?.profileId, rootFolder: rule?.rootFolder, tags: rule?.tags, @@ -77,6 +86,7 @@ const OverrideRuleModal = ({ const submission = { genre: values.genre || null, language: values.language || null, + keywords: values.keywords || null, profileId: Number(values.profileId) || null, rootFolder: values.rootFolder || null, tags: values.tags || null, @@ -151,11 +161,14 @@ const OverrideRuleModal = ({ >

- Condition + {intl.formatMessage(messages.conditions)}

+

+ {intl.formatMessage(messages.conditionsDescription)} +

@@ -180,7 +193,7 @@ const OverrideRuleModal = ({
@@ -193,6 +206,30 @@ const OverrideRuleModal = ({ }} />
+ {errors.language && + touched.language && + typeof errors.language === 'string' && ( +
{errors.language}
+ )} +
+
+
+ +
+
+ { + setFieldValue( + 'keywords', + value?.map((v) => v.value).join(',') + ); + }} + /> +
{errors.genre && touched.genre && typeof errors.genre === 'string' && ( @@ -201,8 +238,11 @@ const OverrideRuleModal = ({

- Settings + {intl.formatMessage(messages.settings)}

+

+ {intl.formatMessage(messages.settingsDescription)} +