better multiselect of columns

This commit is contained in:
Jan Prochazka
2022-01-01 11:44:23 +01:00
parent f6f0108e17
commit d52c69d746
6 changed files with 44 additions and 30 deletions

View File

@@ -20,7 +20,7 @@ export type GroupFunc = 'GROUP' | 'MAX' | 'MIN' | 'SUM' | 'AVG' | 'COUNT' | 'COU
export interface GridConfig extends GridConfigColumns { export interface GridConfig extends GridConfigColumns {
filters: { [uniqueName: string]: string }; filters: { [uniqueName: string]: string };
focusedColumn?: string; focusedColumns?: string[];
columnWidths: { [uniqueName: string]: number }; columnWidths: { [uniqueName: string]: number };
sort: { sort: {
uniqueName: string; uniqueName: string;
@@ -48,7 +48,7 @@ export function createGridConfig(): GridConfig {
filters: {}, filters: {},
columnWidths: {}, columnWidths: {},
sort: [], sort: [],
focusedColumn: null, focusedColumns: null,
grouping: {}, grouping: {},
formFilterColumns: [], formFilterColumns: [],
}; };

View File

@@ -104,10 +104,10 @@ export abstract class GridDisplay {
this.includeInColumnSet('addedColumns', name, true); this.includeInColumnSet('addedColumns', name, true);
} }
focusColumn(uniqueName: string) { focusColumns(uniqueNames: string[]) {
this.setConfig(cfg => ({ this.setConfig(cfg => ({
...cfg, ...cfg,
focusedColumn: uniqueName, focusedColumns: uniqueNames,
})); }));
} }
@@ -115,8 +115,8 @@ export abstract class GridDisplay {
return false; return false;
} }
get focusedColumn() { get focusedColumns() {
return this.config.focusedColumn; return this.config.focusedColumns;
} }
get engine() { get engine() {

View File

@@ -26,48 +26,62 @@
let selectedColumns = []; let selectedColumns = [];
let currentColumnUniqueName = null; let currentColumnUniqueName = null;
let dragStartColumnIndex = null; let dragStartColumnIndex = null;
let shiftOriginColumnIndex = null;
$: items = display?.getColumns(filter)?.filter(column => filterName(filter, column.columnName)) || []; $: items = display?.getColumns(filter)?.filter(column => filterName(filter, column.columnName)) || [];
function selectColumn(uniqueName) { function selectColumnIndexCore(index, e) {
const uniqueName = items[index].uniqueName;
if (e.shiftKey) {
const curIndex = _.findIndex(items, x => x.uniqueName == currentColumnUniqueName);
if (curIndex >= 0 && shiftOriginColumnIndex == null) shiftOriginColumnIndex = curIndex;
selectedColumns = _.range(
Math.min(shiftOriginColumnIndex, index),
Math.max(shiftOriginColumnIndex, index) + 1
).map(i => items[i].uniqueName);
} else {
selectedColumns = [uniqueName];
shiftOriginColumnIndex = null;
}
currentColumnUniqueName = uniqueName; currentColumnUniqueName = uniqueName;
selectedColumns = [uniqueName];
if (!isJsonView) { if (!isJsonView) {
display.focusColumn(uniqueName); display.focusColumns(selectedColumns);
} }
} }
function selectColumnIndex(index) { function selectColumnIndex(index, e) {
if (index >= 0 && index < items.length) { if (index >= 0 && index < items.length) {
selectColumn(items[index].uniqueName); selectColumnIndexCore(index, e);
return; return;
} }
if (items.length == 0) { if (items.length == 0) {
return; return;
} }
if (index < 0) { if (index < 0) {
selectColumn(items[0].uniqueName); selectColumnIndexCore(0, e);
return; return;
} else if (index >= items.length) { } else if (index >= items.length) {
selectColumn(items[items.length - 1].uniqueName); selectColumnIndexCore(items.length - 1, e);
return; return;
} }
} }
function moveIndex(indexFunc) { function moveIndex(indexFunc, e) {
const index = _.findIndex(items, x => x.uniqueName == currentColumnUniqueName); const index = _.findIndex(items, x => x.uniqueName == currentColumnUniqueName);
if (index >= 0) { if (index >= 0) {
selectColumnIndex(indexFunc(index)); selectColumnIndex(indexFunc(index), e);
} }
} }
function handleKeyDown(e) { function handleKeyDown(e) {
if (e.keyCode == keycodes.upArrow) moveIndex(i => i - 1); if (e.keyCode == keycodes.upArrow) moveIndex(i => i - 1, e);
else if (e.keyCode == keycodes.downArrow) moveIndex(i => i + 1); else if (e.keyCode == keycodes.downArrow) moveIndex(i => i + 1, e);
else if (e.keyCode == keycodes.home) moveIndex(() => 0); else if (e.keyCode == keycodes.home) moveIndex(() => 0, e);
else if (e.keyCode == keycodes.end) moveIndex(() => items.length - 1); else if (e.keyCode == keycodes.end) moveIndex(() => items.length - 1, e);
else if (e.keyCode == keycodes.pageUp) moveIndex(i => i - 10); else if (e.keyCode == keycodes.pageUp) moveIndex(i => i - 10, e);
else if (e.keyCode == keycodes.pageDown) moveIndex(i => i + 10); else if (e.keyCode == keycodes.pageDown) moveIndex(i => i + 10, e);
else if (e.keyCode == keycodes.space) { else if (e.keyCode == keycodes.space) {
let checked = null; let checked = null;
for (const name of selectedColumns) { for (const name of selectedColumns) {
@@ -143,7 +157,7 @@
).map(i => items[i].uniqueName); ).map(i => items[i].uniqueName);
currentColumnUniqueName = column.uniqueName; currentColumnUniqueName = column.uniqueName;
if (!isJsonView) { if (!isJsonView) {
display.focusColumn(column.uniqueName); display.focusColumns([currentColumnUniqueName, ...selectedColumns]);
} }
} }
} }
@@ -154,7 +168,7 @@
if (domFocusField) domFocusField.focus(); if (domFocusField) domFocusField.focus();
currentColumnUniqueName = column.uniqueName; currentColumnUniqueName = column.uniqueName;
if (!isJsonView) { if (!isJsonView) {
display.focusColumn(column.uniqueName); display.focusColumns(selectedColumns);
} }
}} }}
on:mouseup={e => { on:mouseup={e => {

View File

@@ -19,7 +19,7 @@
// @ts-ignore // @ts-ignore
if (e.target.closest('.expandColumnIcon')) return; if (e.target.closest('.expandColumnIcon')) return;
if (isJsonView) display.showFilter(column.uniqueName); if (isJsonView) display.showFilter(column.uniqueName);
else display.focusColumn(column.uniqueName); else display.focusColumns([column.uniqueName]);
}} }}
class:isSelected class:isSelected
on:click on:click

