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'; import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; 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, 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'; class UnmappedFilesTable extends Component { // // Lifecycle constructor(props, context) { super(props, context); this.scrollerRef = React.createRef(); this.state = { 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 }); } } 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, columns, deleteUnmappedFile } = this.props; const { selectedState } = this.state; const item = items[rowIndex]; return ( ); }; render() { const { isFetching, isPopulated, isDeleting, error, items, columns, sortKey, sortDirection, onTableOptionChange, onSortPress, isScanningFolders, onAddMissingArtistsPress, deleteUnmappedFiles, ...otherProps } = this.props; const { allSelected, allUnselected, selectedState } = this.state; const selectedTrackFileIds = this.getSelectedIds(); return ( { isFetching && !isPopulated && } { isPopulated && !error && !items.length && Success! My work is done, all files on disk are matched to known tracks. } { isPopulated && !error && !!items.length && this.scrollerRef.current ? } selectedState={selectedState} sortKey={sortKey} sortDirection={sortDirection} /> : null } ); } } 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, sortKey: PropTypes.string, sortDirection: PropTypes.oneOf(sortDirections.all), onTableOptionChange: PropTypes.func.isRequired, onSortPress: PropTypes.func.isRequired, deleteUnmappedFile: PropTypes.func.isRequired, deleteUnmappedFiles: PropTypes.func.isRequired, isScanningFolders: PropTypes.bool.isRequired, onAddMissingArtistsPress: PropTypes.func.isRequired }; export default UnmappedFilesTable;