Merge pull request #411 from dbeaver/feat/boolean-toggle

This commit is contained in:
Alexey
2021-07-07 20:00:13 +03:00
committed by GitHub
7 changed files with 53 additions and 16 deletions
@@ -17,6 +17,7 @@ import { ResultSetFormatAction } from '@cloudbeaver/plugin-data-viewer';
import { EditingContext } from '../../Editing/EditingContext';
import { DataGridContext } from '../DataGridContext';
import { DataGridSelectionContext } from '../DataGridSelection/DataGridSelectionContext';
import { isBooleanFormatterAvailable } from '../Formatters/CellFormatters/isBooleanFormatterAvailable';
import { TableDataContext } from '../TableDataContext';
import { CellContext, ICellContext } from './CellContext';
@@ -79,7 +80,9 @@ export const CellRenderer: React.FC<CellRendererProps<any>> = observer(function
}, [column, rowIdx, selectionContext, dataGridContext]);
const handleDoubleClick = useCallback(() => {
if (!column.editable || resultColumn?.dataKind?.toLowerCase() === 'boolean') {
if (!column.editable || (
resultColumn && isBooleanFormatterAvailable(editor?.getCell(rowIdx, Number(column.key)), resultColumn)
)) {
return;
}
const format = dataGridContext?.model.source.getAction(dataGridContext.resultIndex, ResultSetFormatAction);
@@ -96,7 +99,7 @@ export const CellRenderer: React.FC<CellRendererProps<any>> = observer(function
}
editingContext?.edit({ idx: column.idx, rowIdx });
}, [column, rowIdx, props.row]);
}, [column, rowIdx, props.row, editor, resultColumn]);
const row = editor?.get(rowIdx) || props.row;
@@ -9,6 +9,7 @@
import { injectable } from '@cloudbeaver/core-di';
import { ResultSetDataAction, ResultSetFormatAction } from '@cloudbeaver/plugin-data-viewer';
import { isBooleanFormatterAvailable } from '../Formatters/CellFormatters/isBooleanFormatterAvailable';
import { DataGridContextMenuService } from './DataGridContextMenuService';
@injectable()
@@ -50,13 +51,15 @@ export class DataGridContextMenuCellEditingService {
},
isHidden(context) {
const data = context.data.model.source.getAction(context.data.resultIndex, ResultSetDataAction);
const editor = context.data.model.source.getEditor(context.data.resultIndex);
const cellValue = editor.getCell(context.data.row, context.data.column);
const column = data.getColumn(context.data.column);
if (!column) {
return true;
}
return column.dataKind?.toLowerCase() === 'boolean';
return isBooleanFormatterAvailable(cellValue, column);
},
order: 0,
title: 'data_grid_table_editing_open_inline_editor',
@@ -6,28 +6,38 @@
* you may not use this file except in compliance with the License.
*/
import { useContext } from 'react';
import { useContext, useRef } from 'react';
import type { FormatterProps } from 'react-data-grid';
import { ResultSetFormatAction } from '@cloudbeaver/plugin-data-viewer';
import { EditingContext } from '../../Editing/EditingContext';
import { DataGridContext } from '../DataGridContext';
import { TableDataContext } from '../TableDataContext';
import { BooleanFormatter } from './CellFormatters/BooleanFormatter';
import { isBooleanFormatterAvailable } from './CellFormatters/isBooleanFormatterAvailable';
import { TextFormatter } from './CellFormatters/TextFormatter';
export const CellFormatterFactory: React.FC<FormatterProps> = function CellFormatterFactory(props) {
const formatterRef = useRef<React.FC<FormatterProps> | null>(null);
const context = useContext(DataGridContext);
const tableDataContext = useContext(TableDataContext);
const formatter = context?.model.source.getAction(context.resultIndex, ResultSetFormatAction);
const editingContext = useContext(EditingContext);
const isEditing = editingContext?.isEditing({ idx: props.column.idx, rowIdx: props.rowIdx });
const resultColumn = tableDataContext?.getColumnInfo(props.column.key);
const rawValue = formatter?.get(props.row[props.column.key]) ?? props.row[props.column.key];
let Formatter: React.FC<FormatterProps> = TextFormatter;
if (!isEditing || formatterRef === null) {
formatterRef.current = TextFormatter;
if (resultColumn?.dataKind?.toLowerCase() === 'boolean' && (typeof rawValue === 'boolean' || formatter?.isNull(rawValue))) {
Formatter = BooleanFormatter;
if (resultColumn && isBooleanFormatterAvailable(rawValue, resultColumn)) {
formatterRef.current = BooleanFormatter;
}
}
const Formatter = formatterRef.current!;
return <Formatter {...props} />;
};
@@ -42,8 +42,9 @@ export const BooleanFormatter: React.FC<FormatterProps> = observer(function Bool
const formatter = context?.model.source.getAction(context.resultIndex, ResultSetFormatAction);
const resultColumn = tableDataContext?.getColumnInfo(column.key);
const rawValue = formatter?.get(row[column.key]) ?? row[column.key];
const stringifiedValue = formatter?.toDisplayString(rawValue) ?? String(rawValue);
const value = rawValue === null ? stringifiedValue : `[${rawValue ? 'v' : ' '}]`;
const value = typeof rawValue === 'string' ? rawValue.toLowerCase() === 'true' : rawValue;
const stringifiedValue = formatter?.toDisplayString(value) ?? String(value);
const valueRepresentation = value === null ? stringifiedValue : `[${value ? 'v' : ' '}]`;
const classes = getClasses(rawValue);
const getNextValue = useCallback((prev: boolean | null) => {
@@ -60,10 +61,10 @@ export const BooleanFormatter: React.FC<FormatterProps> = observer(function Bool
as='span'
title={stringifiedValue}
onClick={() => context?.model.source.getEditor(context.resultIndex)
.setCell(rowIdx, Number(column.key), getNextValue(rawValue))}
{...use({ boolean: rawValue !== null })}
.setCell(rowIdx, Number(column.key), getNextValue(value))}
{...use({ boolean: value !== null })}
>
{value}
{valueRepresentation}
</boolean-formatter>
);
});
@@ -0,0 +1,19 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2021 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import type { SqlResultColumn } from '@cloudbeaver/core-sdk';
import type { IResultSetValue } from '@cloudbeaver/plugin-data-viewer';
export function isBooleanFormatterAvailable(cellValue: IResultSetValue, column: SqlResultColumn): boolean {
return column?.dataKind?.toLowerCase() === 'boolean'
&& (
typeof cellValue === 'boolean'
|| cellValue === null
|| (typeof cellValue === 'string' && ['false', 'true'].includes(cellValue.toLowerCase()))
);
}
@@ -299,6 +299,10 @@ export class DatabaseDataEditor<TResult extends IDatabaseDataResult> implements
return String(valueA) === String(valueB);
}
if (typeof valueA === 'boolean' || typeof valueB === 'boolean') {
return String(valueA).toLowerCase() === String(valueB).toLowerCase();
}
if (isResultSetContentValue(valueA) && isResultSetContentValue(valueB)) {
if ('text' in valueA && 'text' in valueB) {
return valueA.text === valueB.text;
@@ -17,7 +17,6 @@ import { CodeEditorLoader } from '@cloudbeaver/plugin-codemirror';
import type { IResultSetElementKey } from '../../DatabaseDataModel/Actions/ResultSet/IResultSetElementKey';
import { isResultSetContentValue } from '../../DatabaseDataModel/Actions/ResultSet/isResultSetContentValue';
import { ResultSetDataAction } from '../../DatabaseDataModel/Actions/ResultSet/ResultSetDataAction';
import { ResultSetFormatAction } from '../../DatabaseDataModel/Actions/ResultSet/ResultSetFormatAction';
import { ResultSetSelectAction } from '../../DatabaseDataModel/Actions/ResultSet/ResultSetSelectAction';
import type { IDatabaseResultSet } from '../../DatabaseDataModel/IDatabaseResultSet';
@@ -93,7 +92,6 @@ export const TextValuePresentation: TabContainerPanelComponent<IDataValuePanelPr
const result = model.getResult(resultIndex);
const selection = model.source.getAction(resultIndex, ResultSetSelectAction);
const data = model.source.getAction(resultIndex, ResultSetDataAction);
const selectedCells = selection.getSelectedElements();
const focusCell = selection.getFocusedElement();
@@ -113,8 +111,7 @@ export const TextValuePresentation: TabContainerPanelComponent<IDataValuePanelPr
.getCell(firstSelectedCell.row, firstSelectedCell.column);
stringValue = format.getText(value) ?? '';
readonly = format.isReadOnly(firstSelectedCell)
|| data.getColumn(firstSelectedCell.column)?.dataKind?.toLowerCase() === 'boolean';
readonly = format.isReadOnly(firstSelectedCell);
if (isResultSetContentValue(value)) {
if (value.contentType) {