Remove movie editor code

pull/8414/head
Qstick 1 year ago
parent e85c010bf2
commit 2d96c308f0

@ -1,31 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import DeleteMovieModalContentConnector from './DeleteMovieModalContentConnector';
function DeleteMovieModal(props) {
const {
isOpen,
onModalClose,
...otherProps
} = props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
>
<DeleteMovieModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
</Modal>
);
}
DeleteMovieModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default DeleteMovieModal;

@ -1,13 +0,0 @@
.message {
margin-top: 20px;
margin-bottom: 10px;
}
.pathContainer {
margin-left: 5px;
}
.path {
margin-left: 5px;
color: var(--dangerColor);
}

@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
'path': string;
'pathContainer': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,145 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import Button from 'Components/Link/Button';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './DeleteMovieModalContent.css';
class DeleteMovieModalContent extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
deleteFiles: false,
addImportExclusion: false
};
}
//
// Listeners
onDeleteFilesChange = ({ value }) => {
this.setState({ deleteFiles: value });
};
onAddImportExclusionChange = ({ value }) => {
this.setState({ addImportExclusion: value });
};
onDeleteMovieConfirmed = () => {
const deleteFiles = this.state.deleteFiles;
const addImportExclusion = this.state.addImportExclusion;
this.setState({ deleteFiles: false, addImportExclusion: false });
this.props.onDeleteSelectedPress(deleteFiles, addImportExclusion);
};
//
// Render
render() {
const {
movies,
onModalClose
} = this.props;
const deleteFiles = this.state.deleteFiles;
const addImportExclusion = this.state.addImportExclusion;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('DeleteSelectedMovie')}
</ModalHeader>
<ModalBody>
<div>
<FormGroup>
<FormLabel>{`Delete Movie Folder${movies.length > 1 ? 's' : ''}`}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="deleteFiles"
value={deleteFiles}
helpText={`Delete Movie Folder${movies.length > 1 ? 's' : ''} and all contents`}
kind={kinds.DANGER}
onChange={this.onDeleteFilesChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('AddListExclusion')}</FormLabel>
<FormInputGroup
type={inputTypes.CHECK}
name="addImportExclusion"
value={addImportExclusion}
helpText={translate('AddImportExclusionHelpText')}
kind={kinds.DANGER}
onChange={this.onAddImportExclusionChange}
/>
</FormGroup>
</div>
<div className={styles.message}>
{`Are you sure you want to delete ${movies.length} selected movie(s)${deleteFiles ? ' and all contents' : ''}?`}
</div>
<ul>
{
movies.map((s) => {
return (
<li key={s.title}>
<span>{s.title}</span>
{
deleteFiles &&
<span className={styles.pathContainer}>
-
<span className={styles.path}>
{s.path}
</span>
</span>
}
</li>
);
})
}
</ul>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
{translate('Cancel')}
</Button>
<Button
kind={kinds.DANGER}
onPress={this.onDeleteMovieConfirmed}
>
{translate('Delete')}
</Button>
</ModalFooter>
</ModalContent>
);
}
}
DeleteMovieModalContent.propTypes = {
movies: PropTypes.arrayOf(PropTypes.object).isRequired,
onModalClose: PropTypes.func.isRequired,
onDeleteSelectedPress: PropTypes.func.isRequired
};
export default DeleteMovieModalContent;

@ -1,46 +0,0 @@
import _ from 'lodash';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { bulkDeleteMovie } from 'Store/Actions/movieIndexActions';
import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector';
import DeleteMovieModalContent from './DeleteMovieModalContent';
function createMapStateToProps() {
return createSelector(
(state, { movieIds }) => movieIds,
createAllMoviesSelector(),
(movieIds, allMovies) => {
const selectedMovie = _.intersectionWith(allMovies, movieIds, (s, id) => {
return s.id === id;
});
const sortedMovies = _.orderBy(selectedMovie, 'sortTitle');
const movies = _.map(sortedMovies, (s) => {
return {
title: s.title,
path: s.path
};
});
return {
movies
};
}
);
}
function createMapDispatchToProps(dispatch, props) {
return {
onDeleteSelectedPress(deleteFiles, addImportExclusion) {
dispatch(bulkDeleteMovie({
movieIds: props.movieIds,
deleteFiles,
addImportExclusion
}));
props.onModalClose();
}
};
}
export default connect(createMapStateToProps, createMapDispatchToProps)(DeleteMovieModalContent);

