fix(plugin-data-spreadsheet-new): CB-817 inline editor

This commit is contained in:
Wroud
2021-08-23 23:22:48 +03:00
parent b9108c4e05
commit a879ddbc11
5 changed files with 56 additions and 11 deletions
@@ -55,6 +55,9 @@ export const CellEditor = observer<Pick<EditorProps<IResultSetRowKey>, 'row' | '
const [popperRef, setPopperRef] = useState<HTMLDivElement | null>(null);
const popper = usePopper(elementRef, popperRef, {
placement: 'right',
modifiers: [
{ name: 'flip', enabled: false },
],
});
if (!dataGridContext || !tableDataContext || column.columnDataIndex === null) {
@@ -132,6 +135,7 @@ export const CellEditor = observer<Pick<EditorProps<IResultSetRowKey>, 'row' | '
<InlineEditor
ref={inputRef}
value={value}
controlsPosition="inside"
edited
hideSave
hideCancel
@@ -39,15 +39,16 @@ const rowHeight = 25;
const headerHeight = 28;
export const DataGridTable: React.FC<IDataPresentationProps<any, IDatabaseResultSet>> = observer(function DataGridTable({ model, actions, resultIndex, className }) {
const gridContainerRef = useRef<HTMLDivElement>(null);
const dataGridRef = useRef<DataGridHandle>(null);
const gridContainerRef = useRef<HTMLDivElement | null>(null);
const editorRef = useRef<HTMLDivElement>(null);
const dataGridDivRef = useRef<HTMLDivElement | null>(null);
const dataGridRef = useRef<DataGridHandle>(null);
const styles = useStyles(reactGridStyles, baseStyles);
const [columnResize] = useState(() => new Executor<IColumnResizeInfo>());
const selectionAction = model.source.getAction(resultIndex, ResultSetSelectAction);
const tableData = useTableData(model, resultIndex);
const tableData = useTableData(model, resultIndex, dataGridDivRef);
const focusSyncRef = useRef<CellPosition | null>(null);
const gridSelectionContext = useGridSelectionContext(tableData, selectionAction);
@@ -79,6 +80,18 @@ export const DataGridTable: React.FC<IDataPresentationProps<any, IDatabaseResult
},
});
function setContainersRef(element: HTMLDivElement) {
gridContainerRef.current = element;
const gridDiv = gridContainerRef.current?.firstChild;
if (gridDiv instanceof HTMLDivElement) {
dataGridDivRef.current = gridDiv;
} else {
dataGridDivRef.current = null;
}
}
const { onKeydownHandler } = useGridSelectedCellsCopy(tableData, gridSelectionContext);
const { onMouseDownHandler, onMouseMoveHandler } = useGridDragging({
onDragStart: startPosition => {
@@ -110,13 +123,11 @@ export const DataGridTable: React.FC<IDataPresentationProps<any, IDatabaseResult
}
if (selectionAction.isFocused(data.value.key)) {
const gridDiv = gridContainerRef.current?.firstChild;
const rowTop = rowIdx * rowHeight;
const gridDiv = dataGridDivRef.current;
dataGridRef.current?.scrollToColumn(idx);
if (
gridDiv instanceof HTMLDivElement
) {
if (gridDiv) {
if (rowTop < gridDiv.scrollTop - rowHeight + headerHeight) {
gridDiv.scrollTo({
top: rowTop,
@@ -205,7 +216,7 @@ export const DataGridTable: React.FC<IDataPresentationProps<any, IDatabaseResult
<EditingContext.Provider value={editingContext}>
<TableDataContext.Provider value={tableData}>
<grid-container
ref={gridContainerRef}
ref={setContainersRef}
className="cb-react-grid-container"
tabIndex={-1}
onKeyDown={onKeydownHandler}
@@ -20,7 +20,7 @@ import { CellContext } from '../../CellRenderer/CellContext';
import { DataGridContext } from '../../DataGridContext';
import { TableDataContext } from '../../TableDataContext';
export const TextFormatter: React.FC<FormatterProps> = observer(function TextFormatter({ row, rowIdx, column, isCellSelected }) {
export const TextFormatter: React.FC<FormatterProps> = observer(function TextFormatter({ row, column, isCellSelected }) {
const editorRef = useRef<IEditorRef>(null);
const context = useContext(DataGridContext);
const editingContext = useContext(EditingContext);
@@ -19,6 +19,12 @@ declare module 'react-data-grid' {
}
}
interface IColumnMetrics {
width: number;
left: number;
right: number;
}
export interface ITableData {
format: ResultSetFormatAction;
data: ResultSetDataAction;
@@ -27,6 +33,8 @@ export interface ITableData {
columns: Array<Column<IResultSetRowKey, any>>;
columnKeys: IResultSetColumnKey[];
rows: IResultSetRowKey[];
gridDiv: HTMLDivElement | null;
getMetrics: (columnIndex: number) => IColumnMetrics;
getRow: (rowIndex: number) => IResultSetRowKey;
getColumn: (columnIndex: number) => Column<IResultSetRowKey, any>;
getColumnByDataIndex: (key: IResultSetColumnKey) => Column<IResultSetRowKey, any>;
@@ -19,7 +19,7 @@ import { TableIndexColumnHeader } from './TableColumnHeader/TableIndexColumnHead
import type { ITableData } from './TableDataContext';
export const indexColumn: Column<IResultSetRowKey, any> = {
key: '#',
key: 'index',
columnDataIndex: null,
name: '#',
minWidth: 60,
@@ -30,13 +30,20 @@ export const indexColumn: Column<IResultSetRowKey, any> = {
formatter: IndexFormatter,
};
export function useTableData(model: IDatabaseDataModel<any, IDatabaseResultSet>, resultIndex: number): ITableData {
export function useTableData(
model: IDatabaseDataModel<any, IDatabaseResultSet>,
resultIndex: number,
gridDIVElement: React.RefObject<HTMLDivElement | null>
): ITableData {
const format = model.source.getAction(resultIndex, ResultSetFormatAction);
const data = model.source.getAction(resultIndex, ResultSetDataAction);
const editor = model.source.getAction(resultIndex, ResultSetEditAction);
const view = model.source.getAction(resultIndex, ResultSetViewAction);
return useObservableRef<ITableData>(() => ({
get gridDiv(): HTMLDivElement | null {
return gridDIVElement.current;
},
get columnKeys(): IResultSetColumnKey[] {
return this.view.columnKeys;
},
@@ -75,6 +82,21 @@ export function useTableData(model: IDatabaseDataModel<any, IDatabaseResultSet>,
return columns;
},
getMetrics(columnIndex) {
let left = 0;
for (let i = 0; i < columnIndex; i++) {
const column = this.columns[i];
left += column.width as number;
}
const column = this.getColumn(columnIndex);
return {
left,
right: left + (column.width as number),
width: column.width as number,
};
},
getRow(rowIndex) {
return this.rows[rowIndex];
},