diff --git a/webapp/packages/core/src/blocks/InputField.tsx b/webapp/packages/core/src/blocks/InputField.tsx
index 1328b531ee..fb76442bda 100644
--- a/webapp/packages/core/src/blocks/InputField.tsx
+++ b/webapp/packages/core/src/blocks/InputField.tsx
@@ -27,6 +27,10 @@ const styles = css`
padding: 0 12px;
line-height: 16px;
font-weight: 500;
+
+ &:empty {
+ display: none;
+ }
}
& input {
flex: 1;
diff --git a/webapp/packages/data-viewer-plugin/locales/en.json b/webapp/packages/data-viewer-plugin/locales/en.json
new file mode 100644
index 0000000000..4c66cfe33f
--- /dev/null
+++ b/webapp/packages/data-viewer-plugin/locales/en.json
@@ -0,0 +1,3 @@
+{
+ "table_header_sql_expression": "Enter a SQL expression to filter results"
+}
\ No newline at end of file
diff --git a/webapp/packages/data-viewer-plugin/locales/ru.json b/webapp/packages/data-viewer-plugin/locales/ru.json
new file mode 100644
index 0000000000..d4062890cc
--- /dev/null
+++ b/webapp/packages/data-viewer-plugin/locales/ru.json
@@ -0,0 +1,3 @@
+{
+ "table_header_sql_expression": "Введите SQL выражение чтобы отфильтровать результаты"
+}
\ No newline at end of file
diff --git a/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeader.tsx b/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeader.tsx
new file mode 100644
index 0000000000..fd325df129
--- /dev/null
+++ b/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeader.tsx
@@ -0,0 +1,49 @@
+/*
+ * cloudbeaver - Cloud Database Manager
+ * Copyright (C) 2020 DBeaver Corp and others
+ *
+ * Licensed under the Apache License, Version 2.0.
+ * you may not use this file except in compliance with the License.
+ */
+
+import { observer } from 'mobx-react';
+import styled, { css } from 'reshadow';
+
+import { Placeholder } from '@dbeaver/core/blocks';
+import { useService } from '@dbeaver/core/dist/di';
+import { composes, useStyles } from '@dbeaver/core/theming';
+
+import { TableViewerModel } from '../TableViewerModel';
+import { TableHeaderService } from './TableHeaderService';
+
+const styles = composes(
+ css`
+ table-header {
+ composes: theme-background-secondary theme-text-on-secondary from global;
+ }
+ `,
+ css`
+ table-header {
+ height: 40px;
+ flex: 0 0 auto;
+ display: flex;
+ align-items: center;
+ }
+ `
+);
+
+type Props = {
+ model: TableViewerModel;
+}
+
+export const TableHeader = observer(function TableHeader({
+ model,
+}: Props) {
+ const service = useService(TableHeaderService);
+
+ return styled(useStyles(styles))(
+
+
+
+ );
+});
diff --git a/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeaderService.ts b/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeaderService.ts
new file mode 100644
index 0000000000..8b8fa16c7f
--- /dev/null
+++ b/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeaderService.ts
@@ -0,0 +1,22 @@
+/*
+ * cloudbeaver - Cloud Database Manager
+ * Copyright (C) 2020 DBeaver Corp and others
+ *
+ * Licensed under the Apache License, Version 2.0.
+ * you may not use this file except in compliance with the License.
+ */
+
+import { PlaceholderContainer } from '@dbeaver/core/blocks';
+import { injectable, Bootstrap } from '@dbeaver/core/di';
+
+import { TableViewerModel } from '../TableViewerModel';
+import { TableWhereFilter } from './TableWhereFilter';
+
+@injectable()
+export class TableHeaderService extends Bootstrap {
+ readonly tableHeaderPlaceholder = new PlaceholderContainer()
+
+ bootstrap() {
+ this.tableHeaderPlaceholder.add(TableWhereFilter, 1);
+ }
+}
diff --git a/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableWhereFilter.tsx b/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableWhereFilter.tsx
new file mode 100644
index 0000000000..efd9195428
--- /dev/null
+++ b/webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableWhereFilter.tsx
@@ -0,0 +1,71 @@
+/*
+ * cloudbeaver - Cloud Database Manager
+ * Copyright (C) 2020 DBeaver Corp and others
+ *
+ * Licensed under the Apache License, Version 2.0.
+ * you may not use this file except in compliance with the License.
+ */
+
+import { observer } from 'mobx-react';
+import { useCallback } from 'react';
+import styled, { css } from 'reshadow';
+
+import { InputField, IconButton, SubmittingForm } from '@dbeaver/core/blocks';
+import { useTranslate } from '@dbeaver/core/localization';
+import { composes, useStyles } from '@dbeaver/core/theming';
+
+import { TableViewerModel } from '../TableViewerModel';
+
+const styles = composes(
+ css`
+ IconButton {
+ composes: theme-text-primary theme-ripple from global;
+ }
+ `,
+ css`
+ SubmittingForm {
+ height: 40px;
+ flex: 1;
+ display: flex;
+ align-items: center;
+ }
+ InputField {
+ flex: 1;
+ }
+ IconButton {
+ margin-right: 18px;
+ position: relative;
+ height: 24px;
+ width: 24px;
+ display: block;
+ }
+ `
+);
+
+type Props = {
+ context: TableViewerModel;
+}
+
+export const TableWhereFilter = observer(function TableWhereFilter({
+ context,
+}: Props) {
+ const translate = useTranslate();
+ const handleChange = useCallback(
+ (value: string) => context.setQueryWhereFilter(value),
+ [context]
+ );
+
+ return styled(useStyles(styles))(
+ context.applyQueryFilters()}>
+
+ context.applyQueryFilters()}/>
+
+ );
+});
diff --git a/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewer.tsx b/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewer.tsx
index f7465ca04e..a08cabaea3 100644
--- a/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewer.tsx
+++ b/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewer.tsx
@@ -15,6 +15,7 @@ import { useService } from '@dbeaver/core/di';
import { TableFooter } from './TableFooter/TableFooter';
import { TableGrid } from './TableGrid';
+import { TableHeader } from './TableHeader/TableHeader';
import { TableViewerStorageService } from './TableViewerStorageService';
const viewerStyles = css`
@@ -45,6 +46,7 @@ export const TableViewer = observer(function TableViewer({
return styled(viewerStyles)(
+
diff --git a/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewerModel.ts b/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewerModel.ts
index e8a7a5c164..3b5e490b1a 100644
--- a/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewerModel.ts
+++ b/webapp/packages/data-viewer-plugin/src/TableViewer/TableViewerModel.ts
@@ -147,6 +147,9 @@ export class TableViewerModel implements ITableViewerModelOptions {
setQueryWhereFilter(where: string | null) {
this.queryWhereFilter = where;
+ }
+
+ applyQueryFilters() {
this.resetData();
}
diff --git a/webapp/packages/data-viewer-plugin/src/manifest.ts b/webapp/packages/data-viewer-plugin/src/manifest.ts
index b9ecf9c2aa..dcbc096117 100644
--- a/webapp/packages/data-viewer-plugin/src/manifest.ts
+++ b/webapp/packages/data-viewer-plugin/src/manifest.ts
@@ -12,6 +12,7 @@ import { DataViewerBootstrap } from './DataViewerBootstrap';
import { DataViewerTableService } from './DataViewerTableService';
import { DataViewerTabService } from './DataViewerTabService';
import { TableFooterMenuService } from './TableViewer/TableFooter/TableFooterMenu/TableFooterMenuService';
+import { TableHeaderService } from './TableViewer/TableHeader/TableHeaderService';
import { TableViewerStorageService } from './TableViewer/TableViewerStorageService';
export const manifest: PluginManifest = {
@@ -24,6 +25,7 @@ export const manifest: PluginManifest = {
DataViewerTableService,
TableViewerStorageService,
TableFooterMenuService,
+ TableHeaderService,
],
async initialize(services: IServiceInjector) {