@ -1,57 +0,0 @@
.inputContainer {
margin-right: 20px;
min-width: 150px;
}
.buttonContainer {
display: flex;
justify-content: flex-end;
flex-grow: 1;
}
.buttonContainerContent {
flex-grow: 0;
}
.buttons {
display: flex;
justify-content: flex-end;
flex-grow: 1;
}
.organizeSelectedButton,
.tagsButton {
composes: button from '~Components/Link/SpinnerButton.css';
margin-right: 10px;
height: 35px;
}
.deleteSelectedButton {
composes: button from '~Components/Link/SpinnerButton.css';
margin-left: 50px;
height: 35px;
}
@media only screen and (max-width: $breakpointSmall) {
.inputContainer {
margin-right: 0;
}
.buttonContainer {
justify-content: flex-start;
}
.buttonContainerContent {
flex-grow: 1;
}
.buttons {
justify-content: space-between;
}
.selectedMovieLabel {
text-align: left;
}
}

@ -1,14 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'buttonContainer': string;
'buttonContainerContent': string;
'buttons': string;
'deleteSelectedButton': string;
'inputContainer': string;
'organizeSelectedButton': string;
'selectedMovieLabel': string;
'tagsButton': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,303 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import AvailabilitySelectInput from 'Components/Form/AvailabilitySelectInput';
import QualityProfileSelectInputConnector from 'Components/Form/QualityProfileSelectInputConnector';
import RootFolderSelectInputConnector from 'Components/Form/RootFolderSelectInputConnector';
import SelectInput from 'Components/Form/SelectInput';
import SpinnerButton from 'Components/Link/SpinnerButton';
import PageContentFooter from 'Components/Page/PageContentFooter';
import { kinds } from 'Helpers/Props';
import MoveMovieModal from 'Movie/MoveMovie/MoveMovieModal';
import translate from 'Utilities/String/translate';
import DeleteMovieModal from './Delete/DeleteMovieModal';
import MovieEditorFooterLabel from './MovieEditorFooterLabel';
import TagsModal from './Tags/TagsModal';
import styles from './MovieEditorFooter.css';
const NO_CHANGE = 'noChange';
class MovieEditorFooter extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
monitored: NO_CHANGE,
qualityProfileId: NO_CHANGE,
minimumAvailability: NO_CHANGE,
rootFolderPath: NO_CHANGE,
savingTags: false,
isDeleteMovieModalOpen: false,
isTagsModalOpen: false,
isConfirmMoveModalOpen: false,
destinationRootFolder: null
};
}
componentDidUpdate(prevProps) {
const {
isSaving,
saveError
} = this.props;
if (prevProps.isSaving && !isSaving && !saveError) {
this.setState({
monitored: NO_CHANGE,
qualityProfileId: NO_CHANGE,
minimumAvailability: NO_CHANGE,
rootFolderPath: NO_CHANGE,
savingTags: false
});
}
}
//
// Listeners
onInputChange = ({ name, value }) => {
this.setState({ [name]: value });
if (value === NO_CHANGE) {
return;
}
switch (name) {
case 'rootFolderPath':
this.setState({
isConfirmMoveModalOpen: true,
destinationRootFolder: value
});
break;
case 'monitored':
this.props.onSaveSelected({ [name]: value === 'monitored' });
break;
default:
this.props.onSaveSelected({ [name]: value });
}
};
onApplyTagsPress = (tags, applyTags) => {
this.setState({
savingTags: true,
isTagsModalOpen: false
});
this.props.onSaveSelected({
tags,
applyTags
});
};
onDeleteSelectedPress = () => {
this.setState({ isDeleteMovieModalOpen: true });
};
onDeleteMovieModalClose = () => {
this.setState({ isDeleteMovieModalOpen: false });
};
onTagsPress = () => {
this.setState({ isTagsModalOpen: true });
};
onTagsModalClose = () => {
this.setState({ isTagsModalOpen: false });
};
onSaveRootFolderPress = () => {
this.setState({
isConfirmMoveModalOpen: false,
destinationRootFolder: null
});
this.props.onSaveSelected({ rootFolderPath: this.state.destinationRootFolder });
};
onMoveMoviePress = () => {
this.setState({
isConfirmMoveModalOpen: false,
destinationRootFolder: null
});
this.props.onSaveSelected({
rootFolderPath: this.state.destinationRootFolder,
moveFiles: true
});
};
//
// Render
render() {
const {
movieIds,
selectedCount,
isSaving,
isDeleting,
isOrganizingMovie,
onOrganizeMoviePress
} = this.props;
const {
monitored,
qualityProfileId,
minimumAvailability,
rootFolderPath,
savingTags,
isTagsModalOpen,
isDeleteMovieModalOpen,
isConfirmMoveModalOpen,
destinationRootFolder
} = this.state;
const monitoredOptions = [
{ key: NO_CHANGE, value: translate('NoChange'), disabled: true },
{ key: 'monitored', value: translate('Monitored') },
{ key: 'unmonitored', value: translate('Unmonitored') }
];
return (
<PageContentFooter>
<div className={styles.inputContainer}>
<MovieEditorFooterLabel
label={translate('MonitorMovie')}
isSaving={isSaving && monitored !== NO_CHANGE}
/>
<SelectInput
name="monitored"
value={monitored}
values={monitoredOptions}
isDisabled={!selectedCount}
onChange={this.onInputChange}
/>
</div>
<div className={styles.inputContainer}>
<MovieEditorFooterLabel
label={translate('QualityProfile')}
isSaving={isSaving && qualityProfileId !== NO_CHANGE}
/>
<QualityProfileSelectInputConnector
name="qualityProfileId"
value={qualityProfileId}
includeNoChange={true}
isDisabled={!selectedCount}
onChange={this.onInputChange}
/>
</div>
<div className={styles.inputContainer}>
<MovieEditorFooterLabel
label={translate('MinimumAvailability')}
isSaving={isSaving && minimumAvailability !== NO_CHANGE}
/>
<AvailabilitySelectInput
name="minimumAvailability"
value={minimumAvailability}
includeNoChange={true}
isDisabled={!selectedCount}
onChange={this.onInputChange}
/>
</div>
<div className={styles.inputContainer}>
<MovieEditorFooterLabel
label={translate('RootFolder')}
isSaving={isSaving && rootFolderPath !== NO_CHANGE}
/>
<RootFolderSelectInputConnector
name="rootFolderPath"
value={rootFolderPath}
includeNoChange={true}
isDisabled={!selectedCount}
selectedValueOptions={{ includeFreeSpace: false }}
onChange={this.onInputChange}
/>
</div>
<div className={styles.buttonContainer}>
<div className={styles.buttonContainerContent}>
<MovieEditorFooterLabel
label={translate('MoviesSelectedInterp', [selectedCount])}
isSaving={false}
/>
<div className={styles.buttons}>
<div>
<SpinnerButton
className={styles.organizeSelectedButton}
kind={kinds.WARNING}
isSpinning={isOrganizingMovie}
isDisabled={!selectedCount || isOrganizingMovie}
onPress={onOrganizeMoviePress}
>
{translate('RenameFiles')}
</SpinnerButton>
<SpinnerButton
className={styles.tagsButton}
isSpinning={isSaving && savingTags}
isDisabled={!selectedCount || isOrganizingMovie}
onPress={this.onTagsPress}
>
{translate('SetTags')}
</SpinnerButton>
</div>
<SpinnerButton
className={styles.deleteSelectedButton}
kind={kinds.DANGER}
isSpinning={isDeleting}
isDisabled={!selectedCount || isDeleting}
onPress={this.onDeleteSelectedPress}
>
{translate('Delete')}
</SpinnerButton>
</div>
</div>
</div>
<TagsModal
isOpen={isTagsModalOpen}
movieIds={movieIds}
onApplyTagsPress={this.onApplyTagsPress}
onModalClose={this.onTagsModalClose}
/>
<DeleteMovieModal
isOpen={isDeleteMovieModalOpen}
movieIds={movieIds}
onModalClose={this.onDeleteMovieModalClose}
/>
<MoveMovieModal
destinationRootFolder={destinationRootFolder}
isOpen={isConfirmMoveModalOpen}
onSavePress={this.onSaveRootFolderPress}
onMoveMoviePress={this.onMoveMoviePress}
/>
</PageContentFooter>
);
}
}
MovieEditorFooter.propTypes = {
movieIds: PropTypes.arrayOf(PropTypes.number).isRequired,
selectedCount: PropTypes.number.isRequired,
isSaving: PropTypes.bool.isRequired,
saveError: PropTypes.object,
isDeleting: PropTypes.bool.isRequired,
deleteError: PropTypes.object,
isOrganizingMovie: PropTypes.bool.isRequired,
onSaveSelected: PropTypes.func.isRequired,
onOrganizeMoviePress: PropTypes.func.isRequired
};
export default MovieEditorFooter;

