columns resize

This commit is contained in:
Jan Prochazka 2020-05-10 18:52:14 +02:00
parent 836db096a9
commit a41538b452
9 changed files with 90 additions and 41 deletions

View File

@ -19,6 +19,7 @@ export interface GridReferenceDefinition {
export interface GridConfig extends GridConfigColumns {
filters: { [uniqueName: string]: string };
focusedColumn?: string;
columnWidths: { [uniqueName: string]: number };
sort: {
uniqueName: string;
order: 'ASC' | 'DESC';
@ -37,6 +38,7 @@ export function createGridConfig(): GridConfig {
expandedColumns: [],
addedColumns: [],
filters: {},
columnWidths: {},
sort: [],
focusedColumn: null,
};

View File

@ -38,12 +38,13 @@ export function combineReferenceActions(a: ReferenceActionResult, b: ReferenceAc
return 'noAction';
}
export type ChangeCacheFunc = (changeFunc: (config: GridCache) => GridCache) => void;
export type ChangeCacheFunc = (changeFunc: (cache: GridCache) => GridCache) => void;
export type ChangeConfigFunc = (changeFunc: (config: GridConfig) => GridConfig) => void;
export abstract class GridDisplay {
constructor(
public config: GridConfig,
protected setConfig: (config: GridConfig) => void,
protected setConfig: ChangeConfigFunc,
public cache: GridCache,
protected setCache: ChangeCacheFunc,
public driver?: EngineDriver
@ -67,10 +68,10 @@ export abstract class GridDisplay {
}
focusColumn(uniqueName: string) {
this.setConfig({
...this.config,
this.setConfig((cfg) => ({
...cfg,
focusedColumn: uniqueName,
});
}));
}
get focusedColumn() {
@ -96,30 +97,30 @@ export abstract class GridDisplay {
includeInColumnSet(field: keyof GridConfigColumns, uniqueName: string, isIncluded: boolean) {
// console.log('includeInColumnSet', field, uniqueName, isIncluded);
if (isIncluded) {
this.setConfig({
...this.config,
[field]: [...(this.config[field] || []), uniqueName],
});
this.setConfig((cfg) => ({
...cfg,
[field]: [...(cfg[field] || []), uniqueName],
}));
} else {
this.setConfig({
...this.config,
[field]: (this.config[field] || []).filter((x) => x != uniqueName),
});
this.setConfig((cfg) => ({
...cfg,
[field]: (cfg[field] || []).filter((x) => x != uniqueName),
}));
}
}
showAllColumns() {
this.setConfig({
...this.config,
this.setConfig((cfg) => ({
...cfg,
hiddenColumns: [],
});
}));
}
hideAllColumns() {
this.setConfig({
...this.config,
this.setConfig((cfg) => ({
...cfg,
hiddenColumns: this.columns.map((x) => x.uniqueName),
});
}));
}
get hiddenColumnIndexes() {
@ -203,21 +204,21 @@ export abstract class GridDisplay {
}
setFilter(uniqueName, value) {
this.setConfig({
...this.config,
this.setConfig((cfg) => ({
...cfg,
filters: {
...this.config.filters,
...cfg.filters,
[uniqueName]: value,
},
});
}));
this.reload();
}
setSort(uniqueName, order) {
this.setConfig({
...this.config,
this.setConfig((cfg) => ({
...cfg,
sort: [{ uniqueName, order }],
});
}));
this.reload();
}
@ -230,10 +231,10 @@ export abstract class GridDisplay {
}
clearFilters() {
this.setConfig({
...this.config,
this.setConfig((cfg) => ({
...cfg,
filters: {},
});
}));
this.reload();
}
@ -314,6 +315,23 @@ export abstract class GridDisplay {
return sql;
}
resizeColumn(uniqueName: string, computedSize: number, diff: number) {
this.setConfig((cfg) => {
const columnWidths = {
...cfg.columnWidths,
};
if (columnWidths[uniqueName]) {
columnWidths[uniqueName] += diff;
} else {
columnWidths[uniqueName] = computedSize + diff;
}
return {
...cfg,
columnWidths,
};
});
}
getCountQuery() {
const select = this.createSelect();
select.columns = [

View File

@ -1,4 +1,4 @@
import { GridDisplay, ChangeCacheFunc } from './GridDisplay';
import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay';
import { QueryResultColumn } from '@dbgate/types';
import { GridConfig, GridCache } from './GridConfig';
@ -7,7 +7,7 @@ export class JslGridDisplay extends GridDisplay {
jslid,
columns: QueryResultColumn[],
config: GridConfig,
setConfig: (config: GridConfig) => void,
setConfig: ChangeConfigFunc,
cache: GridCache,
setCache: ChangeCacheFunc
) {

View File

@ -6,6 +6,7 @@ import {
DisplayColumn,
ReferenceActionResult,
DisplayedColumnInfo,
ChangeConfigFunc,
} from './GridDisplay';
import { TableInfo, EngineDriver, ViewInfo, ColumnInfo, NamedObjectInfo } from '@dbgate/types';
import { GridConfig, GridCache, createGridCache } from './GridConfig';
@ -19,7 +20,7 @@ export class TableGridDisplay extends GridDisplay {
public tableName: NamedObjectInfo,
driver: EngineDriver,
config: GridConfig,
setConfig: (config: GridConfig) => void,
setConfig: ChangeConfigFunc,
cache: GridCache,
setCache: ChangeCacheFunc,
protected getTableInfo: ({ schemaName, pureName }) => Promise<TableInfo>

View File

@ -1,5 +1,5 @@
import _ from 'lodash';
import { GridDisplay, ChangeCacheFunc } from './GridDisplay';
import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay';
import { EngineDriver, ViewInfo, ColumnInfo } from '@dbgate/types';
import { GridConfig, GridCache } from './GridConfig';
@ -8,7 +8,7 @@ export class ViewGridDisplay extends GridDisplay {
public view: ViewInfo,
driver: EngineDriver,
config: GridConfig,
setConfig: (config: GridConfig) => void,
setConfig: ChangeConfigFunc,
cache: GridCache,
setCache: ChangeCacheFunc
) {

View File

@ -3,10 +3,12 @@ import styled from 'styled-components';
import ColumnLabel from './ColumnLabel';
import DropDownButton from '../widgets/DropDownButton';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import { useSplitterDrag } from '../widgets/Splitter';
import { FontIcon } from '../icons';
const HeaderDiv = styled.div`
display: flex;
flex-wrap: nowrap;
`;
const LabelDiv = styled.div`
@ -15,13 +17,22 @@ const LabelDiv = styled.div`
// padding-left: 2px;
padding: 2px;
margin: auto;
white-space: nowrap;
`;
const IconWrapper = styled.span`
margin-left: 3px;
`;
export default function ColumnHeaderControl({ column, setSort, order }) {
const ResizeHandle = styled.div`
background-color: #ccc;
width: 2px;
cursor: col-resize;
z-index: 1;
`;
export default function ColumnHeaderControl({ column, setSort, onResize, order }) {
const onResizeDown = useSplitterDrag('clientX', onResize);
return (
<HeaderDiv>
<LabelDiv>
@ -43,6 +54,7 @@ export default function ColumnHeaderControl({ column, setSort, order }) {
<DropDownMenuItem onClick={() => setSort('DESC')}>Sort descending</DropDownMenuItem>
</DropDownButton>
)}
<ResizeHandle className="resizeHandleControl" onMouseDown={onResizeDown} />
</HeaderDiv>
);
}

View File

@ -6,6 +6,7 @@ import { SequenceIcon, ForeignKeyIcon } from '../icons';
const Label = styled.span`
font-weight: ${props => (props.notNull ? 'bold' : 'normal')};
white-space: nowrap;
`;
/** @param column {import('@dbgate/datalib').DisplayColumn|import('@dbgate/types').ColumnInfo} */

View File

@ -509,7 +509,9 @@ export default function DataGridCore(props) {
function handleGridMouseDown(event) {
if (event.target.closest('.buttonLike')) return;
if (event.target.closest('.resizeHandleControl')) return;
if (event.target.closest('input')) return;
// event.target.closest('table').focus();
event.preventDefault();
// @ts-ignore
@ -1044,6 +1046,7 @@ export default function DataGridCore(props) {
column={col}
setSort={display.sortable ? (order) => display.setSort(col.uniqueName, order) : null}
order={display.getSortOrder(col.uniqueName)}
onResize={(diff) => display.resizeColumn(col.uniqueName, col.widthNumber, diff)}
/>
</TableHeaderCell>
))}

View File

@ -1,8 +1,9 @@
import _ from 'lodash';
import { SeriesSizes } from './SeriesSizes';
import { CellAddress } from './selection';
import { GridDisplay } from '@dbgate/datalib';
export function countColumnSizes(loadedRows, columns, containerWidth, display) {
export function countColumnSizes(loadedRows, columns, containerWidth, display: GridDisplay) {
const columnSizes = new SeriesSizes();
if (!loadedRows || !columns) return columnSizes;
@ -25,12 +26,17 @@ export function countColumnSizes(loadedRows, columns, containerWidth, display) {
//this.columnSizes.PutSizeOverride(col, this.columns[col].Name.length * 8);
const column = columns[colIndex];
if (display.config.columnWidths[column.uniqueName]) {
columnSizes.putSizeOverride(colIndex, display.config.columnWidths[column.uniqueName]);
continue;
}
// if (column.columnClientObject != null && column.columnClientObject.notNull) context.font = "bold 14px Helvetica";
// else context.font = "14px Helvetica";
context.font = 'bold 14px Helvetica';
let text = column.headerText;
let headerWidth = context.measureText(text).width + 64;
const text = column.headerText;
const headerWidth = context.measureText(text).width + 64;
// if (column.columnClientObject != null && column.columnClientObject.icon != null) headerWidth += 16;
// if (this.getFilterOnColumn(column.uniquePath)) headerWidth += 16;
@ -47,9 +53,14 @@ export function countColumnSizes(loadedRows, columns, containerWidth, display) {
context.font = '14px Helvetica';
for (let row of loadedRows.slice(0, 20)) {
for (let colIndex = 0; colIndex < columns.length; colIndex++) {
let uqName = columns[colIndex].uniqueName;
let text = row[uqName];
let width = context.measureText(text).width + 8;
const uqName = columns[colIndex].uniqueName;
if (display.config.columnWidths[uqName]) {
continue;
}
const text = row[uqName];
const width = context.measureText(text).width + 8;
// console.log('colName', colName, text, width);
columnSizes.putSizeOverride(colIndex, width);
// let colName = this.columns[colIndex].uniquePath;
@ -103,6 +114,7 @@ export function countVisibleRealColumns(columnSizes, firstVisibleColumnScrollInd
realColumns.push({
...col,
colIndex,
widthNumber,
widthPx: `${widthNumber}px`,
});
}