diff --git a/packages/datalib/src/PerspectiveConfig.ts b/packages/datalib/src/PerspectiveConfig.ts index e17c63c3c..8c0dd3932 100644 --- a/packages/datalib/src/PerspectiveConfig.ts +++ b/packages/datalib/src/PerspectiveConfig.ts @@ -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: [], }; } diff --git a/packages/datalib/src/PerspectiveDataLoader.ts b/packages/datalib/src/PerspectiveDataLoader.ts index 577eb3d9e..be5fd7c40 100644 --- a/packages/datalib/src/PerspectiveDataLoader.ts +++ b/packages/datalib/src/PerspectiveDataLoader.ts @@ -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 }, }, diff --git a/packages/datalib/src/PerspectiveDataProvider.ts b/packages/datalib/src/PerspectiveDataProvider.ts index 5ac04679f..d11e9b45c 100644 --- a/packages/datalib/src/PerspectiveDataProvider.ts +++ b/packages/datalib/src/PerspectiveDataProvider.ts @@ -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; diff --git a/packages/datalib/src/PerspectiveTreeNode.ts b/packages/datalib/src/PerspectiveTreeNode.ts index ab8346eec..4855f4a92 100644 --- a/packages/datalib/src/PerspectiveTreeNode.ts +++ b/packages/datalib/src/PerspectiveTreeNode.ts @@ -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(), }; } diff --git a/packages/web/src/perspectives/PerspectiveHeaderControl.svelte b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte new file mode 100644 index 000000000..ed8470866 --- /dev/null +++ b/packages/web/src/perspectives/PerspectiveHeaderControl.svelte @@ -0,0 +1,184 @@ + + +{#if column.isVisible(columnLevel)} + (mouseIn = true)} + on:mouseleave={() => (mouseIn = false)} + > +
+
+ {column.title} +
+ + {#if order == 'ASC'} + + + {#if orderIndex >= 0} + {orderIndex + 1} + {/if} + + {/if} + {#if order == 'DESC'} + + + {#if orderIndex >= 0} + {orderIndex + 1} + {/if} + + {/if} +
+ + {#if mouseIn} + + {/if} + +{/if} +{#if column.showParent(columnLevel)} + {column.getParentName(columnLevel)} +{/if} + + diff --git a/packages/web/src/perspectives/PerspectiveTable.svelte b/packages/web/src/perspectives/PerspectiveTable.svelte index cd7201f7b..ede92f9d0 100644 --- a/packages/web/src/perspectives/PerspectiveTable.svelte +++ b/packages/web/src/perspectives/PerspectiveTable.svelte @@ -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} {#each display.columns as column} - {#if column.isVisible(columnLevel)} - {column.title} - {/if} - {#if column.showParent(columnLevel)} - {column.getParentName(columnLevel)} - {/if} + {/each} {/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; } diff --git a/packages/web/src/perspectives/PerspectiveView.svelte b/packages/web/src/perspectives/PerspectiveView.svelte index 3efee0500..50e3ecb47 100644 --- a/packages/web/src/perspectives/PerspectiveView.svelte +++ b/packages/web/src/perspectives/PerspectiveView.svelte @@ -79,7 +79,7 @@ - + diff --git a/packages/web/src/tabs/PerspectiveTab.svelte b/packages/web/src/tabs/PerspectiveTab.svelte index 8b34d0455..fb136fad0 100644 --- a/packages/web/src/tabs/PerspectiveTab.svelte +++ b/packages/web/src/tabs/PerspectiveTab.svelte @@ -12,6 +12,8 @@ testEnabled: () => getCurrentEditor() != null, onClick: () => getCurrentEditor().refresh(), }); + + export const allowAddToFavorites = props => true;