mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
fix(plugin-data-spreadsheet-new): CB-817 inline editor
This commit is contained in:
@@ -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}
|
||||
|
||||
+1
-1
@@ -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];
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user