mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-02 02:03:58 +00:00
grid sorting
This commit is contained in:
@@ -9,6 +9,10 @@ export interface GridConfigColumns {
|
|||||||
|
|
||||||
export interface GridConfig extends GridConfigColumns {
|
export interface GridConfig extends GridConfigColumns {
|
||||||
filters: { [uniqueName: string]: string };
|
filters: { [uniqueName: string]: string };
|
||||||
|
sort: {
|
||||||
|
uniqueName: string;
|
||||||
|
order: 'ASC' | 'DESC';
|
||||||
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GridCache {
|
export interface GridCache {
|
||||||
@@ -22,6 +26,7 @@ export function createGridConfig(): GridConfig {
|
|||||||
expandedColumns: [],
|
expandedColumns: [],
|
||||||
addedColumns: [],
|
addedColumns: [],
|
||||||
filters: {},
|
filters: {},
|
||||||
|
sort: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -307,6 +307,20 @@ export abstract class GridDisplay {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applySortOnSelect(select: Select, displayedColumnInfo: DisplayedColumnInfo) {
|
||||||
|
if (this.config.sort?.length > 0) {
|
||||||
|
select.orderBy = this.config.sort
|
||||||
|
.map(col => ({ ...col, dispInfo: displayedColumnInfo[col.uniqueName] }))
|
||||||
|
.filter(col => col.dispInfo)
|
||||||
|
.map(col => ({
|
||||||
|
exprType: 'column',
|
||||||
|
columnName: col.dispInfo.columnName,
|
||||||
|
direction: col.order,
|
||||||
|
source: { alias: col.dispInfo.sourceAlias },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getDisplayColumns(table: TableInfo, parentPath: string[]) {
|
getDisplayColumns(table: TableInfo, parentPath: string[]) {
|
||||||
return (
|
return (
|
||||||
table?.columns
|
table?.columns
|
||||||
@@ -350,6 +364,18 @@ export abstract class GridDisplay {
|
|||||||
this.reload();
|
this.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setSort(uniqueName, order) {
|
||||||
|
this.setConfig({
|
||||||
|
...this.config,
|
||||||
|
sort: [{ uniqueName, order }],
|
||||||
|
});
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
getSortOrder(uniqueName) {
|
||||||
|
return this.config.sort.find(x => x.uniqueName == uniqueName)?.order;
|
||||||
|
}
|
||||||
|
|
||||||
get filterCount() {
|
get filterCount() {
|
||||||
return _.compact(_.values(this.config.filters)).length;
|
return _.compact(_.values(this.config.filters)).length;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ export class TableGridDisplay extends GridDisplay {
|
|||||||
this.addHintsToSelect(select)
|
this.addHintsToSelect(select)
|
||||||
);
|
);
|
||||||
this.applyFilterOnSelect(select, displayedColumnInfo);
|
this.applyFilterOnSelect(select, displayedColumnInfo);
|
||||||
|
this.applySortOnSelect(select, displayedColumnInfo);
|
||||||
if (action == 'loadRequired') {
|
if (action == 'loadRequired') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ 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 { FontIcon } from '../icons';
|
||||||
|
|
||||||
const HeaderDiv = styled.div`
|
const HeaderDiv = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -15,15 +16,29 @@ const LabelDiv = styled.div`
|
|||||||
margin: auto;
|
margin: auto;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function ColumnHeaderControl({ column }) {
|
const IconWrapper = styled.span`
|
||||||
|
margin-left: 3px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default function ColumnHeaderControl({ column, setSort, order }) {
|
||||||
return (
|
return (
|
||||||
<HeaderDiv>
|
<HeaderDiv>
|
||||||
<LabelDiv>
|
<LabelDiv>
|
||||||
<ColumnLabel {...column} />
|
<ColumnLabel {...column} />
|
||||||
|
{order == 'ASC' && (
|
||||||
|
<IconWrapper>
|
||||||
|
<FontIcon icon="fas fa-sort-alpha-down green" />
|
||||||
|
</IconWrapper>
|
||||||
|
)}
|
||||||
|
{order == 'DESC' && (
|
||||||
|
<IconWrapper>
|
||||||
|
<FontIcon icon="fas fa-sort-alpha-down-alt green" />
|
||||||
|
</IconWrapper>
|
||||||
|
)}
|
||||||
</LabelDiv>
|
</LabelDiv>
|
||||||
<DropDownButton>
|
<DropDownButton>
|
||||||
<DropDownMenuItem onClick={() => {}}>Sort ascending</DropDownMenuItem>
|
<DropDownMenuItem onClick={() => setSort('ASC')}>Sort ascending</DropDownMenuItem>
|
||||||
<DropDownMenuItem onClick={() => {}}>Sort descending</DropDownMenuItem>
|
<DropDownMenuItem onClick={() => setSort('DESC')}>Sort descending</DropDownMenuItem>
|
||||||
</DropDownButton>
|
</DropDownButton>
|
||||||
</HeaderDiv>
|
</HeaderDiv>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -845,7 +845,11 @@ export default function DataGridCore(props) {
|
|||||||
key={col.uniqueName}
|
key={col.uniqueName}
|
||||||
style={{ width: col.widthPx, minWidth: col.widthPx, maxWidth: col.widthPx }}
|
style={{ width: col.widthPx, minWidth: col.widthPx, maxWidth: col.widthPx }}
|
||||||
>
|
>
|
||||||
<ColumnHeaderControl column={col} />
|
<ColumnHeaderControl
|
||||||
|
column={col}
|
||||||
|
setSort={order => display.setSort(col.uniqueName, order)}
|
||||||
|
order={display.getSortOrder(col.uniqueName)}
|
||||||
|
/>
|
||||||
</TableHeaderCell>
|
</TableHeaderCell>
|
||||||
))}
|
))}
|
||||||
</TableHeaderRow>
|
</TableHeaderRow>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ export function countColumnSizes(loadedRows, columns, containerWidth, display) {
|
|||||||
context.font = 'bold 14px Helvetica';
|
context.font = 'bold 14px Helvetica';
|
||||||
|
|
||||||
let text = column.headerText;
|
let text = column.headerText;
|
||||||
let headerWidth = context.measureText(text).width + 50;
|
let 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;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export function FontIcon({ icon, ...props }) {
|
|||||||
|
|
||||||
if (_.includes(parts, 'spin')) className += ' fa-spin';
|
if (_.includes(parts, 'spin')) className += ' fa-spin';
|
||||||
|
|
||||||
const style = props.style || {};
|
const style = { ...props.style };
|
||||||
|
|
||||||
const last = parts[parts.length - 1];
|
const last = parts[parts.length - 1];
|
||||||
if (last && last != 'spin') {
|
if (last && last != 'spin') {
|
||||||
|
|||||||
Reference in New Issue
Block a user