mirror of
https://github.com/dbgate/dbgate
synced 2024-11-07 20:26:23 +00:00
columns resize
This commit is contained in:
parent
836db096a9
commit
a41538b452
@ -19,6 +19,7 @@ export interface GridReferenceDefinition {
|
|||||||
export interface GridConfig extends GridConfigColumns {
|
export interface GridConfig extends GridConfigColumns {
|
||||||
filters: { [uniqueName: string]: string };
|
filters: { [uniqueName: string]: string };
|
||||||
focusedColumn?: string;
|
focusedColumn?: string;
|
||||||
|
columnWidths: { [uniqueName: string]: number };
|
||||||
sort: {
|
sort: {
|
||||||
uniqueName: string;
|
uniqueName: string;
|
||||||
order: 'ASC' | 'DESC';
|
order: 'ASC' | 'DESC';
|
||||||
@ -37,6 +38,7 @@ export function createGridConfig(): GridConfig {
|
|||||||
expandedColumns: [],
|
expandedColumns: [],
|
||||||
addedColumns: [],
|
addedColumns: [],
|
||||||
filters: {},
|
filters: {},
|
||||||
|
columnWidths: {},
|
||||||
sort: [],
|
sort: [],
|
||||||
focusedColumn: null,
|
focusedColumn: null,
|
||||||
};
|
};
|
||||||
|
@ -38,12 +38,13 @@ export function combineReferenceActions(a: ReferenceActionResult, b: ReferenceAc
|
|||||||
return 'noAction';
|
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 {
|
export abstract class GridDisplay {
|
||||||
constructor(
|
constructor(
|
||||||
public config: GridConfig,
|
public config: GridConfig,
|
||||||
protected setConfig: (config: GridConfig) => void,
|
protected setConfig: ChangeConfigFunc,
|
||||||
public cache: GridCache,
|
public cache: GridCache,
|
||||||
protected setCache: ChangeCacheFunc,
|
protected setCache: ChangeCacheFunc,
|
||||||
public driver?: EngineDriver
|
public driver?: EngineDriver
|
||||||
@ -67,10 +68,10 @@ export abstract class GridDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
focusColumn(uniqueName: string) {
|
focusColumn(uniqueName: string) {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
focusedColumn: uniqueName,
|
focusedColumn: uniqueName,
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
get focusedColumn() {
|
get focusedColumn() {
|
||||||
@ -96,30 +97,30 @@ export abstract class GridDisplay {
|
|||||||
includeInColumnSet(field: keyof GridConfigColumns, uniqueName: string, isIncluded: boolean) {
|
includeInColumnSet(field: keyof GridConfigColumns, uniqueName: string, isIncluded: boolean) {
|
||||||
// console.log('includeInColumnSet', field, uniqueName, isIncluded);
|
// console.log('includeInColumnSet', field, uniqueName, isIncluded);
|
||||||
if (isIncluded) {
|
if (isIncluded) {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
[field]: [...(this.config[field] || []), uniqueName],
|
[field]: [...(cfg[field] || []), uniqueName],
|
||||||
});
|
}));
|
||||||
} else {
|
} else {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
[field]: (this.config[field] || []).filter((x) => x != uniqueName),
|
[field]: (cfg[field] || []).filter((x) => x != uniqueName),
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showAllColumns() {
|
showAllColumns() {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
hiddenColumns: [],
|
hiddenColumns: [],
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
hideAllColumns() {
|
hideAllColumns() {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
hiddenColumns: this.columns.map((x) => x.uniqueName),
|
hiddenColumns: this.columns.map((x) => x.uniqueName),
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
get hiddenColumnIndexes() {
|
get hiddenColumnIndexes() {
|
||||||
@ -203,21 +204,21 @@ export abstract class GridDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
setFilter(uniqueName, value) {
|
setFilter(uniqueName, value) {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
filters: {
|
filters: {
|
||||||
...this.config.filters,
|
...cfg.filters,
|
||||||
[uniqueName]: value,
|
[uniqueName]: value,
|
||||||
},
|
},
|
||||||
});
|
}));
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
setSort(uniqueName, order) {
|
setSort(uniqueName, order) {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
sort: [{ uniqueName, order }],
|
sort: [{ uniqueName, order }],
|
||||||
});
|
}));
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,10 +231,10 @@ export abstract class GridDisplay {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearFilters() {
|
clearFilters() {
|
||||||
this.setConfig({
|
this.setConfig((cfg) => ({
|
||||||
...this.config,
|
...cfg,
|
||||||
filters: {},
|
filters: {},
|
||||||
});
|
}));
|
||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,6 +315,23 @@ export abstract class GridDisplay {
|
|||||||
return sql;
|
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() {
|
getCountQuery() {
|
||||||
const select = this.createSelect();
|
const select = this.createSelect();
|
||||||
select.columns = [
|
select.columns = [
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { GridDisplay, ChangeCacheFunc } from './GridDisplay';
|
import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay';
|
||||||
import { QueryResultColumn } from '@dbgate/types';
|
import { QueryResultColumn } from '@dbgate/types';
|
||||||
import { GridConfig, GridCache } from './GridConfig';
|
import { GridConfig, GridCache } from './GridConfig';
|
||||||
|
|
||||||
@ -7,7 +7,7 @@ export class JslGridDisplay extends GridDisplay {
|
|||||||
jslid,
|
jslid,
|
||||||
columns: QueryResultColumn[],
|
columns: QueryResultColumn[],
|
||||||
config: GridConfig,
|
config: GridConfig,
|
||||||
setConfig: (config: GridConfig) => void,
|
setConfig: ChangeConfigFunc,
|
||||||
cache: GridCache,
|
cache: GridCache,
|
||||||
setCache: ChangeCacheFunc
|
setCache: ChangeCacheFunc
|
||||||
) {
|
) {
|
||||||
|
@ -6,6 +6,7 @@ import {
|
|||||||
DisplayColumn,
|
DisplayColumn,
|
||||||
ReferenceActionResult,
|
ReferenceActionResult,
|
||||||
DisplayedColumnInfo,
|
DisplayedColumnInfo,
|
||||||
|
ChangeConfigFunc,
|
||||||
} from './GridDisplay';
|
} from './GridDisplay';
|
||||||
import { TableInfo, EngineDriver, ViewInfo, ColumnInfo, NamedObjectInfo } from '@dbgate/types';
|
import { TableInfo, EngineDriver, ViewInfo, ColumnInfo, NamedObjectInfo } from '@dbgate/types';
|
||||||
import { GridConfig, GridCache, createGridCache } from './GridConfig';
|
import { GridConfig, GridCache, createGridCache } from './GridConfig';
|
||||||
@ -19,7 +20,7 @@ export class TableGridDisplay extends GridDisplay {
|
|||||||
public tableName: NamedObjectInfo,
|
public tableName: NamedObjectInfo,
|
||||||
driver: EngineDriver,
|
driver: EngineDriver,
|
||||||
config: GridConfig,
|
config: GridConfig,
|
||||||
setConfig: (config: GridConfig) => void,
|
setConfig: ChangeConfigFunc,
|
||||||
cache: GridCache,
|
cache: GridCache,
|
||||||
setCache: ChangeCacheFunc,
|
setCache: ChangeCacheFunc,
|
||||||
protected getTableInfo: ({ schemaName, pureName }) => Promise<TableInfo>
|
protected getTableInfo: ({ schemaName, pureName }) => Promise<TableInfo>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { GridDisplay, ChangeCacheFunc } from './GridDisplay';
|
import { GridDisplay, ChangeCacheFunc, ChangeConfigFunc } from './GridDisplay';
|
||||||
import { EngineDriver, ViewInfo, ColumnInfo } from '@dbgate/types';
|
import { EngineDriver, ViewInfo, ColumnInfo } from '@dbgate/types';
|
||||||
import { GridConfig, GridCache } from './GridConfig';
|
import { GridConfig, GridCache } from './GridConfig';
|
||||||
|
|
||||||
@ -8,7 +8,7 @@ export class ViewGridDisplay extends GridDisplay {
|
|||||||
public view: ViewInfo,
|
public view: ViewInfo,
|
||||||
driver: EngineDriver,
|
driver: EngineDriver,
|
||||||
config: GridConfig,
|
config: GridConfig,
|
||||||
setConfig: (config: GridConfig) => void,
|
setConfig: ChangeConfigFunc,
|
||||||
cache: GridCache,
|
cache: GridCache,
|
||||||
setCache: ChangeCacheFunc
|
setCache: ChangeCacheFunc
|
||||||
) {
|
) {
|
||||||
|
@ -3,10 +3,12 @@ import styled from 'styled-components';
|
|||||||
import ColumnLabel from './ColumnLabel';
|
import ColumnLabel from './ColumnLabel';
|
||||||
import DropDownButton from '../widgets/DropDownButton';
|
import DropDownButton from '../widgets/DropDownButton';
|
||||||
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
import { DropDownMenuItem } from '../modals/DropDownMenu';
|
||||||
|
import { useSplitterDrag } from '../widgets/Splitter';
|
||||||
import { FontIcon } from '../icons';
|
import { FontIcon } from '../icons';
|
||||||
|
|
||||||
const HeaderDiv = styled.div`
|
const HeaderDiv = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const LabelDiv = styled.div`
|
const LabelDiv = styled.div`
|
||||||
@ -15,13 +17,22 @@ const LabelDiv = styled.div`
|
|||||||
// padding-left: 2px;
|
// padding-left: 2px;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const IconWrapper = styled.span`
|
const IconWrapper = styled.span`
|
||||||
margin-left: 3px;
|
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 (
|
return (
|
||||||
<HeaderDiv>
|
<HeaderDiv>
|
||||||
<LabelDiv>
|
<LabelDiv>
|
||||||
@ -43,6 +54,7 @@ export default function ColumnHeaderControl({ column, setSort, order }) {
|
|||||||
<DropDownMenuItem onClick={() => setSort('DESC')}>Sort descending</DropDownMenuItem>
|
<DropDownMenuItem onClick={() => setSort('DESC')}>Sort descending</DropDownMenuItem>
|
||||||
</DropDownButton>
|
</DropDownButton>
|
||||||
)}
|
)}
|
||||||
|
<ResizeHandle className="resizeHandleControl" onMouseDown={onResizeDown} />
|
||||||
</HeaderDiv>
|
</HeaderDiv>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import { SequenceIcon, ForeignKeyIcon } from '../icons';
|
|||||||
|
|
||||||
const Label = styled.span`
|
const Label = styled.span`
|
||||||
font-weight: ${props => (props.notNull ? 'bold' : 'normal')};
|
font-weight: ${props => (props.notNull ? 'bold' : 'normal')};
|
||||||
|
white-space: nowrap;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
/** @param column {import('@dbgate/datalib').DisplayColumn|import('@dbgate/types').ColumnInfo} */
|
/** @param column {import('@dbgate/datalib').DisplayColumn|import('@dbgate/types').ColumnInfo} */
|
||||||
|
@ -509,7 +509,9 @@ export default function DataGridCore(props) {
|
|||||||
|
|
||||||
function handleGridMouseDown(event) {
|
function handleGridMouseDown(event) {
|
||||||
if (event.target.closest('.buttonLike')) return;
|
if (event.target.closest('.buttonLike')) return;
|
||||||
|
if (event.target.closest('.resizeHandleControl')) return;
|
||||||
if (event.target.closest('input')) return;
|
if (event.target.closest('input')) return;
|
||||||
|
|
||||||
// event.target.closest('table').focus();
|
// event.target.closest('table').focus();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
@ -1044,6 +1046,7 @@ export default function DataGridCore(props) {
|
|||||||
column={col}
|
column={col}
|
||||||
setSort={display.sortable ? (order) => display.setSort(col.uniqueName, order) : null}
|
setSort={display.sortable ? (order) => display.setSort(col.uniqueName, order) : null}
|
||||||
order={display.getSortOrder(col.uniqueName)}
|
order={display.getSortOrder(col.uniqueName)}
|
||||||
|
onResize={(diff) => display.resizeColumn(col.uniqueName, col.widthNumber, diff)}
|
||||||
/>
|
/>
|
||||||
</TableHeaderCell>
|
</TableHeaderCell>
|
||||||
))}
|
))}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { SeriesSizes } from './SeriesSizes';
|
import { SeriesSizes } from './SeriesSizes';
|
||||||
import { CellAddress } from './selection';
|
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();
|
const columnSizes = new SeriesSizes();
|
||||||
if (!loadedRows || !columns) return columnSizes;
|
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);
|
//this.columnSizes.PutSizeOverride(col, this.columns[col].Name.length * 8);
|
||||||
const column = columns[colIndex];
|
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";
|
// if (column.columnClientObject != null && column.columnClientObject.notNull) context.font = "bold 14px Helvetica";
|
||||||
// else context.font = "14px Helvetica";
|
// else context.font = "14px Helvetica";
|
||||||
context.font = 'bold 14px Helvetica';
|
context.font = 'bold 14px Helvetica';
|
||||||
|
|
||||||
let text = column.headerText;
|
const text = column.headerText;
|
||||||
let headerWidth = context.measureText(text).width + 64;
|
const headerWidth = context.measureText(text).width + 64;
|
||||||
|
|
||||||
// if (column.columnClientObject != null && column.columnClientObject.icon != null) headerWidth += 16;
|
// if (column.columnClientObject != null && column.columnClientObject.icon != null) headerWidth += 16;
|
||||||
// if (this.getFilterOnColumn(column.uniquePath)) headerWidth += 16;
|
// if (this.getFilterOnColumn(column.uniquePath)) headerWidth += 16;
|
||||||
@ -47,9 +53,14 @@ export function countColumnSizes(loadedRows, columns, containerWidth, display) {
|
|||||||
context.font = '14px Helvetica';
|
context.font = '14px Helvetica';
|
||||||
for (let row of loadedRows.slice(0, 20)) {
|
for (let row of loadedRows.slice(0, 20)) {
|
||||||
for (let colIndex = 0; colIndex < columns.length; colIndex++) {
|
for (let colIndex = 0; colIndex < columns.length; colIndex++) {
|
||||||
let uqName = columns[colIndex].uniqueName;
|
const uqName = columns[colIndex].uniqueName;
|
||||||
let text = row[uqName];
|
|
||||||
let width = context.measureText(text).width + 8;
|
if (display.config.columnWidths[uqName]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const text = row[uqName];
|
||||||
|
const width = context.measureText(text).width + 8;
|
||||||
// console.log('colName', colName, text, width);
|
// console.log('colName', colName, text, width);
|
||||||
columnSizes.putSizeOverride(colIndex, width);
|
columnSizes.putSizeOverride(colIndex, width);
|
||||||
// let colName = this.columns[colIndex].uniquePath;
|
// let colName = this.columns[colIndex].uniquePath;
|
||||||
@ -103,6 +114,7 @@ export function countVisibleRealColumns(columnSizes, firstVisibleColumnScrollInd
|
|||||||
realColumns.push({
|
realColumns.push({
|
||||||
...col,
|
...col,
|
||||||
colIndex,
|
colIndex,
|
||||||
|
widthNumber,
|
||||||
widthPx: `${widthNumber}px`,
|
widthPx: `${widthNumber}px`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user