@ -1,8 +0,0 @@
.label {
margin-bottom: 3px;
font-weight: bold;
}
.savingIcon {
margin-left: 8px;
}

@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'label': string;
'savingIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,40 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import SpinnerIcon from 'Components/SpinnerIcon';
import { icons } from 'Helpers/Props';
import styles from './MovieEditorFooterLabel.css';
function MovieEditorFooterLabel(props) {
const {
className,
label,
isSaving
} = props;
return (
<div className={className}>
{label}
{
isSaving &&
<SpinnerIcon
className={styles.savingIcon}
name={icons.SPINNER}
isSpinning={true}
/>
}
</div>
);
}
MovieEditorFooterLabel.propTypes = {
className: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
isSaving: PropTypes.bool.isRequired
};
MovieEditorFooterLabel.defaultProps = {
className: styles.label
};
export default MovieEditorFooterLabel;

@ -1,31 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import OrganizeMovieModalContentConnector from './OrganizeMovieModalContentConnector';
function OrganizeMovieModal(props) {
const {
isOpen,
onModalClose,
...otherProps
} = props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
>
<OrganizeMovieModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
</Modal>
);
}
OrganizeMovieModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default OrganizeMovieModal;

@ -1,8 +0,0 @@
.renameIcon {
margin-left: 5px;
}
.message {
margin-top: 20px;
margin-bottom: 10px;
}

