diff --git a/frontend/src/Components/Form/FormInputGroup.js b/frontend/src/Components/Form/FormInputGroup.js
index 06a4de336..a9220b1ee 100644
--- a/frontend/src/Components/Form/FormInputGroup.js
+++ b/frontend/src/Components/Form/FormInputGroup.js
@@ -17,6 +17,7 @@ import RootFolderSelectInputConnector from './RootFolderSelectInputConnector';
import MovieMonitoredSelectInput from './MovieMonitoredSelectInput';
import EnhancedSelectInput from './EnhancedSelectInput';
import TagInputConnector from './TagInputConnector';
+import TagSelectInputConnector from './TagSelectInputConnector';
import TextTagInputConnector from './TextTagInputConnector';
import TextInput from './TextInput';
import FormInputHelpText from './FormInputHelpText';
@@ -72,6 +73,9 @@ function getComponent(type) {
case inputTypes.TEXT_TAG:
return TextTagInputConnector;
+ case inputTypes.TAG_SELECT:
+ return TagSelectInputConnector;
+
default:
return TextInput;
}
diff --git a/frontend/src/Components/Form/ProviderFieldFormGroup.js b/frontend/src/Components/Form/ProviderFieldFormGroup.js
index d52afb4db..9cdbe69f9 100644
--- a/frontend/src/Components/Form/ProviderFieldFormGroup.js
+++ b/frontend/src/Components/Form/ProviderFieldFormGroup.js
@@ -26,6 +26,8 @@ function getType(type) {
return inputTypes.SELECT;
case 'tag':
return inputTypes.TEXT_TAG;
+ case 'tagSelect':
+ return inputTypes.TAG_SELECT;
case 'textbox':
return inputTypes.TEXT;
case 'oAuth':
diff --git a/frontend/src/Components/Form/TagSelectInputConnector.js b/frontend/src/Components/Form/TagSelectInputConnector.js
new file mode 100644
index 000000000..71d7c4f06
--- /dev/null
+++ b/frontend/src/Components/Form/TagSelectInputConnector.js
@@ -0,0 +1,102 @@
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+import React, { Component } from 'react';
+import { connect } from 'react-redux';
+import { createSelector } from 'reselect';
+import TagInput from './TagInput';
+
+function createMapStateToProps() {
+ return createSelector(
+ (state, { value }) => value,
+ (state, { values }) => values,
+ (tags, tagList) => {
+ const sortedTags = _.sortBy(tagList, 'value');
+
+ return {
+ tags: tags.reduce((acc, tag) => {
+ const matchingTag = _.find(tagList, { key: tag });
+
+ if (matchingTag) {
+ acc.push({
+ id: tag,
+ name: matchingTag.value
+ });
+ }
+
+ return acc;
+ }, []),
+
+ tagList: sortedTags.map(({ key: id, value: name }) => {
+ return {
+ id,
+ name
+ };
+ }),
+
+ allTags: sortedTags
+ };
+ }
+ );
+}
+
+class TagSelectInputConnector extends Component {
+
+ //
+ // Listeners
+
+ onTagAdd = (tag) => {
+ const {
+ name,
+ value,
+ allTags
+ } = this.props;
+
+ const existingTag =_.some(allTags, { key: tag.id });
+
+ const newValue = value.slice();
+
+ if (existingTag) {
+ newValue.push(tag.id);
+ }
+
+ this.props.onChange({ name, value: newValue });
+ }
+
+ onTagDelete = ({ index }) => {
+ const {
+ name,
+ value
+ } = this.props;
+
+ const newValue = value.slice();
+ newValue.splice(index, 1);
+
+ this.props.onChange({
+ name,
+ value: newValue
+ });
+ }
+
+ //
+ // Render
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+TagSelectInputConnector.propTypes = {
+ name: PropTypes.string.isRequired,
+ value: PropTypes.arrayOf(PropTypes.number).isRequired,
+ values: PropTypes.arrayOf(PropTypes.object).isRequired,
+ allTags: PropTypes.arrayOf(PropTypes.object).isRequired,
+ onChange: PropTypes.func.isRequired
+};
+
+export default connect(createMapStateToProps)(TagSelectInputConnector);
diff --git a/frontend/src/Helpers/Props/inputTypes.js b/frontend/src/Helpers/Props/inputTypes.js
index 5f42c4c3c..abc594b8d 100644
--- a/frontend/src/Helpers/Props/inputTypes.js
+++ b/frontend/src/Helpers/Props/inputTypes.js
@@ -14,6 +14,7 @@ export const SELECT = 'select';
export const TAG = 'tag';
export const TEXT = 'text';
export const TEXT_TAG = 'textTag';
+export const TAG_SELECT = 'tagSelect';
export const all = [
AUTO_COMPLETE,
@@ -31,5 +32,6 @@ export const all = [
SELECT,
TAG,
TEXT,
- TEXT_TAG
+ TEXT_TAG,
+ TAG_SELECT
];
diff --git a/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs b/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs
index 70a9fbe46..4785a382c 100644
--- a/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs
+++ b/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs
@@ -36,7 +36,8 @@ namespace NzbDrone.Core.Annotations
Url,
Captcha,
OAuth,
- Device
+ Device,
+ TagSelect
}
public enum HiddenType
diff --git a/src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs b/src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs
index ba5b23b64..44fab01db 100644
--- a/src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs
+++ b/src/NzbDrone.Core/Indexers/AwesomeHD/AwesomeHDSettings.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.AwesomeHD
@@ -40,7 +41,7 @@ namespace NzbDrone.Core.Indexers.AwesomeHD
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
- // [FieldDefinition(4, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(4, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
[FieldDefinition(5)]
diff --git a/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs b/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs
index 0d5d8af3d..cb2179af0 100644
--- a/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs
+++ b/src/NzbDrone.Core/Indexers/HDBits/HDBitsSettings.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.HDBits
@@ -56,7 +57,7 @@ namespace NzbDrone.Core.Indexers.HDBits
[FieldDefinition(7, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
- // [FieldDefinition(8, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(8, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
[FieldDefinition(9)]
diff --git a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs
index 27e942d0c..8b5d84ca8 100644
--- a/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs
+++ b/src/NzbDrone.Core/Indexers/IPTorrents/IPTorrentsSettings.cs
@@ -3,6 +3,7 @@ using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.IPTorrents
@@ -44,7 +45,7 @@ namespace NzbDrone.Core.Indexers.IPTorrents
[FieldDefinition(2, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
- // [FieldDefinition(3, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(3, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
[FieldDefinition(4)]
diff --git a/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs b/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs
index a7810a34d..8fb59a8d3 100644
--- a/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Nyaa/NyaaSettings.cs
@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Text.RegularExpressions;
using FluentValidation;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Nyaa
@@ -42,7 +43,7 @@ namespace NzbDrone.Core.Indexers.Nyaa
[FieldDefinition(3, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
- // [FieldDefinition(4, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(4, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
[FieldDefinition(5)]
diff --git a/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornSettings.cs b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornSettings.cs
index 559b3f40e..441408269 100644
--- a/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornSettings.cs
+++ b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcornSettings.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.PassThePopcorn
@@ -47,7 +48,7 @@ namespace NzbDrone.Core.Indexers.PassThePopcorn
[FieldDefinition(5)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
- // [FieldDefinition(6, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(6, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
diff --git a/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs b/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs
index 237b6b065..7bd0cdd96 100644
--- a/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Rarbg/RarbgSettings.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Rarbg
@@ -46,7 +47,7 @@ namespace NzbDrone.Core.Indexers.Rarbg
[FieldDefinition(4, Type = FieldType.Number, Label = "Minimum Seeders", HelpText = "Minimum number of seeders required.", Advanced = true)]
public int MinimumSeeders { get; set; }
- // [FieldDefinition(5, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(5, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
[FieldDefinition(6, Type = FieldType.Textbox, Label = "Categories", HelpText = "Comma Separated list, you can retrieve the ID by checking the URL behind the category on the website (i.e. Movie/x264/1080 = 44)", HelpLink = "https://rarbgmirror.org/torrents.php?category=movies", Advanced = true)]
diff --git a/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.cs b/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.cs
index dd840ac1a..eb7233e45 100644
--- a/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.cs
+++ b/src/NzbDrone.Core/Indexers/TorrentPotato/TorrentPotatoSettings.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.TorrentPotato
@@ -45,7 +46,7 @@ namespace NzbDrone.Core.Indexers.TorrentPotato
[FieldDefinition(5)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
- // [FieldDefinition(6, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
+ [FieldDefinition(6, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
diff --git a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs
index e1e6fbd12..4825d569f 100644
--- a/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs
+++ b/src/NzbDrone.Core/Indexers/TorrentRss/TorrentRssIndexerSettings.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using FluentValidation;
using NzbDrone.Core.Annotations;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.TorrentRss
@@ -46,7 +47,7 @@ namespace NzbDrone.Core.Indexers.TorrentRss
[FieldDefinition(5)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
- // [FieldDefinition(6, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(6, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
public NzbDroneValidationResult Validate()
diff --git a/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs
index 8f31e2e9c..cbef1526a 100644
--- a/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs
+++ b/src/NzbDrone.Core/Indexers/Torznab/TorznabSettings.cs
@@ -5,6 +5,7 @@ using FluentValidation;
using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.Indexers.Newznab;
+using NzbDrone.Core.Parser.Model;
using NzbDrone.Core.Validation;
namespace NzbDrone.Core.Indexers.Torznab
@@ -64,7 +65,7 @@ namespace NzbDrone.Core.Indexers.Torznab
[FieldDefinition(9)]
public SeedCriteriaSettings SeedCriteria { get; set; } = new SeedCriteriaSettings();
- // [FieldDefinition(10, Type = FieldType.Tag, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
+ [FieldDefinition(10, Type = FieldType.TagSelect, SelectOptions = typeof(IndexerFlags), Label = "Required Flags", HelpText = "What indexer flags are required?", HelpLink = "https://github.com/Radarr/Radarr/wiki/Indexer-Flags#1-required-flags", Advanced = true)]
public IEnumerable RequiredFlags { get; set; }
public override NzbDroneValidationResult Validate()
diff --git a/src/Radarr.Http/ClientSchema/SchemaBuilder.cs b/src/Radarr.Http/ClientSchema/SchemaBuilder.cs
index 7c2fb8648..bca139c83 100644
--- a/src/Radarr.Http/ClientSchema/SchemaBuilder.cs
+++ b/src/Radarr.Http/ClientSchema/SchemaBuilder.cs
@@ -103,7 +103,7 @@ namespace Radarr.Http.ClientSchema
Section = fieldAttribute.Section
};
- if (fieldAttribute.Type == FieldType.Select)
+ if (fieldAttribute.Type == FieldType.Select || fieldAttribute.Type == FieldType.TagSelect)
{
field.SelectOptions = GetSelectOptions(fieldAttribute.SelectOptions);
}