mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-01 07:23:58 +00:00
form view filters
This commit is contained in:
@@ -22,4 +22,29 @@ export class FormViewDisplay {
|
|||||||
public dbinfo: DatabaseInfo = null
|
public dbinfo: DatabaseInfo = null
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
addFilterColumn(column) {
|
||||||
|
if (!column) return;
|
||||||
|
this.setConfig((cfg) => ({
|
||||||
|
...cfg,
|
||||||
|
formFilterColumns: [...(cfg.formFilterColumns || []), column.uniqueName],
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
setFilter(uniqueName, value) {
|
||||||
|
this.setConfig((cfg) => ({
|
||||||
|
...cfg,
|
||||||
|
filters: {
|
||||||
|
...cfg.filters,
|
||||||
|
[uniqueName]: value,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
removeFilter(uniqueName) {
|
||||||
|
this.setConfig((cfg) => ({
|
||||||
|
...cfg,
|
||||||
|
formFilterColumns: (cfg.formFilterColumns || []).filter((x) => x != uniqueName),
|
||||||
|
filters: _.omit(cfg.filters || [], uniqueName),
|
||||||
|
}));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ export interface GridConfig extends GridConfigColumns {
|
|||||||
reference?: GridReferenceDefinition;
|
reference?: GridReferenceDefinition;
|
||||||
isFormView?: boolean;
|
isFormView?: boolean;
|
||||||
formViewKey?: { [uniqueName: string]: string };
|
formViewKey?: { [uniqueName: string]: string };
|
||||||
|
formViewKeyRequested?: { [uniqueName: string]: string };
|
||||||
|
formFilterColumns: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GridCache {
|
export interface GridCache {
|
||||||
@@ -47,6 +49,7 @@ export function createGridConfig(): GridConfig {
|
|||||||
sort: [],
|
sort: [],
|
||||||
focusedColumn: null,
|
focusedColumn: null,
|
||||||
grouping: {},
|
grouping: {},
|
||||||
|
formFilterColumns: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import ColumnManager from './ColumnManager';
|
import ColumnManager from './ColumnManager';
|
||||||
|
import FormViewFilters from '../formview/FormViewFilters';
|
||||||
|
|
||||||
import ReferenceManager from './ReferenceManager';
|
import ReferenceManager from './ReferenceManager';
|
||||||
import { HorizontalSplitter } from '../widgets/Splitter';
|
import { HorizontalSplitter } from '../widgets/Splitter';
|
||||||
import WidgetColumnBar, { WidgetColumnBarItem } from '../widgets/WidgetColumnBar';
|
import WidgetColumnBar, { WidgetColumnBarItem } from '../widgets/WidgetColumnBar';
|
||||||
import CellDataView from '../celldata/CellDataView';
|
import CellDataView from '../celldata/CellDataView';
|
||||||
import { FreeTableGridDisplay } from 'dbgate-datalib';
|
|
||||||
import useTheme from '../theme/useTheme';
|
import useTheme from '../theme/useTheme';
|
||||||
|
|
||||||
const LeftContainer = styled.div`
|
const LeftContainer = styled.div`
|
||||||
@@ -40,6 +40,11 @@ export default function DataGrid(props) {
|
|||||||
<ColumnManager {...props} managerSize={managerSize} />
|
<ColumnManager {...props} managerSize={managerSize} />
|
||||||
</WidgetColumnBarItem>
|
</WidgetColumnBarItem>
|
||||||
)}
|
)}
|
||||||
|
{isFormView && (
|
||||||
|
<WidgetColumnBarItem title="Filters" name="filters" height="30%">
|
||||||
|
<FormViewFilters {...props} managerSize={managerSize} />
|
||||||
|
</WidgetColumnBarItem>
|
||||||
|
)}
|
||||||
{props.showReferences && props.display.hasReferences && (
|
{props.showReferences && props.display.hasReferences && (
|
||||||
<WidgetColumnBarItem title="References" name="references" height="30%" collapsed={props.isDetailView}>
|
<WidgetColumnBarItem title="References" name="references" height="30%" collapsed={props.isDetailView}>
|
||||||
<ReferenceManager {...props} managerSize={managerSize} />
|
<ReferenceManager {...props} managerSize={managerSize} />
|
||||||
|
|||||||
@@ -157,7 +157,14 @@ export default function FormView(props) {
|
|||||||
showMenu(
|
showMenu(
|
||||||
event.pageX,
|
event.pageX,
|
||||||
event.pageY,
|
event.pageY,
|
||||||
<FormViewContextMenu switchToTable={handleSwitchToTable} onNavigate={onNavigate} />
|
<FormViewContextMenu
|
||||||
|
switchToTable={handleSwitchToTable}
|
||||||
|
onNavigate={onNavigate}
|
||||||
|
addToFilter={() => formDisplay.addFilterColumn(getCellColumn(currentCell))}
|
||||||
|
filterThisValue={
|
||||||
|
isDataCell(currentCell) ? () => formDisplay.filterCellValue(getCellColumn(currentCell), rowData) : null
|
||||||
|
}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -394,7 +401,7 @@ export default function FormView(props) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const rowCountInfo = React.useMemo(() => {
|
const rowCountInfo = React.useMemo(() => {
|
||||||
if (rowData == null) return 'No data';
|
if (rowData == null) return 'No data';
|
||||||
if (allRowCount == null || rowCountBefore == null) return 'Loading row count...';
|
if (allRowCount == null || rowCountBefore == null) return 'Loading row count...';
|
||||||
return `Row: ${(rowCountBefore + 1).toLocaleString()} / ${allRowCount.toLocaleString()}`;
|
return `Row: ${(rowCountBefore + 1).toLocaleString()} / ${allRowCount.toLocaleString()}`;
|
||||||
}, [rowCountBefore, allRowCount]);
|
}, [rowCountBefore, allRowCount]);
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { DropDownMenuItem, DropDownMenuDivider } from '../modals/DropDownMenu';
|
import { DropDownMenuItem, DropDownMenuDivider } from '../modals/DropDownMenu';
|
||||||
|
|
||||||
export default function FormViewContextMenu({ switchToTable, onNavigate }) {
|
export default function FormViewContextMenu({ switchToTable, onNavigate, addToFilter, filterThisValue }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<DropDownMenuItem onClick={switchToTable} keyText="F4">
|
<DropDownMenuItem onClick={switchToTable} keyText="F4">
|
||||||
Table view
|
Table view
|
||||||
</DropDownMenuItem>
|
</DropDownMenuItem>
|
||||||
|
{addToFilter && <DropDownMenuItem onClick={addToFilter}>Add to filter</DropDownMenuItem>}
|
||||||
|
{filterThisValue && <DropDownMenuItem onClick={filterThisValue}>Filter this value</DropDownMenuItem>}
|
||||||
<DropDownMenuDivider />
|
<DropDownMenuDivider />
|
||||||
<DropDownMenuItem onClick={() => onNavigate('begin')} keyText="Ctrl+Home">
|
<DropDownMenuItem onClick={() => onNavigate('begin')} keyText="Ctrl+Home">
|
||||||
Navigate to begin
|
Navigate to begin
|
||||||
|
|||||||
77
packages/web/src/formview/FormViewFilters.js
Normal file
77
packages/web/src/formview/FormViewFilters.js
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { ManagerInnerContainer } from '../datagrid/ManagerStyles';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
import ColumnLabel from '../datagrid/ColumnLabel';
|
||||||
|
import { TextField } from '../utility/inputs';
|
||||||
|
import { getFilterType } from 'dbgate-filterparser';
|
||||||
|
import DataFilterControl from '../datagrid/DataFilterControl';
|
||||||
|
import InlineButton from '../widgets/InlineButton';
|
||||||
|
import { FontIcon } from '../icons';
|
||||||
|
|
||||||
|
const ColumnWrapper = styled.div`
|
||||||
|
margin: 5px;
|
||||||
|
`;
|
||||||
|
const ColumnNameWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const TextFieldWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
`;
|
||||||
|
const StyledTextField = styled(TextField)`
|
||||||
|
flex: 1;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default function FormViewFilters(props) {
|
||||||
|
const { formDisplay } = props;
|
||||||
|
if (!formDisplay || !formDisplay.baseTable || !formDisplay.baseTable.primaryKey) return null;
|
||||||
|
const { baseTable } = formDisplay;
|
||||||
|
const { formViewKey, formFilterColumns, filters } = formDisplay.config || {};
|
||||||
|
|
||||||
|
const allFilterNames = _.union(_.keys(filters || {}), formFilterColumns || []);
|
||||||
|
console.log('filters', filters);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ManagerInnerContainer style={{ maxWidth: props.managerSize }}>
|
||||||
|
{baseTable.primaryKey.columns.map((col) => (
|
||||||
|
<ColumnWrapper key={col.columnName}>
|
||||||
|
<ColumnNameWrapper>
|
||||||
|
<div>
|
||||||
|
<FontIcon icon="img primary-key" />
|
||||||
|
<ColumnLabel {...baseTable.columns.find((x) => x.columnName == col.columnName)} />
|
||||||
|
</div>
|
||||||
|
</ColumnNameWrapper>
|
||||||
|
<TextFieldWrapper>
|
||||||
|
<StyledTextField value={formViewKey && formViewKey[col.columnName]} />
|
||||||
|
</TextFieldWrapper>
|
||||||
|
</ColumnWrapper>
|
||||||
|
))}
|
||||||
|
{allFilterNames.map((columnName) => {
|
||||||
|
const column = baseTable.columns.find((x) => x.columnName == columnName);
|
||||||
|
if (!column) return null;
|
||||||
|
return (
|
||||||
|
<ColumnWrapper key={columnName}>
|
||||||
|
<ColumnNameWrapper>
|
||||||
|
<ColumnLabel {...column} />
|
||||||
|
<InlineButton
|
||||||
|
square
|
||||||
|
onClick={() => {
|
||||||
|
formDisplay.removeFilter(column.columnName);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontIcon icon="icon delete" />
|
||||||
|
</InlineButton>
|
||||||
|
</ColumnNameWrapper>
|
||||||
|
<DataFilterControl
|
||||||
|
filterType={getFilterType(column.dataType)}
|
||||||
|
filter={filters[column.columnName]}
|
||||||
|
setFilter={(value) => formDisplay.setFilter(column.columnName, value)}
|
||||||
|
/>
|
||||||
|
</ColumnWrapper>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ManagerInnerContainer>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user