mirror of
https://github.com/Readarr/Readarr.git
synced 2026-04-18 21:34:28 -04:00
New: Add details and delete buttons to file editor table
This commit is contained in:
@@ -0,0 +1,6 @@
|
|||||||
|
.TrackActionsCell {
|
||||||
|
composes: cell from '~Components/Table/Cells/TableRowCell.css';
|
||||||
|
|
||||||
|
width: 70px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import FileDetailsModal from 'BookFile/FileDetailsModal';
|
||||||
|
import IconButton from 'Components/Link/IconButton';
|
||||||
|
import ConfirmModal from 'Components/Modal/ConfirmModal';
|
||||||
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
|
import { icons, kinds } from 'Helpers/Props';
|
||||||
|
import styles from './BookFileActionsCell.css';
|
||||||
|
|
||||||
|
class BookFileActionsCell extends Component {
|
||||||
|
|
||||||
|
//
|
||||||
|
// Lifecycle
|
||||||
|
|
||||||
|
constructor(props, context) {
|
||||||
|
super(props, context);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
isDetailsModalOpen: false,
|
||||||
|
isConfirmDeleteModalOpen: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Listeners
|
||||||
|
|
||||||
|
onDetailsPress = () => {
|
||||||
|
this.setState({ isDetailsModalOpen: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
onDetailsModalClose = () => {
|
||||||
|
this.setState({ isDetailsModalOpen: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
onDeleteFilePress = () => {
|
||||||
|
this.setState({ isConfirmDeleteModalOpen: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
onConfirmDelete = () => {
|
||||||
|
this.setState({ isConfirmDeleteModalOpen: false });
|
||||||
|
this.props.deleteBookFile({ id: this.props.id });
|
||||||
|
}
|
||||||
|
|
||||||
|
onConfirmDeleteModalClose = () => {
|
||||||
|
this.setState({ isConfirmDeleteModalOpen: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Render
|
||||||
|
|
||||||
|
render() {
|
||||||
|
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
path
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
|
const {
|
||||||
|
isDetailsModalOpen,
|
||||||
|
isConfirmDeleteModalOpen
|
||||||
|
} = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<TableRowCell className={styles.TrackActionsCell}>
|
||||||
|
{
|
||||||
|
path &&
|
||||||
|
<IconButton
|
||||||
|
name={icons.INFO}
|
||||||
|
onPress={this.onDetailsPress}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
{
|
||||||
|
path &&
|
||||||
|
<IconButton
|
||||||
|
name={icons.DELETE}
|
||||||
|
onPress={this.onDeleteFilePress}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
<FileDetailsModal
|
||||||
|
isOpen={isDetailsModalOpen}
|
||||||
|
onModalClose={this.onDetailsModalClose}
|
||||||
|
id={id}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<ConfirmModal
|
||||||
|
isOpen={isConfirmDeleteModalOpen}
|
||||||
|
kind={kinds.DANGER}
|
||||||
|
title="Delete Book File"
|
||||||
|
message={`Are you sure you want to delete ${path}?`}
|
||||||
|
confirmLabel="Delete"
|
||||||
|
onConfirm={this.onConfirmDelete}
|
||||||
|
onCancel={this.onConfirmDeleteModalClose}
|
||||||
|
/>
|
||||||
|
</TableRowCell>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BookFileActionsCell.propTypes = {
|
||||||
|
id: PropTypes.number.isRequired,
|
||||||
|
path: PropTypes.string,
|
||||||
|
deleteBookFile: PropTypes.func.isRequired
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BookFileActionsCell;
|
||||||
@@ -4,6 +4,7 @@ import BookQuality from 'Book/BookQuality';
|
|||||||
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
import TableRowCell from 'Components/Table/Cells/TableRowCell';
|
||||||
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
|
||||||
import TableRow from 'Components/Table/TableRow';
|
import TableRow from 'Components/Table/TableRow';
|
||||||
|
import BookFileActionsCell from './BookFileActionsCell';
|
||||||
|
|
||||||
function BookFileEditorRow(props) {
|
function BookFileEditorRow(props) {
|
||||||
const {
|
const {
|
||||||
@@ -12,7 +13,8 @@ function BookFileEditorRow(props) {
|
|||||||
quality,
|
quality,
|
||||||
qualityCutoffNotMet,
|
qualityCutoffNotMet,
|
||||||
isSelected,
|
isSelected,
|
||||||
onSelectedChange
|
onSelectedChange,
|
||||||
|
deleteBookFile
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -32,6 +34,12 @@ function BookFileEditorRow(props) {
|
|||||||
isCutoffNotMet={qualityCutoffNotMet}
|
isCutoffNotMet={qualityCutoffNotMet}
|
||||||
/>
|
/>
|
||||||
</TableRowCell>
|
</TableRowCell>
|
||||||
|
|
||||||
|
<BookFileActionsCell
|
||||||
|
id={id}
|
||||||
|
path={path}
|
||||||
|
deleteBookFile={deleteBookFile}
|
||||||
|
/>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -42,7 +50,8 @@ BookFileEditorRow.propTypes = {
|
|||||||
quality: PropTypes.object.isRequired,
|
quality: PropTypes.object.isRequired,
|
||||||
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
qualityCutoffNotMet: PropTypes.bool.isRequired,
|
||||||
isSelected: PropTypes.bool,
|
isSelected: PropTypes.bool,
|
||||||
onSelectedChange: PropTypes.func.isRequired
|
onSelectedChange: PropTypes.func.isRequired,
|
||||||
|
deleteBookFile: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BookFileEditorRow;
|
export default BookFileEditorRow;
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ const columns = [
|
|||||||
name: 'quality',
|
name: 'quality',
|
||||||
label: 'Quality',
|
label: 'Quality',
|
||||||
isVisible: true
|
isVisible: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'actions',
|
||||||
|
columnLabel: 'Actions',
|
||||||
|
isVisible: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
@@ -117,7 +122,8 @@ class BookFileEditorTableContent extends Component {
|
|||||||
isPopulated,
|
isPopulated,
|
||||||
error,
|
error,
|
||||||
items,
|
items,
|
||||||
qualities
|
qualities,
|
||||||
|
dispatchDeleteBookFile
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -178,6 +184,7 @@ class BookFileEditorTableContent extends Component {
|
|||||||
isSelected={selectedState[item.id]}
|
isSelected={selectedState[item.id]}
|
||||||
{...item}
|
{...item}
|
||||||
onSelectedChange={this.onSelectedChange}
|
onSelectedChange={this.onSelectedChange}
|
||||||
|
deleteBookFile={dispatchDeleteBookFile}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
@@ -230,7 +237,8 @@ BookFileEditorTableContent.propTypes = {
|
|||||||
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
items: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
qualities: PropTypes.arrayOf(PropTypes.object).isRequired,
|
qualities: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
onDeletePress: PropTypes.func.isRequired,
|
onDeletePress: PropTypes.func.isRequired,
|
||||||
onQualityChange: PropTypes.func.isRequired
|
onQualityChange: PropTypes.func.isRequired,
|
||||||
|
dispatchDeleteBookFile: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default BookFileEditorTableContent;
|
export default BookFileEditorTableContent;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ 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 { deleteBookFiles, updateBookFiles } from 'Store/Actions/bookFileActions';
|
import { deleteBookFile, deleteBookFiles, updateBookFiles } from 'Store/Actions/bookFileActions';
|
||||||
import { fetchQualityProfileSchema } from 'Store/Actions/settingsActions';
|
import { fetchQualityProfileSchema } from 'Store/Actions/settingsActions';
|
||||||
import createAuthorSelector from 'Store/Selectors/createAuthorSelector';
|
import createAuthorSelector from 'Store/Selectors/createAuthorSelector';
|
||||||
import getQualities from 'Utilities/Quality/getQualities';
|
import getQualities from 'Utilities/Quality/getQualities';
|
||||||
@@ -67,6 +67,10 @@ function createMapDispatchToProps(dispatch, props) {
|
|||||||
|
|
||||||
onDeletePress(bookFileIds) {
|
onDeletePress(bookFileIds) {
|
||||||
dispatch(deleteBookFiles({ bookFileIds }));
|
dispatch(deleteBookFiles({ bookFileIds }));
|
||||||
|
},
|
||||||
|
|
||||||
|
dispatchDeleteBookFile(id) {
|
||||||
|
dispatch(deleteBookFile(id));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -119,7 +123,8 @@ BookFileEditorTableContentConnector.propTypes = {
|
|||||||
bookId: PropTypes.number,
|
bookId: PropTypes.number,
|
||||||
qualities: PropTypes.arrayOf(PropTypes.object).isRequired,
|
qualities: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
dispatchFetchQualityProfileSchema: PropTypes.func.isRequired,
|
dispatchFetchQualityProfileSchema: PropTypes.func.isRequired,
|
||||||
dispatchUpdateBookFiles: PropTypes.func.isRequired
|
dispatchUpdateBookFiles: PropTypes.func.isRequired,
|
||||||
|
dispatchDeleteBookFile: PropTypes.func.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
export default connect(createMapStateToProps, createMapDispatchToProps)(BookFileEditorTableContentConnector);
|
export default connect(createMapStateToProps, createMapDispatchToProps)(BookFileEditorTableContentConnector);
|
||||||
|
|||||||
Reference in New Issue
Block a user