perspective sorting

This commit is contained in:
Jan Prochazka
2022-07-31 12:10:56 +02:00
parent 7694864fe7
commit 452dba7f32
8 changed files with 230 additions and 32 deletions

View File

@@ -6,6 +6,10 @@ export interface PerspectiveConfigColumns {
export interface PerspectiveConfig extends PerspectiveConfigColumns {
filters: { [uniqueName: string]: string };
sort: {
uniqueName: string;
order: 'ASC' | 'DESC';
}[];
}
export function createPerspectiveConfig(): PerspectiveConfig {
@@ -14,6 +18,7 @@ export function createPerspectiveConfig(): PerspectiveConfig {
checkedColumns: [],
uncheckedColumns: [],
filters: {},
sort: [],
};
}

View File

@@ -109,10 +109,10 @@ export class PerspectiveDataLoader {
},
})),
selectAll: !dataColumns,
orderBy: orderBy?.map(columnName => ({
orderBy: orderBy?.map(({ columnName, order }) => ({
exprType: 'column',
columnName,
direction: 'ASC',
direction: order,
source: {
name: { schemaName, pureName },
},

View File

@@ -16,7 +16,10 @@ export interface PerspectiveDataLoadProps {
schemaName: string;
pureName: string;
dataColumns: string[];
orderBy: string[];
orderBy: {
columnName: string;
order: 'ASC' | 'DESC';
}[];
bindingColumns?: string[];
bindingValues?: any[][];
range?: RangeDefinition;

View File

@@ -95,6 +95,9 @@ export abstract class PerspectiveTreeNode {
get filterType(): FilterType {
return 'string';
}
get columnName() {
return null;
}
getChildMatchColumns() {
return [];
@@ -181,6 +184,25 @@ export abstract class PerspectiveTreeNode {
conditions,
};
}
getOrderBy(table: TableInfo): PerspectiveDataLoadProps['orderBy'] {
const res = _compact(
this.childNodes.map(node => {
const sort = this.config?.sort?.find(x => x.uniqueName == node.uniqueName);
if (sort) {
return {
columnName: node.columnName,
order: sort.order,
};
}
})
);
return res.length > 0
? res
: table?.primaryKey?.columns.map(x => ({ columnName: x.columnName, order: 'ASC' })) || [
{ columnName: table?.columns[0].columnName, order: 'ASC' },
];
}
}
export class PerspectiveTableColumnNode extends PerspectiveTreeNode {
@@ -237,7 +259,7 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode {
),
dataColumns: this.getDataLoadColumns(),
databaseConfig: this.databaseConfig,
orderBy: this.refTable?.primaryKey?.columns.map(x => x.columnName) || [this.refTable.columns[0].columnName],
orderBy: this.getOrderBy(this.refTable),
condition: this.getChildrenCondition(),
};
}
@@ -252,6 +274,10 @@ export class PerspectiveTableColumnNode extends PerspectiveTreeNode {
return this.column.columnName;
}
get columnName() {
return this.column.columnName;
}
get fieldName() {
return this.codeName + 'Ref';
}
@@ -322,7 +348,7 @@ export class PerspectiveTableNode extends PerspectiveTreeNode {
pureName: this.table.pureName,
dataColumns: this.getDataLoadColumns(),
databaseConfig: this.databaseConfig,
orderBy: this.table.primaryKey?.columns.map(x => x.columnName) || [this.table.columns[0].columnName],
orderBy: this.getOrderBy(this.table),
condition: this.getChildrenCondition(),
};
}
@@ -397,7 +423,7 @@ export class PerspectiveTableReferenceNode extends PerspectiveTableNode {
),
dataColumns: this.getDataLoadColumns(),
databaseConfig: this.databaseConfig,
orderBy: this.table.primaryKey?.columns.map(x => x.columnName) || [this.table.columns[0].columnName],
orderBy: this.getOrderBy(this.table),
condition: this.getChildrenCondition(),
};
}

View File

@@ -0,0 +1,184 @@
<script lang="ts">
import { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveDisplayColumn } from 'dbgate-datalib';
import _ from 'lodash';
import DropDownButton from '../buttons/DropDownButton.svelte';
import FontIcon from '../icons/FontIcon.svelte';
export let label;
export let column: PerspectiveDisplayColumn;
export let columnLevel;
export let config: PerspectiveConfig;
export let setConfig: ChangePerspectiveConfigFunc;
// export let setSort = undefined;
// export let addToSort = undefined;
// export let clearSort = undefined;
// export let grouping = undefined;
// export let order = undefined;
// export let orderIndex = undefined;
// export let isSortDefined = false;
let mouseIn;
$: uniqueName = column.dataNode.uniqueName;
// $: console.log('CFG', config);
$: order = config.sort?.find(x => x.uniqueName == uniqueName)?.order;
$: orderIndex = config.sort?.length > 1 ? _.findIndex(config.sort, x => x.uniqueName == uniqueName) : -1;
$: isSortDefined = config.sort?.length > 0;
const setSort = order => {
setConfig(
cfg => ({
...cfg,
sort: [{ uniqueName, order }],
}),
true
);
};
const addToSort = order => {
setConfig(
cfg => ({
...cfg,
sort: [...(cfg.sort || []), { uniqueName, order }],
}),
true
);
};
const clearSort = () => {
setConfig(
cfg => ({
...cfg,
sort: [],
}),
true
);
};
// display.setSort(col.uniqueName, order)
// addToSort={display.sortable ? order => display.addToSort(col.uniqueName, order) : null}
// order={display.sortable ? display.getSortOrder(col.uniqueName) : null}
// orderIndex={display.sortable ? display.getSortOrderIndex(col.uniqueName) : -1}
// isSortDefined={display.sortable ? display.isSortDefined() : false}
// clearSort={display.sortable ? () => display.clearSort() : null}
function getMenu() {
return [
{ onClick: () => setSort('ASC'), text: 'Sort ascending' },
{ onClick: () => setSort('DESC'), text: 'Sort descending' },
isSortDefined && !order && { onClick: () => addToSort('ASC'), text: 'Add to sort - ascending' },
isSortDefined && !order && { onClick: () => addToSort('DESC'), text: 'Add to sort - descending' },
order && { onClick: () => clearSort(), text: 'Clear sort criteria' },
];
}
</script>
{#if column.isVisible(columnLevel)}
<th
rowspan={column.rowSpan}
class="columnHeader"
on:mouseenter={() => (mouseIn = true)}
on:mouseleave={() => (mouseIn = false)}
>
<div class="wrap">
<div class="label">
{column.title}
</div>
{#if order == 'ASC'}
<span class="icon">
<FontIcon icon="img sort-asc" />
{#if orderIndex >= 0}
<span class="color-icon-green order-index">{orderIndex + 1}</span>
{/if}
</span>
{/if}
{#if order == 'DESC'}
<span class="icon">
<FontIcon icon="img sort-desc" />
{#if orderIndex >= 0}
<span class="color-icon-green order-index">{orderIndex + 1}</span>
{/if}
</span>
{/if}
</div>
{#if mouseIn}
<div class="menuButton">
<DropDownButton menu={getMenu} narrow />
</div>
{/if}
</th>
{/if}
{#if column.showParent(columnLevel)}
<th colspan={column.getColSpan(columnLevel)} class="tableHeader">{column.getParentName(columnLevel)}</th>
{/if}
<style>
.wrap {
display: flex;
}
.menuButton {
position: absolute;
right: 0;
bottom: 0;
}
.label {
flex-wrap: nowrap;
}
.order-index {
font-size: 10pt;
margin-left: -3px;
margin-right: 2px;
top: -1px;
position: relative;
}
.label {
flex: 1;
min-width: 10px;
padding: 2px;
margin: auto;
white-space: nowrap;
}
.icon {
margin-left: 3px;
align-self: center;
font-size: 18px;
}
/* .resizer {
background-color: var(--theme-border);
width: 2px;
cursor: col-resize;
z-index: 1;
} */
.grouping {
color: var(--theme-font-alt);
white-space: nowrap;
}
.data-type {
color: var(--theme-font-3);
}
th {
/* border: 1px solid var(--theme-border); */
text-align: left;
padding: 2px;
margin: 0;
background-color: var(--theme-bg-1);
overflow: hidden;
vertical-align: center;
z-index: 100;
font-weight: normal;
border-bottom: 1px solid var(--theme-border);
border-right: 1px solid var(--theme-border);
}
th.tableHeader {
font-weight: bold;
}
th.columnHeader {
position: relative;
}
</style>

View File

@@ -28,12 +28,14 @@
import PerspectiveCell from './PerspectiveCell.svelte';
import DataGridCell from '../datagrid/DataGridCell.svelte';
import PerspectiveLoadingIndicator from './PerspectiveLoadingIndicator.svelte';
import PerspectiveHeaderControl from './PerspectiveHeaderControl.svelte';
const dbg = debug('dbgate:PerspectivaTable');
export const activator = createActivator('PerspectiveTable', true);
export let root: PerspectiveTreeNode;
export let loadedCounts;
export let config;
export let setConfig;
let dataRows;
@@ -159,12 +161,7 @@
{#each _.range(display.columnLevelCount) as columnLevel}
<tr>
{#each display.columns as column}
{#if column.isVisible(columnLevel)}
<th rowspan={column.rowSpan}>{column.title}</th>
{/if}
{#if column.showParent(columnLevel)}
<th colspan={column.getColSpan(columnLevel)} class="tableName">{column.getParentName(columnLevel)}</th>
{/if}
<PerspectiveHeaderControl label={column.title} {column} {columnLevel} {setConfig} {config} />
{/each}
</tr>
{/each}
@@ -266,25 +263,6 @@
z-index: 100;
}
th {
/* border: 1px solid var(--theme-border); */
text-align: left;
padding: 2px;
margin: 0;
background-color: var(--theme-bg-1);
overflow: hidden;
vertical-align: center;
z-index: 100;
font-weight: normal;
border-bottom: 1px solid var(--theme-border);
border-right: 1px solid var(--theme-border);
}
th.tableName {
font-weight: bold;
}
th.filter {
padding: 0;
}

View File

@@ -79,7 +79,7 @@
</div>
<svelte:fragment slot="2">
<PerspectiveTable {root} {loadedCounts} {setConfig} />
<PerspectiveTable {root} {loadedCounts} {config} {setConfig} />
</svelte:fragment>
</HorizontalSplitter>

View File

@@ -12,6 +12,8 @@
testEnabled: () => getCurrentEditor() != null,
onClick: () => getCurrentEditor().refresh(),
});
export const allowAddToFavorites = props => true;
</script>
<script lang="ts">