@ -1,8 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
'renameIcon': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,75 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Alert from 'Components/Alert';
import Icon from 'Components/Icon';
import Button from 'Components/Link/Button';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './OrganizeMovieModalContent.css';
function OrganizeMovieModalContent(props) {
const {
movieTitles,
onModalClose,
onOrganizeMoviePress
} = props;
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
{translate('OrganizeSelectedMovies')}
</ModalHeader>
<ModalBody>
<Alert>
{translate('PreviewRenameHelpText')}
<Icon
className={styles.renameIcon}
name={icons.ORGANIZE}
/>
</Alert>
<div className={styles.message}>
{translate('OrganizeConfirm', [movieTitles.length])}
</div>
<ul>
{
movieTitles.map((title) => {
return (
<li key={title}>
{title}
</li>
);
})
}
</ul>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
{translate('Cancel')}
</Button>
<Button
kind={kinds.DANGER}
onPress={onOrganizeMoviePress}
>
{translate('Organize')}
</Button>
</ModalFooter>
</ModalContent>
);
}
OrganizeMovieModalContent.propTypes = {
movieTitles: PropTypes.arrayOf(PropTypes.string).isRequired,
onModalClose: PropTypes.func.isRequired,
onOrganizeMoviePress: PropTypes.func.isRequired
};
export default OrganizeMovieModalContent;

@ -1,67 +0,0 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import * as commandNames from 'Commands/commandNames';
import { executeCommand } from 'Store/Actions/commandActions';
import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector';
import OrganizeMovieModalContent from './OrganizeMovieModalContent';
function createMapStateToProps() {
return createSelector(
(state, { movieIds }) => movieIds,
createAllMoviesSelector(),
(movieIds, allMovies) => {
const movies = _.intersectionWith(allMovies, movieIds, (s, id) => {
return s.id === id;
});
const sortedMovies = _.orderBy(movies, 'sortTitle');
const movieTitles = _.map(sortedMovies, 'title');
return {
movieTitles
};
}
);
}
const mapDispatchToProps = {
executeCommand
};
class OrganizeMovieModalContentConnector extends Component {
//
// Listeners
onOrganizeMoviePress = () => {
this.props.executeCommand({
name: commandNames.RENAME_MOVIE,
movieIds: this.props.movieIds
});
this.props.onModalClose(true);
};
//
// Render
render(props) {
return (
<OrganizeMovieModalContent
{...this.props}
onOrganizeMoviePress={this.onOrganizeMoviePress}
/>
);
}
}
OrganizeMovieModalContentConnector.propTypes = {
movieIds: PropTypes.arrayOf(PropTypes.number).isRequired,
onModalClose: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired
};
export default connect(createMapStateToProps, mapDispatchToProps)(OrganizeMovieModalContentConnector);

@ -1,31 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import Modal from 'Components/Modal/Modal';
import TagsModalContentConnector from './TagsModalContentConnector';
function TagsModal(props) {
const {
isOpen,
onModalClose,
...otherProps
} = props;
return (
<Modal
isOpen={isOpen}
onModalClose={onModalClose}
>
<TagsModalContentConnector
{...otherProps}
onModalClose={onModalClose}
/>
</Modal>
);
}
TagsModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
onModalClose: PropTypes.func.isRequired
};
export default TagsModal;

@ -1,12 +0,0 @@
.renameIcon {
margin-left: 5px;
}
.message {
margin-top: 20px;
margin-bottom: 10px;
}
.result {
padding-top: 4px;
}