View File

@@ -740,9 +740,9 @@
$: { $: {
tick().then(() => { tick().then(() => {
if (display && display.focusedColumn) { if (display?.focusedColumns?.length > 0) {
const invMap = _.invert(realColumnUniqueNames); const invMap = _.invert(realColumnUniqueNames);
const colIndex = invMap[display.focusedColumn]; const colIndex = invMap[display.focusedColumns[0]];
if (colIndex) { if (colIndex) {
scrollIntoView([null, colIndex]); scrollIntoView([null, colIndex]);
} }
@@ -908,7 +908,7 @@
} }
} }
if (display.focusedColumn) display.focusColumn(null); if (display.focusedColumns) display.focusColumns(null);
} }
function handleGridMouseMove(event) { function handleGridMouseMove(event) {
@@ -1490,7 +1490,7 @@
{isDynamicStructure} {isDynamicStructure}
selectedCells={filterCellsForRow(selectedCells, rowIndex)} selectedCells={filterCellsForRow(selectedCells, rowIndex)}
autofillMarkerCell={filterCellForRow(autofillMarkerCell, rowIndex)} autofillMarkerCell={filterCellForRow(autofillMarkerCell, rowIndex)}
focusedColumn={display.focusedColumn} focusedColumns={display.focusedColumns}
inplaceEditorState={$inplaceEditorState} inplaceEditorState={$inplaceEditorState}
currentCellColumn={currentCell && currentCell[0] == rowIndex ? currentCell[1] : null} currentCellColumn={currentCell && currentCell[0] == rowIndex ? currentCell[1] : null}
{dispatchInsplaceEditor} {dispatchInsplaceEditor}

View File

@@ -17,7 +17,7 @@
export let selectedCells = undefined; export let selectedCells = undefined;
export let autofillSelectedCells = undefined; export let autofillSelectedCells = undefined;
export let autofillMarkerCell = undefined; export let autofillMarkerCell = undefined;
export let focusedColumn = undefined; export let focusedColumns = undefined;
export let inplaceEditorState; export let inplaceEditorState;
export let dispatchInsplaceEditor; export let dispatchInsplaceEditor;
export let onSetFormView; export let onSetFormView;
@@ -75,7 +75,7 @@
isCurrentCell={col.colIndex == currentCellColumn} isCurrentCell={col.colIndex == currentCellColumn}
isFrameSelected={frameSelection ? cellIsSelected(rowIndex, col.colIndex, selectedCells) : false} isFrameSelected={frameSelection ? cellIsSelected(rowIndex, col.colIndex, selectedCells) : false}
isAutofillSelected={cellIsSelected(rowIndex, col.colIndex, autofillSelectedCells)} isAutofillSelected={cellIsSelected(rowIndex, col.colIndex, autofillSelectedCells)}
isFocusedColumn={col.uniqueName == focusedColumn} isFocusedColumn={focusedColumns?.includes(col.uniqueName)}
isModifiedCell={rowStatus.modifiedFields && rowStatus.modifiedFields.has(col.uniqueName)} isModifiedCell={rowStatus.modifiedFields && rowStatus.modifiedFields.has(col.uniqueName)}
isModifiedRow={rowStatus.status == 'updated'} isModifiedRow={rowStatus.status == 'updated'}
isInserted={rowStatus.status == 'inserted' || isInserted={rowStatus.status == 'inserted' ||