column manager

This commit is contained in:
Jan Prochazka
2021-03-06 09:31:02 +01:00
parent 8cf014efa4
commit 18e7171038
9 changed files with 148 additions and 2 deletions

View File

@@ -0,0 +1,28 @@
<script lang="ts">
import { filterName, GridDisplay } from 'dbgate-datalib';
import InlineButton from '../elements/InlineButton.svelte';
import ManagerInnerContainer from '../elements/ManagerInnerContainer.svelte';
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
import SearchInput from '../elements/SearchInput.svelte';
import ColumnManagerRow from './ColumnManagerRow.svelte';
export let managerSize;
export let display: GridDisplay;
let columnFilter;
</script>
<SearchBoxWrapper>
<SearchInput placeholder="Search columns" bind:value={columnFilter} />
<InlineButton on:click={() => display.hideAllColumns()}>Hide</InlineButton>
<InlineButton on:click={() => display.showAllColumns()}>Show</InlineButton>
</SearchBoxWrapper>
<ManagerInnerContainer width={managerSize}>
{#each display
.getColumns(columnFilter)
.filter(column => filterName(columnFilter, column.columnName)) as column (column.uniqueName)}
<ColumnManagerRow {display} {column} />
{/each}
</ManagerInnerContainer>

View File

@@ -0,0 +1,44 @@
<script lang="ts">
import { plusExpandIcon } from '../icons/expandIcons';
import FontIcon from '../icons/FontIcon.svelte';
import ColumnLabel from './ColumnLabel.svelte';
export let column;
export let display;
</script>
<div
class="row"
on:click={e => {
// @ts-ignore
if (e.target.closest('.expandColumnIcon')) return;
display.focusColumn(column.uniqueName);
}}
>
<span class="expandColumnIcon">
<FontIcon
icon={column.foreignKey ? plusExpandIcon(display.isExpandedColumn(column.uniqueName)) : 'icon invisible-box'}
on:click={() => display.toggleExpandedColumn(column.uniqueName)}
/>
</span>
<input
type="checkbox"
style={`margin-left: ${5 + (column.uniquePath.length - 1) * 10}px`}
checked={column.isChecked}
on:change={() => display.setColumnVisibility(column.uniquePath, !column.isChecked)}
/>
<ColumnLabel {...column} />
</div>
<style>
.row {
margin-left: 5px;
margin-right: 5px;
cursor: pointer;
white-space: nowrap;
}
.row:hover {
background: var(--theme-bg-hover);
}
</style>

View File

@@ -2,16 +2,20 @@
import HorizontalSplitter from '../elements/HorizontalSplitter.svelte';
import WidgetColumnBar from '../widgets/WidgetColumnBar.svelte';
import WidgetColumnBarItem from '../widgets/WidgetColumnBarItem.svelte';
import ColumnManager from './ColumnManager.svelte';
export let config;
export let gridCoreComponent;
export let showReferences = true;
let managerSize;
</script>
<HorizontalSplitter initialValue="300px">
<HorizontalSplitter initialValue="300px" bind:size={managerSize}>
<div class="left" slot="1">
<WidgetColumnBar>
<WidgetColumnBarItem title="Columns" name="columns" height={showReferences ? '40%' : '60%'} />
<ColumnManager {...$$props} {managerSize} />
</WidgetColumnBar>
</div>
<div slot="2">

View File

@@ -32,6 +32,7 @@
export let isInserted = false;
export let isDeleted = false;
export let isAutofillSelected = false;
export let isFocusedColumn = false;
$: value = (rowData || {})[col.uniqueName];
</script>
@@ -46,6 +47,7 @@
class:isInserted
class:isDeleted
class:isAutofillSelected
class:isFocusedColumn
style={`width:${col.width}px; min-width:${col.width}px; max-width:${col.width}px`}
>
{#if value == null}
@@ -107,6 +109,9 @@
outline: 3px solid var(--theme-bg-selected);
outline-offset: -3px;
}
td.isFocusedColumn {
background: var(--theme-bg-alt);
}
td.isModifiedRow {
background: var(--theme-bg-gold);
}

View File

@@ -46,6 +46,7 @@
import ColumnHeaderControl from './ColumnHeaderControl.svelte';
import DataGridRow from './DataGridRow.svelte';
import { getFilterType, getFilterValueExpression } from 'dbgate-filterparser';
import { tick } from 'svelte';
import {
cellIsSelected,
countColumnSizes,
@@ -135,6 +136,51 @@
}
}
$: {
if (display && display.focusedColumn) {
const invMap = _.invert(realColumnUniqueNames);
const colIndex = invMap[display.focusedColumn];
if (colIndex) {
scrollIntoView([null, colIndex]);
}
}
}
function scrollIntoView(cell) {
const [row, col] = cell;
if (row != null) {
let newRow = null;
const rowCount = grider.rowCount;
if (rowCount == 0) return;
if (row < firstVisibleRowScrollIndex) newRow = row;
else if (row + 1 >= firstVisibleRowScrollIndex + visibleRowCountLowerBound)
newRow = row - visibleRowCountLowerBound + 2;
if (newRow < 0) newRow = 0;
if (newRow >= rowCount) newRow = rowCount - 1;
if (newRow != null) {
firstVisibleRowScrollIndex = newRow;
domVerticalScroll.scroll(newRow);
}
}
if (col != null) {
if (col >= columnSizes.frozenCount) {
let newColumn = columnSizes.scrollInView(
firstVisibleColumnScrollIndex,
col - columnSizes.frozenCount,
gridScrollAreaWidth
);
firstVisibleColumnScrollIndex = newColumn;
domHorizontalScroll.scroll(newColumn);
}
}
}
function handleGridMouseDown(event) {
if (event.target.closest('.buttonLike')) return;
if (event.target.closest('.resizeHandleControl')) return;
@@ -341,6 +387,7 @@
{autofillSelectedCells}
selectedCells={filterCellsForRow(selectedCells, rowIndex)}
autofillMarkerCell={filterCellForRow(autofillMarkerCell, rowIndex)}
focusedColumn={display.focusedColumn}
{frameSelection}
/>
{/each}

View File

@@ -12,6 +12,7 @@
export let selectedCells = undefined;
export let autofillSelectedCells = undefined;
export let autofillMarkerCell = undefined;
export let focusedColumn = undefined;
$: rowData = grider.getRowData(rowIndex);
$: rowStatus = grider.getRowStatus(rowIndex);
@@ -36,6 +37,7 @@
isSelected={frameSelection ? false : cellIsSelected(rowIndex, col.colIndex, selectedCells)}
isFrameSelected={frameSelection ? cellIsSelected(rowIndex, col.colIndex, selectedCells) : false}
isAutofillSelected={cellIsSelected(rowIndex, col.colIndex, autofillSelectedCells)}
isFocusedColumn={col.uniqueName == focusedColumn}
/>
{/each}
</tr>

View File

@@ -15,7 +15,7 @@
export let isSplitter = true;
export let initialValue = undefined;
let size = 0;
export let size = 0;
let clientWidth;
$: size = computeSplitterSize(initialValue, clientWidth);

View File

@@ -0,0 +1,15 @@
<script lang="ts">
export let width;
</script>
<div style={`max-width: ${width}px`}>
<slot />
</div>
<style>
div {
flex: 1 1;
overflow-y: auto;
overflow-x: auto;
}
</style>

View File

@@ -3,6 +3,7 @@
<style>
div {
display: flex;
border-bottom: 1px solid var(--theme-border);
margin-bottom: 5px;
}
</style>