Added Enabled & IndexerId to Edit Release Profile UI

This commit is contained in:
Taloth Saldono 2019-06-16 18:28:09 +02:00
parent 5ac7672756
commit c1f3da00a4
7 changed files with 110 additions and 71 deletions

View File

@ -4,50 +4,59 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import sortByName from 'Utilities/Array/sortByName'; import sortByName from 'Utilities/Array/sortByName';
import SelectInput from './SelectInput'; import { fetchIndexers } from 'Store/Actions/settingsActions';
import EnhancedSelectInput from './EnhancedSelectInput';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state) => state.settings.indexers, (state) => state.settings.indexers,
(state, { includeNoChange }) => includeNoChange, (state, { includeAny }) => includeAny,
(state, { includeMixed }) => includeMixed, (indexers, includeAny) => {
(indexers, includeNoChange, includeMixed) => { const {
const values = _.map(indexers.items.sort(sortByName), (indexer) => { isFetching,
isPopulated,
error,
items
} = indexers;
const values = _.map(items.sort(sortByName), (indexer) => {
return { return {
key: indexer.id, key: indexer.id,
value: indexer.name value: indexer.name
}; };
}); });
if (includeNoChange) { if (includeAny) {
values.unshift({ values.unshift({
key: 'noChange', key: 0,
value: 'No Change', value: '(Any)'
disabled: true
});
}
if (includeMixed) {
values.unshift({
key: 'mixed',
value: '(Mixed)',
disabled: true
}); });
} }
return { return {
isFetching,
isPopulated,
error,
values values
}; };
} }
); );
} }
const mapDispatchToProps = {
dispatchFetchIndexers: fetchIndexers
};
class IndexerSelectInputConnector extends Component { class IndexerSelectInputConnector extends Component {
// //
// Lifecycle // Lifecycle
componentDidMount() { componentDidMount() {
if (!this.props.isPopulated) {
this.props.dispatchFetchIndexers();
}
const { const {
name, name,
value, value,
@ -55,11 +64,7 @@ class IndexerSelectInputConnector extends Component {
} = this.props; } = this.props;
if (!value || !_.some(values, (option) => parseInt(option.key) === value)) { if (!value || !_.some(values, (option) => parseInt(option.key) === value)) {
const firstValue = _.find(values, (option) => !isNaN(parseInt(option.key))); this.onChange({ name, value: 0 });
if (firstValue) {
this.onChange({ name, value: firstValue.key });
}
} }
} }
@ -75,7 +80,7 @@ class IndexerSelectInputConnector extends Component {
render() { render() {
return ( return (
<SelectInput <EnhancedSelectInput
{...this.props} {...this.props}
onChange={this.onChange} onChange={this.onChange}
/> />
@ -84,15 +89,18 @@ class IndexerSelectInputConnector extends Component {
} }
IndexerSelectInputConnector.propTypes = { IndexerSelectInputConnector.propTypes = {
isFetching: PropTypes.bool.isRequired,
isPopulated: PropTypes.bool.isRequired,
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), value: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
values: PropTypes.arrayOf(PropTypes.object).isRequired, values: PropTypes.arrayOf(PropTypes.object).isRequired,
includeNoChange: PropTypes.bool.isRequired, includeAny: PropTypes.bool.isRequired,
onChange: PropTypes.func.isRequired onChange: PropTypes.func.isRequired,
dispatchFetchIndexers: PropTypes.func.isRequired
}; };
IndexerSelectInputConnector.defaultProps = { IndexerSelectInputConnector.defaultProps = {
includeNoChange: false includeAny: false
}; };
export default connect(createMapStateToProps)(IndexerSelectInputConnector); export default connect(createMapStateToProps, mapDispatchToProps)(IndexerSelectInputConnector);

View File

@ -34,9 +34,9 @@ function EditReleaseProfileModalContent(props) {
required, required,
ignored, ignored,
preferred, preferred,
indexerId,
includePreferredWhenRenaming, includePreferredWhenRenaming,
tags tags,
indexerId
} = item; } = item;
return ( return (
@ -127,6 +127,7 @@ function EditReleaseProfileModalContent(props) {
name="indexerId" name="indexerId"
helpText="Specify what indexer the profile applies to" helpText="Specify what indexer the profile applies to"
{...indexerId} {...indexerId}
includeAny={true}
onChange={onInputChange} onChange={onInputChange}
/> />
</FormGroup> </FormGroup>

View File

@ -8,13 +8,13 @@ import { setReleaseProfileValue, saveReleaseProfile } from 'Store/Actions/settin
import EditReleaseProfileModalContent from './EditReleaseProfileModalContent'; import EditReleaseProfileModalContent from './EditReleaseProfileModalContent';
const newReleaseProfile = { const newReleaseProfile = {
enabled: false, enabled: true,
required: '', required: '',
ignored: '', ignored: '',
preferred: [], preferred: [],
includePreferredWhenRenaming: false, includePreferredWhenRenaming: false,
indexer: 0, tags: [],
tags: [] indexerId: 0
}; };
function createMapStateToProps() { function createMapStateToProps() {

View File

@ -1,3 +1,4 @@
import _ from 'lodash';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import split from 'Utilities/String/split'; import split from 'Utilities/String/split';
@ -68,10 +69,13 @@ class ReleaseProfile extends Component {
render() { render() {
const { const {
id, id,
enabled,
required, required,
ignored, ignored,
tags, tags,
tagList indexerId,
tagList,
indexerList
} = this.props; } = this.props;
const { const {
@ -80,6 +84,8 @@ class ReleaseProfile extends Component {
isDeleteReleaseProfileModalOpen isDeleteReleaseProfileModalOpen
} = this.state; } = this.state;
const indexer = indexerId !== 0 && _.find(indexerList, { id: indexerId });
return ( return (
<Card <Card
className={styles.releaseProfile} className={styles.releaseProfile}
@ -105,6 +111,23 @@ class ReleaseProfile extends Component {
} }
</div> </div>
<div>
{
sortedPreferred.map((item) => {
const isPreferred = item.value >= 0;
return (
<Label
key={item.key}
kind={isPreferred ? kinds.DEFAULT : kinds.WARNING}
>
{item.key} {isPreferred && '+'}{item.value}
</Label>
);
})
}
</div>
<div> <div>
{ {
split(ignored).map((item) => { split(ignored).map((item) => {
@ -124,28 +147,33 @@ class ReleaseProfile extends Component {
} }
</div> </div>
<div>
{
sortedPreferred.map((item) => {
const isPreferred = item.value >= 0;
return (
<Label
key={item.key}
kind={isPreferred ? kinds.DEFAULT : kinds.WARNING}
>
{item.key} {isPreferred && '+'}{item.value}
</Label>
);
})
}
</div>
<TagList <TagList
tags={tags} tags={tags}
tagList={tagList} tagList={tagList}
/> />
<div>
{
!enabled &&
<Label
kind={kinds.DISABLED}
outline={true}
>
Disabled
</Label>
}
{
indexer &&
<Label
kind={kinds.INFO}
outline={true}
>
{indexer.name}
</Label>
}
</div>
<EditReleaseProfileModalConnector <EditReleaseProfileModalConnector
id={id} id={id}
isOpen={isEditReleaseProfileModalOpen} isOpen={isEditReleaseProfileModalOpen}
@ -169,18 +197,23 @@ class ReleaseProfile extends Component {
ReleaseProfile.propTypes = { ReleaseProfile.propTypes = {
id: PropTypes.number.isRequired, id: PropTypes.number.isRequired,
enabled: PropTypes.bool.isRequired,
required: PropTypes.string.isRequired, required: PropTypes.string.isRequired,
ignored: PropTypes.string.isRequired, ignored: PropTypes.string.isRequired,
preferred: PropTypes.arrayOf(PropTypes.object).isRequired, preferred: PropTypes.arrayOf(PropTypes.object).isRequired,
tags: PropTypes.arrayOf(PropTypes.number).isRequired, tags: PropTypes.arrayOf(PropTypes.number).isRequired,
indexerId: PropTypes.number.isRequired,
tagList: PropTypes.arrayOf(PropTypes.object).isRequired, tagList: PropTypes.arrayOf(PropTypes.object).isRequired,
indexerList: PropTypes.arrayOf(PropTypes.object).isRequired,
onConfirmDeleteReleaseProfile: PropTypes.func.isRequired onConfirmDeleteReleaseProfile: PropTypes.func.isRequired
}; };
ReleaseProfile.defaultProps = { ReleaseProfile.defaultProps = {
enabled: true,
required: '', required: '',
ignored: '', ignored: '',
preferred: [] preferred: [],
indexerId: 0
}; };
export default ReleaseProfile; export default ReleaseProfile;

View File

@ -40,6 +40,7 @@ class ReleaseProfiles extends Component {
const { const {
items, items,
tagList, tagList,
indexerList,
onConfirmDeleteReleaseProfile, onConfirmDeleteReleaseProfile,
...otherProps ...otherProps
} = this.props; } = this.props;
@ -69,6 +70,7 @@ class ReleaseProfiles extends Component {
<ReleaseProfile <ReleaseProfile
key={item.id} key={item.id}
tagList={tagList} tagList={tagList}
indexerList={indexerList}
{...item} {...item}
onConfirmDeleteReleaseProfile={onConfirmDeleteReleaseProfile} onConfirmDeleteReleaseProfile={onConfirmDeleteReleaseProfile}
/> />
@ -92,6 +94,7 @@ ReleaseProfiles.propTypes = {
error: PropTypes.object, error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired,
tagList: PropTypes.arrayOf(PropTypes.object).isRequired, tagList: PropTypes.arrayOf(PropTypes.object).isRequired,
indexerList: PropTypes.arrayOf(PropTypes.object).isRequired,
onConfirmDeleteReleaseProfile: PropTypes.func.isRequired onConfirmDeleteReleaseProfile: PropTypes.func.isRequired
}; };

View File

@ -2,24 +2,28 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { fetchReleaseProfiles, deleteReleaseProfile } from 'Store/Actions/settingsActions'; import { fetchReleaseProfiles, deleteReleaseProfile, fetchIndexers } from 'Store/Actions/settingsActions';
import createTagsSelector from 'Store/Selectors/createTagsSelector'; import createTagsSelector from 'Store/Selectors/createTagsSelector';
import ReleaseProfiles from './ReleaseProfiles'; import ReleaseProfiles from './ReleaseProfiles';
function createMapStateToProps() { function createMapStateToProps() {
return createSelector( return createSelector(
(state) => state.settings.releaseProfiles, (state) => state.settings.releaseProfiles,
(state) => state.settings.indexers,
createTagsSelector(), createTagsSelector(),
(releaseProfiles, tagList) => { (releaseProfiles, indexers, tagList) => {
return { return {
...releaseProfiles, ...releaseProfiles,
tagList tagList,
isIndexersPopulated: indexers.isPopulated,
indexerList: indexers.items
}; };
} }
); );
} }
const mapDispatchToProps = { const mapDispatchToProps = {
fetchIndexers,
fetchReleaseProfiles, fetchReleaseProfiles,
deleteReleaseProfile deleteReleaseProfile
}; };
@ -31,6 +35,9 @@ class ReleaseProfilesConnector extends Component {
componentDidMount() { componentDidMount() {
this.props.fetchReleaseProfiles(); this.props.fetchReleaseProfiles();
if (!this.props.isIndexersPopulated) {
this.props.fetchIndexers();
}
} }
// //
@ -54,8 +61,10 @@ class ReleaseProfilesConnector extends Component {
} }
ReleaseProfilesConnector.propTypes = { ReleaseProfilesConnector.propTypes = {
isIndexersPopulated: PropTypes.bool.isRequired,
fetchReleaseProfiles: PropTypes.func.isRequired, fetchReleaseProfiles: PropTypes.func.isRequired,
deleteReleaseProfile: PropTypes.func.isRequired deleteReleaseProfile: PropTypes.func.isRequired,
fetchIndexers: PropTypes.func.isRequired
}; };
export default connect(createMapStateToProps, mapDispatchToProps)(ReleaseProfilesConnector); export default connect(createMapStateToProps, mapDispatchToProps)(ReleaseProfilesConnector);

View File

@ -1,15 +0,0 @@
import { createSelector } from 'reselect';
function createIndexerSelector() {
return createSelector(
(state, { indexerId }) => indexerId,
(state) => state.settings.indexers.items,
(indexerId, indexers) => {
return indexers.find((profile) => {
return profile.id === indexerId;
});
}
);
}
export default createIndexerSelector;