@ -1,9 +0,0 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'message': string;
'renameIcon': string;
'result': string;
}
export const cssExports: CssExports;
export default cssExports;

@ -1,188 +0,0 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Form from 'Components/Form/Form';
import FormGroup from 'Components/Form/FormGroup';
import FormInputGroup from 'Components/Form/FormInputGroup';
import FormLabel from 'Components/Form/FormLabel';
import Label from 'Components/Label';
import Button from 'Components/Link/Button';
import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes, kinds, sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './TagsModalContent.css';
class TagsModalContent extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
tags: [],
applyTags: 'add'
};
}
//
// Lifecycle
onInputChange = ({ name, value }) => {
this.setState({ [name]: value });
};
onApplyTagsPress = () => {
const {
tags,
applyTags
} = this.state;
this.props.onApplyTagsPress(tags, applyTags);
};
//
// Render
render() {
const {
movieTags,
tagList,
onModalClose
} = this.props;
const {
tags,
applyTags
} = this.state;
const applyTagsOptions = [
{ key: 'add', value: translate('Add') },
{ key: 'remove', value: translate('Remove') },
{ key: 'replace', value: translate('Replace') }
];
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
Tags
</ModalHeader>
<ModalBody>
<Form>
<FormGroup>
<FormLabel>{translate('Tags')}</FormLabel>
<FormInputGroup
type={inputTypes.TAG}
name="tags"
value={tags}
onChange={this.onInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('ApplyTags')}</FormLabel>
<FormInputGroup
type={inputTypes.SELECT}
name="applyTags"
value={applyTags}
values={applyTagsOptions}
helpTexts={[
translate('ApplyTagsHelpTexts1'),
translate('ApplyTagsHelpTexts2'),
translate('ApplyTagsHelpTexts3'),
translate('ApplyTagsHelpTexts4')
]}
onChange={this.onInputChange}
/>
</FormGroup>
<FormGroup>
<FormLabel>{translate('Result')}</FormLabel>
<div className={styles.result}>
{
movieTags.map((t) => {
const tag = _.find(tagList, { id: t });
if (!tag) {
return null;
}
const removeTag = (applyTags === 'remove' && tags.indexOf(t) > -1) ||
(applyTags === 'replace' && tags.indexOf(t) === -1);
return (
<Label
key={tag.id}
title={removeTag ? translate('RemovingTag') : translate('ExistingTag')}
kind={removeTag ? kinds.INVERSE : kinds.INFO}
size={sizes.LARGE}
>
{tag.label}
</Label>
);
})
}
{
(applyTags === 'add' || applyTags === 'replace') &&
tags.map((t) => {
const tag = _.find(tagList, { id: t });
if (!tag) {
return null;
}
if (movieTags.indexOf(t) > -1) {
return null;
}
return (
<Label
key={tag.id}
title={translate('AddingTag')}
kind={kinds.SUCCESS}
size={sizes.LARGE}
>
{tag.label}
</Label>
);
})
}
</div>
</FormGroup>
</Form>
</ModalBody>
<ModalFooter>
<Button onPress={onModalClose}>
{translate('Cancel')}
</Button>
<Button
kind={kinds.PRIMARY}
onPress={this.onApplyTagsPress}
>
{translate('Apply')}
</Button>
</ModalFooter>
</ModalContent>
);
}
}
TagsModalContent.propTypes = {
movieTags: PropTypes.arrayOf(PropTypes.number).isRequired,
tagList: PropTypes.arrayOf(PropTypes.object).isRequired,
onModalClose: PropTypes.func.isRequired,
onApplyTagsPress: PropTypes.func.isRequired
};
export default TagsModalContent;

@ -1,36 +0,0 @@
import _ from 'lodash';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector';
import createTagsSelector from 'Store/Selectors/createTagsSelector';
import TagsModalContent from './TagsModalContent';
function createMapStateToProps() {
return createSelector(
(state, { movieIds }) => movieIds,
createAllMoviesSelector(),
createTagsSelector(),
(movieIds, allMovies, tagList) => {
const movies = _.intersectionWith(allMovies, movieIds, (s, id) => {
return s.id === id;
});
const movieTags = _.uniq(_.concat(..._.map(movies, 'tags')));
return {
movieTags,
tagList
};
}
);
}
function createMapDispatchToProps(dispatch, props) {
return {
onAction() {
// Do something
}
};
}
export default connect(createMapStateToProps, createMapDispatchToProps)(TagsModalContent);
Loading…
Cancel
Save