New: Import List Tags (#505)

* New: Import List Tags

* New: Show ImportLists where Tag is Used in Tag manager

* Fixed: SignalR Errors due to handleTag missing

* Fixed: Clarify Lidarr Tags, not to be confused with LastFmTags
This commit is contained in:
Qstick 2018-10-08 20:56:05 -04:00 committed by GitHub
commit 27736649c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 101 additions and 6 deletions

View file

@ -11,6 +11,7 @@ import { setAppValue, setVersion } from 'Store/Actions/appActions';
import { update, updateItem, removeItem } from 'Store/Actions/baseActions';
import { fetchHealth } from 'Store/Actions/systemActions';
import { fetchQueue, fetchQueueDetails } from 'Store/Actions/queueActions';
import { fetchTags, fetchTagDetails } from 'Store/Actions/tagActions';
function getState(status) {
switch (status) {
@ -68,7 +69,9 @@ const mapDispatchToProps = {
dispatchRemoveItem: removeItem,
dispatchFetchHealth: fetchHealth,
dispatchFetchQueue: fetchQueue,
dispatchFetchQueueDetails: fetchQueueDetails
dispatchFetchQueueDetails: fetchQueueDetails,
dispatchFetchTags: fetchTags,
dispatchFetchTagDetails: fetchTagDetails
};
class SignalRConnector extends Component {
@ -263,6 +266,14 @@ class SignalRConnector extends Component {
// No-op for now, we may want this later
}
handleTag = (body) => {
if (body.action === 'sync') {
this.props.dispatchFetchTags();
this.props.dispatchFetchTagDetails();
return;
}
}
//
// Listeners
@ -362,7 +373,9 @@ SignalRConnector.propTypes = {
dispatchRemoveItem: PropTypes.func.isRequired,
dispatchFetchHealth: PropTypes.func.isRequired,
dispatchFetchQueue: PropTypes.func.isRequired,
dispatchFetchQueueDetails: PropTypes.func.isRequired
dispatchFetchQueueDetails: PropTypes.func.isRequired,
dispatchFetchTags: PropTypes.func.isRequired,
dispatchFetchTagDetails: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(SignalRConnector);

View file

@ -44,6 +44,7 @@ function EditImportListModalContent(props) {
qualityProfileId,
languageProfileId,
metadataProfileId,
tags,
fields
} = item;
@ -152,6 +153,18 @@ function EditImportListModalContent(props) {
/>
</FormGroup>
<FormGroup>
<FormLabel>Lidarr Tags</FormLabel>
<FormInputGroup
type={inputTypes.TAG}
name="tags"
helpText="Add artists from this list with these tags"
{...tags}
onChange={onInputChange}
/>
</FormGroup>
{
!!fields && !!fields.length &&
<div>

View file

@ -17,6 +17,7 @@ function TagDetailsModalContent(props) {
isTagUsed,
artist,
delayProfiles,
importLists,
notifications,
restrictions,
onModalClose,
@ -80,6 +81,21 @@ function TagDetailsModalContent(props) {
</FieldSet>
}
{
!!importLists.length &&
<FieldSet legend="Import Lists">
{
importLists.map((item) => {
return (
<div key={item.id}>
{item.name}
</div>
);
})
}
</FieldSet>
}
{
!!restrictions.length &&
<FieldSet legend="Restrictions">
@ -154,6 +170,7 @@ TagDetailsModalContent.propTypes = {
isTagUsed: PropTypes.bool.isRequired,
artist: PropTypes.arrayOf(PropTypes.object).isRequired,
delayProfiles: PropTypes.arrayOf(PropTypes.object).isRequired,
importLists: PropTypes.arrayOf(PropTypes.object).isRequired,
notifications: PropTypes.arrayOf(PropTypes.object).isRequired,
restrictions: PropTypes.arrayOf(PropTypes.object).isRequired,
onModalClose: PropTypes.func.isRequired,

View file

@ -25,6 +25,14 @@ function createMatchingDelayProfilesSelector() {
);
}
function createMatchingImportListsSelector() {
return createSelector(
(state, { importListIds }) => importListIds,
(state) => state.settings.importLists.items,
findMatchingItems
);
}
function createMatchingNotificationsSelector() {
return createSelector(
(state, { notificationIds }) => notificationIds,
@ -45,12 +53,14 @@ function createMapStateToProps() {
return createSelector(
createMatchingArtistSelector(),
createMatchingDelayProfilesSelector(),
createMatchingImportListsSelector(),
createMatchingNotificationsSelector(),
createMatchingRestrictionsSelector(),
(artist, delayProfiles, notifications, restrictions) => {
(artist, delayProfiles, importLists, notifications, restrictions) => {
return {
artist,
delayProfiles,
importLists,
notifications,
restrictions
};

View file

@ -53,6 +53,7 @@ class Tag extends Component {
const {
label,
delayProfileIds,
importListIds,
notificationIds,
restrictionIds,
artistIds
@ -65,6 +66,7 @@ class Tag extends Component {
const isTagUsed = !!(
delayProfileIds.length ||
importListIds.length ||
notificationIds.length ||
restrictionIds.length ||
artistIds.length
@ -97,6 +99,13 @@ class Tag extends Component {
</div>
}
{
!!importListIds.length &&
<div>
{importListIds.length} import list{importListIds.length > 1 && 's'}
</div>
}
{
!!notificationIds.length &&
<div>
@ -125,6 +134,7 @@ class Tag extends Component {
isTagUsed={isTagUsed}
artistIds={artistIds}
delayProfileIds={delayProfileIds}
importListIds={importListIds}
notificationIds={notificationIds}
restrictionIds={restrictionIds}
isOpen={isDetailsModalOpen}
@ -150,6 +160,7 @@ Tag.propTypes = {
id: PropTypes.number.isRequired,
label: PropTypes.string.isRequired,
delayProfileIds: PropTypes.arrayOf(PropTypes.number).isRequired,
importListIds: PropTypes.arrayOf(PropTypes.number).isRequired,
notificationIds: PropTypes.arrayOf(PropTypes.number).isRequired,
restrictionIds: PropTypes.arrayOf(PropTypes.number).isRequired,
artistIds: PropTypes.arrayOf(PropTypes.number).isRequired,
@ -158,6 +169,7 @@ Tag.propTypes = {
Tag.defaultProps = {
delayProfileIds: [],
importListIds: [],
notificationIds: [],
restrictionIds: [],
artistIds: []

View file

@ -3,7 +3,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchTagDetails } from 'Store/Actions/tagActions';
import { fetchDelayProfiles, fetchNotifications, fetchRestrictions } from 'Store/Actions/settingsActions';
import { fetchDelayProfiles, fetchNotifications, fetchRestrictions, fetchImportLists } from 'Store/Actions/settingsActions';
import Tags from './Tags';
function createMapStateToProps() {
@ -27,6 +27,7 @@ function createMapStateToProps() {
const mapDispatchToProps = {
dispatchFetchTagDetails: fetchTagDetails,
dispatchFetchDelayProfiles: fetchDelayProfiles,
dispatchFetchImportLists: fetchImportLists,
dispatchFetchNotifications: fetchNotifications,
dispatchFetchRestrictions: fetchRestrictions
};
@ -40,12 +41,14 @@ class MetadatasConnector extends Component {
const {
dispatchFetchTagDetails,
dispatchFetchDelayProfiles,
dispatchFetchImportLists,
dispatchFetchNotifications,
dispatchFetchRestrictions
} = this.props;
dispatchFetchTagDetails();
dispatchFetchDelayProfiles();
dispatchFetchImportLists();
dispatchFetchNotifications();
dispatchFetchRestrictions();
}
@ -65,6 +68,7 @@ class MetadatasConnector extends Component {
MetadatasConnector.propTypes = {
dispatchFetchTagDetails: PropTypes.func.isRequired,
dispatchFetchDelayProfiles: PropTypes.func.isRequired,
dispatchFetchImportLists: PropTypes.func.isRequired,
dispatchFetchNotifications: PropTypes.func.isRequired,
dispatchFetchRestrictions: PropTypes.func.isRequired
};