@ -1,5 +1,6 @@
import PropTypes from 'prop-types' ;
import React , { Component } from 'react' ;
import Alert from 'Components/Alert' ;
import LoadingIndicator from 'Components/Loading/LoadingIndicator' ;
import PageContent from 'Components/Page/PageContent' ;
import PageContentBody from 'Components/Page/PageContentBody' ;
@ -9,8 +10,12 @@ import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection';
import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper' ;
import VirtualTable from 'Components/Table/VirtualTable' ;
import VirtualTableRow from 'Components/Table/VirtualTableRow' ;
import { align , icons , sortDirections } from 'Helpers/Props' ;
import { align , icons , kinds , sortDirections } from 'Helpers/Props' ;
import hasDifferentItemsOrOrder from 'Utilities/Object/hasDifferentItemsOrOrder' ;
import translate from 'Utilities/String/translate' ;
import getSelectedIds from 'Utilities/Table/getSelectedIds' ;
import selectAll from 'Utilities/Table/selectAll' ;
import toggleSelected from 'Utilities/Table/toggleSelected' ;
import UnmappedFilesTableHeader from './UnmappedFilesTableHeader' ;
import UnmappedFilesTableRow from './UnmappedFilesTableRow' ;
@ -23,10 +28,43 @@ class UnmappedFilesTable extends Component {
super ( props , context ) ;
this . state = {
scroller : null
scroller : null ,
allSelected : false ,
allUnselected : false ,
lastToggled : null ,
selectedState : { }
} ;
}
componentDidMount ( ) {
this . setSelectedState ( ) ;
}
componentDidUpdate ( prevProps ) {
const {
items ,
sortKey ,
sortDirection ,
isDeleting ,
deleteError
} = this . props ;
if ( sortKey !== prevProps . sortKey ||
sortDirection !== prevProps . sortDirection ||
hasDifferentItemsOrOrder ( prevProps . items , items )
) {
this . setSelectedState ( ) ;
}
const hasFinishedDeleting = prevProps . isDeleting &&
! isDeleting &&
! deleteError ;
if ( hasFinishedDeleting ) {
this . onSelectAllChange ( { value : false } ) ;
}
}
//
// Control
@ -34,6 +72,68 @@ class UnmappedFilesTable extends Component {
this . setState ( { scroller : ref } ) ;
} ;
getSelectedIds = ( ) => {
if ( this . state . allUnselected ) {
return [ ] ;
}
return getSelectedIds ( this . state . selectedState ) ;
} ;
setSelectedState ( ) {
const {
items
} = this . props ;
const {
selectedState
} = this . state ;
const newSelectedState = { } ;
items . forEach ( ( file ) => {
const isItemSelected = selectedState [ file . id ] ;
if ( isItemSelected ) {
newSelectedState [ file . id ] = isItemSelected ;
} else {
newSelectedState [ file . id ] = false ;
}
} ) ;
const selectedCount = getSelectedIds ( newSelectedState ) . length ;
const newStateCount = Object . keys ( newSelectedState ) . length ;
let isAllSelected = false ;
let isAllUnselected = false ;
if ( selectedCount === 0 ) {
isAllUnselected = true ;
} else if ( selectedCount === newStateCount ) {
isAllSelected = true ;
}
this . setState ( { selectedState : newSelectedState , allSelected : isAllSelected , allUnselected : isAllUnselected } ) ;
}
onSelectAllChange = ( { value } ) => {
this . setState ( selectAll ( this . state . selectedState , value ) ) ;
} ;
onSelectAllPress = ( ) => {
this . onSelectAllChange ( { value : ! this . state . allSelected } ) ;
} ;
onSelectedChange = ( { id , value , shiftKey = false } ) => {
this . setState ( ( state ) => {
return toggleSelected ( state , this . props . items , id , value , shiftKey ) ;
} ) ;
} ;
onDeleteUnmappedFilesPress = ( ) => {
const selectedIds = this . getSelectedIds ( ) ;
this . props . deleteUnmappedFiles ( selectedIds ) ;
} ;
rowRenderer = ( { key , rowIndex , style } ) => {
const {
items ,
@ -41,6 +141,10 @@ class UnmappedFilesTable extends Component {
deleteUnmappedFile
} = this . props ;
const {
selectedState
} = this . state ;
const item = items [ rowIndex ] ;
return (
@ -51,6 +155,8 @@ class UnmappedFilesTable extends Component {
< UnmappedFilesTableRow
key = { item . id }
columns = { columns }
isSelected = { selectedState [ item . id ] }
onSelectedChange = { this . onSelectedChange }
deleteUnmappedFile = { deleteUnmappedFile }
{ ... item }
/ >
@ -63,6 +169,7 @@ class UnmappedFilesTable extends Component {
const {
isFetching ,
isPopulated ,
isDeleting ,
error ,
items ,
columns ,
@ -72,13 +179,19 @@ class UnmappedFilesTable extends Component {
onSortPress ,
isScanningFolders ,
onAddMissingAuthorsPress ,
deleteUnmappedFiles ,
... otherProps
} = this . props ;
const {
scroller
scroller ,
allSelected ,
allUnselected ,
selectedState
} = this . state ;
const selectedTrackFileIds = this . getSelectedIds ( ) ;
return (
< PageContent title = { translate ( 'UnmappedFiles' ) } >
< PageToolbar >
@ -90,6 +203,13 @@ class UnmappedFilesTable extends Component {
isSpinning = { isScanningFolders }
onPress = { onAddMissingAuthorsPress }
/ >
< PageToolbarButton
label = { translate ( 'DeleteSelected' ) }
iconName = { icons . DELETE }
isDisabled = { selectedTrackFileIds . length === 0 }
isSpinning = { isDeleting }
onPress = { this . onDeleteUnmappedFilesPress }
/ >
< / P a g e T o o l b a r S e c t i o n >
< PageToolbarSection alignContent = { align . RIGHT } >
@ -117,9 +237,9 @@ class UnmappedFilesTable extends Component {
{
isPopulated && ! error && ! items . length &&
< div >
< Alert kind = { kinds . INFO } >
Success ! My work is done , all files on disk are matched to known books .
< / di v >
< / Al e r t >
}
{
@ -138,8 +258,12 @@ class UnmappedFilesTable extends Component {
sortDirection = { sortDirection }
onTableOptionChange = { onTableOptionChange }
onSortPress = { onSortPress }
allSelected = { allSelected }
allUnselected = { allUnselected }
onSelectAllChange = { this . onSelectAllChange }
/ >
}
selectedState = { selectedState }
sortKey = { sortKey }
sortDirection = { sortDirection }
/ >
@ -153,6 +277,8 @@ class UnmappedFilesTable extends Component {
UnmappedFilesTable . propTypes = {
isFetching : PropTypes . bool . isRequired ,
isPopulated : PropTypes . bool . isRequired ,
isDeleting : PropTypes . bool . isRequired ,
deleteError : PropTypes . object ,
error : PropTypes . object ,
items : PropTypes . arrayOf ( PropTypes . object ) . isRequired ,
columns : PropTypes . arrayOf ( PropTypes . object ) . isRequired ,
@ -161,6 +287,7 @@ UnmappedFilesTable.propTypes = {
onTableOptionChange : PropTypes . func . isRequired ,
onSortPress : PropTypes . func . isRequired ,
deleteUnmappedFile : PropTypes . func . isRequired ,
deleteUnmappedFiles : PropTypes . func . isRequired ,
isScanningFolders : PropTypes . bool . isRequired ,
onAddMissingAuthorsPress : PropTypes . func . isRequired
} ;