New: Rework List Exclusion UI

list-exclusions
Qstick 2 years ago
parent 6659bc034c
commit 74382d7250

@ -181,12 +181,13 @@ class Blocklist extends Component {
> >
<TableBody> <TableBody>
{ {
items.map((item) => { items.map((item, index) => {
return ( return (
<BlocklistRowConnector <BlocklistRowConnector
key={item.id} key={item.id}
isSelected={selectedState[item.id] || false} isSelected={selectedState[item.id] || false}
columns={columns} columns={columns}
index={index}
{...item} {...item}
onSelectedChange={this.onSelectedChange} onSelectedChange={this.onSelectedChange}
/> />

@ -15,12 +15,13 @@
.tmdbId, .tmdbId,
.movieYear { .movieYear {
flex: 0 0 70px; composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 80px;
} }
.actions { .actions {
display: flex; composes: cell from '~Components/Table/Cells/TableRowCell.css';
justify-content: flex-end;
flex: 1 0 auto; width: 70px;
padding-right: 10px;
} }

@ -1,13 +1,16 @@
import classNames from 'classnames';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import React, { Component } from 'react'; import React, { Component } from 'react';
import Icon from 'Components/Icon'; import Icon from 'Components/Icon';
import Link from 'Components/Link/Link'; import Link from 'Components/Link/Link';
import ConfirmModal from 'Components/Modal/ConfirmModal'; import ConfirmModal from 'Components/Modal/ConfirmModal';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableSelectCell from 'Components/Table/Cells/TableSelectCell';
import TableRow from 'Components/Table/TableRow';
import { icons, kinds } from 'Helpers/Props'; import { icons, kinds } from 'Helpers/Props';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector'; import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
import styles from './ImportListExclusion.css'; import styles from './ImportListExclusion.css';
import IconButton from 'Components/Link/IconButton';
class ImportListExclusion extends Component { class ImportListExclusion extends Component {
@ -55,28 +58,82 @@ class ImportListExclusion extends Component {
render() { render() {
const { const {
id, id,
isSelected,
onSelectedChange,
columns,
movieTitle, movieTitle,
tmdbId, tmdbId,
movieYear movieYear
} = this.props; } = this.props;
return ( return (
<div <TableRow>
className={classNames( <TableSelectCell
styles.importExclusion id={id}
)} isSelected={isSelected}
> onSelectedChange={onSelectedChange}
<div className={styles.tmdbId}>{tmdbId}</div> />
<div className={styles.movieTitle}>{movieTitle}</div>
<div className={styles.movieYear}>{movieYear}</div> {
columns.map((column) => {
<div className={styles.actions}> const {
<Link name,
onPress={this.onEditImportExclusionPress} isVisible
> } = column;
<Icon name={icons.EDIT} />
</Link> if (!isVisible) {
</div> return null;
}
if (name === 'tmdbId') {
return (
<TableRowCell key={name}>
{tmdbId}
</TableRowCell>
);
}
if (name === 'movieTitle') {
return (
<TableRowCell key={name}>
{movieTitle}
</TableRowCell>
);
}
if (name === 'movieYear') {
return (
<TableRowCell key={name}>
{movieYear}
</TableRowCell>
);
}
if (name === 'actions') {
return (
<TableRowCell
key={name}
className={styles.actions}
>
<IconButton
title={translate('RemoveFromBlocklist')}
name={icons.EDIT}
onPress={this.onEditImportExclusionPress}
/>
<IconButton
title={translate('RemoveFromBlocklist')}
name={icons.REMOVE}
kind={kinds.DANGER}
onPress={this.onDeleteImportExclusionPress}
/>
</TableRowCell>
);
}
return null;
})
}
<EditImportListExclusionModalConnector <EditImportListExclusionModalConnector
id={id} id={id}
@ -94,7 +151,7 @@ class ImportListExclusion extends Component {
onConfirm={this.onConfirmDeleteImportExclusion} onConfirm={this.onConfirmDeleteImportExclusion}
onCancel={this.onDeleteImportExclusionModalClose} onCancel={this.onDeleteImportExclusionModalClose}
/> />
</div> </TableRow>
); );
} }
} }
@ -104,6 +161,9 @@ ImportListExclusion.propTypes = {
movieTitle: PropTypes.string.isRequired, movieTitle: PropTypes.string.isRequired,
tmdbId: PropTypes.number.isRequired, tmdbId: PropTypes.number.isRequired,
movieYear: PropTypes.number.isRequired, movieYear: PropTypes.number.isRequired,
isSelected: PropTypes.bool.isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
onSelectedChange: PropTypes.func.isRequired,
onConfirmDeleteImportExclusion: PropTypes.func.isRequired onConfirmDeleteImportExclusion: PropTypes.func.isRequired
}; };

@ -4,8 +4,12 @@ import FieldSet from 'Components/FieldSet';
import Icon from 'Components/Icon'; import Icon from 'Components/Icon';
import Link from 'Components/Link/Link'; import Link from 'Components/Link/Link';
import PageSectionContent from 'Components/Page/PageSectionContent'; import PageSectionContent from 'Components/Page/PageSectionContent';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons } from 'Helpers/Props'; import { icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate'; import translate from 'Utilities/String/translate';
import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected';
import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector'; import EditImportListExclusionModalConnector from './EditImportListExclusionModalConnector';
import ImportListExclusion from './ImportListExclusion'; import ImportListExclusion from './ImportListExclusion';
import styles from './ImportListExclusions.css'; import styles from './ImportListExclusions.css';
@ -19,6 +23,10 @@ class ImportListExclusions extends Component {
super(props, context); super(props, context);
this.state = { this.state = {
allSelected: false,
allUnselected: false,
lastToggled: null,
selectedState: {},
isAddImportExclusionModalOpen: false isAddImportExclusionModalOpen: false
}; };
} }
@ -26,6 +34,16 @@ class ImportListExclusions extends Component {
// //
// Listeners // Listeners
onSelectAllChange = ({ value }) => {
this.setState(selectAll(this.state.selectedState, value));
};
onSelectedChange = ({ id, value, shiftKey = false }) => {
this.setState((state) => {
return toggleSelected(state, this.props.items, id, value, shiftKey);
});
};
onAddImportExclusionPress = () => { onAddImportExclusionPress = () => {
this.setState({ isAddImportExclusionModalOpen: true }); this.setState({ isAddImportExclusionModalOpen: true });
}; };
@ -41,41 +59,50 @@ class ImportListExclusions extends Component {
const { const {
items, items,
onConfirmDeleteImportExclusion, onConfirmDeleteImportExclusion,
columns,
...otherProps ...otherProps
} = this.props; } = this.props;
const {
allSelected,
allUnselected,
selectedState
} = this.state;
return ( return (
<FieldSet legend={translate('ListExclusions')}> <FieldSet legend={translate('ListExclusions')}>
<PageSectionContent <PageSectionContent
errorMessage={translate('UnableToLoadListExclusions')} errorMessage={translate('UnableToLoadListExclusions')}
{...otherProps} {...otherProps}
> >
<div className={styles.importListExclusionsHeader}>
<div className={styles.tmdbId}>
TMDb Id
</div>
<div className={styles.title}>
{translate('Title')}
</div>
<div className={styles.movieYear}>
{translate('Year')}
</div>
</div>
<div> <div>
{ <Table
items.map((item, index) => { selectAll={true}
return ( allSelected={allSelected}
<ImportListExclusion allUnselected={allUnselected}
key={item.id} columns={columns}
{...item} {...otherProps}
{...otherProps} onSelectAllChange={this.onSelectAllChange}
index={index} >
onConfirmDeleteImportExclusion={onConfirmDeleteImportExclusion} <TableBody>
/> {
); items.map((item, index) => {
}) return (
} <ImportListExclusion
key={item.id}
isSelected={selectedState[item.id] || false}
{...item}
{...otherProps}
columns={columns}
index={index}
onSelectedChange={this.onSelectedChange}
onConfirmDeleteImportExclusion={onConfirmDeleteImportExclusion}
/>
);
})
}
</TableBody>
</Table>
</div> </div>
<div className={styles.addImportExclusion}> <div className={styles.addImportExclusion}>
@ -101,6 +128,7 @@ class ImportListExclusions extends Component {
ImportListExclusions.propTypes = { ImportListExclusions.propTypes = {
isFetching: PropTypes.bool.isRequired, isFetching: PropTypes.bool.isRequired,
error: PropTypes.object, error: PropTypes.object,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired,
onConfirmDeleteImportExclusion: PropTypes.func.isRequired onConfirmDeleteImportExclusion: PropTypes.func.isRequired
}; };

@ -4,6 +4,7 @@ import createRemoveItemHandler from 'Store/Actions/Creators/createRemoveItemHand
import createSaveProviderHandler from 'Store/Actions/Creators/createSaveProviderHandler'; import createSaveProviderHandler from 'Store/Actions/Creators/createSaveProviderHandler';
import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer'; import createSetSettingValueReducer from 'Store/Actions/Creators/Reducers/createSetSettingValueReducer';
import { createThunk } from 'Store/thunks'; import { createThunk } from 'Store/thunks';
import translate from 'Utilities/String/translate';
// //
// Variables // Variables
@ -48,7 +49,34 @@ export default {
items: [], items: [],
isSaving: false, isSaving: false,
saveError: null, saveError: null,
pendingChanges: {} pendingChanges: {},
columns: [
{
name: 'tmdbId',
label: 'TmdbId',
isSortable: true,
isVisible: true
},
{
name: 'movieTitle',
label: translate('Title'),
isSortable: true,
isVisible: true
},
{
name: 'movieYear',
label: translate('Year'),
isSortable: true,
isVisible: true
},
{
name: 'actions',
columnLabel: translate('Actions'),
isVisible: true,
isModifiable: false
}
]
}, },
// //

@ -1,10 +1,8 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using FluentValidation; using FluentValidation;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Core.Annotations;
using NzbDrone.Core.CustomFormats; using NzbDrone.Core.CustomFormats;
using Radarr.Http; using Radarr.Http;
using Radarr.Http.REST; using Radarr.Http.REST;

Loading…
Cancel
Save