diff --git a/lib/gui/app/components/drive-selector/drive-selector.tsx b/lib/gui/app/components/drive-selector/drive-selector.tsx index 7cb5196a..d09c8b4b 100644 --- a/lib/gui/app/components/drive-selector/drive-selector.tsx +++ b/lib/gui/app/components/drive-selector/drive-selector.tsx @@ -79,7 +79,7 @@ const DrivesTable = styled((props: GenericTableProps) => ( [data-display='table-body'] { > [data-display='table-row'] > [data-display='table-cell'] { &:nth-child(2) { - width: 38%; + width: 32%; } &:nth-child(3) { @@ -345,6 +345,16 @@ export class DriveSelector extends React.Component< } } + private deselectingAll(rows: DrivelistDrive[]) { + return ( + rows.length > 0 && + rows.length === this.state.selectedList.length && + this.state.selectedList.every( + (d) => rows.findIndex((r) => d.device === r.device) > -1, + ) + ); + } + componentDidMount() { this.unsubscribe = store.subscribe(() => { const drives = getDrives(); @@ -423,6 +433,7 @@ export class DriveSelector extends React.Component< t.setRowSelection(selectedList); } }} + checkedRowsNumber={selectedList.length} multipleSelection={this.props.multipleSelection} columns={this.tableColumns} data={displayedDrives} @@ -432,8 +443,11 @@ export class DriveSelector extends React.Component< } rowKey="displayName" onCheck={(rows: Drive[]) => { - const newSelection = rows.filter(isDrivelistDrive); + let newSelection = rows.filter(isDrivelistDrive); if (this.props.multipleSelection) { + if (this.deselectingAll(newSelection)) { + newSelection = []; + } this.setState({ selectedList: newSelection, }); @@ -450,24 +464,20 @@ export class DriveSelector extends React.Component< ) { return; } - if (this.props.multipleSelection) { - const newList = [...selectedList]; - const selectedIndex = selectedList.findIndex( - (drive) => drive.device === row.device, - ); - if (selectedIndex === -1) { - newList.push(row); - } else { - // Deselect if selected - newList.splice(selectedIndex, 1); - } - this.setState({ - selectedList: newList, - }); - return; + const index = selectedList.findIndex( + (d) => d.device === row.device, + ); + const newList = this.props.multipleSelection + ? [...selectedList] + : []; + if (index === -1) { + newList.push(row); + } else { + // Deselect if selected + newList.splice(index, 1); } this.setState({ - selectedList: [row], + selectedList: newList, }); }} /> diff --git a/lib/gui/app/styled-components.tsx b/lib/gui/app/styled-components.tsx index 2b5f8547..79578718 100644 --- a/lib/gui/app/styled-components.tsx +++ b/lib/gui/app/styled-components.tsx @@ -151,6 +151,11 @@ export const Modal = styled(({ style, children, ...props }) => { padding: 0; height: 100%; + > div:first-child { + height: 81%; + padding: 24px 30px 0; + } + > h3 { margin: 0; padding: 24px 30px 0; @@ -225,6 +230,8 @@ export const Alert = styled((props) => ( export interface GenericTableProps extends BaseTableProps { refFn: (t: BaseTable) => void; + data: T[]; + checkedRowsNumber?: number; multipleSelection: boolean; showWarnings?: boolean; } @@ -254,6 +261,22 @@ function StyledTable() { input[type='checkbox'] + div { display: ${(props) => (props.multipleSelection ? 'flex' : 'none')}; + + ${(props) => + props.multipleSelection && + props.checkedRowsNumber !== 0 && + props.checkedRowsNumber !== props.data.length + ? ` + font-weight: 600; + color: ${colors.primary.foreground}; + background: ${colors.primary.background}; + + ::after { + content: '–'; + } + ` + : ''} + } } } @@ -276,8 +299,7 @@ function StyledTable() { &[data-highlight='true'] { &.system { - background-color: ${(props) => - props.showWarnings ? '#fff5e6' : '#e8f5fc'}; + background-color: ${(props) => (props.showWarnings ? '#fff5e6' : '#e8f5fc')}; } > [data-display='table-cell']:first-child {