From a03adedf687c9a3e56396302e648b2901697ff21 Mon Sep 17 00:00:00 2001 From: Wroud Date: Sat, 13 Jun 2020 23:50:31 +0300 Subject: [PATCH 1/2] feat(data-viewer-plugin): add query filter CB-85 --- .../packages/core/src/blocks/InputField.tsx | 4 ++ .../data-viewer-plugin/locales/en.json | 3 + .../data-viewer-plugin/locales/ru.json | 3 + .../TableViewer/TableHeader/TableHeader.tsx | 49 +++++++++++++ .../TableHeader/TableHeaderService.ts | 22 ++++++ .../TableHeader/TableWhereFilter.tsx | 71 +++++++++++++++++++ .../src/TableViewer/TableViewer.tsx | 2 + .../src/TableViewer/TableViewerModel.ts | 3 + .../data-viewer-plugin/src/manifest.ts | 2 + 9 files changed, 159 insertions(+) create mode 100644 webapp/packages/data-viewer-plugin/locales/en.json create mode 100644 webapp/packages/data-viewer-plugin/locales/ru.json create mode 100644 webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeader.tsx create mode 100644 webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableHeaderService.ts create mode 100644 webapp/packages/data-viewer-plugin/src/TableViewer/TableHeader/TableWhereFilter.tsx 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) { From ecb225e36d26a047e7398db2f8d09ba2827e8234 Mon Sep 17 00:00:00 2001 From: serge-rider Date: Sun, 14 Jun 2020 12:49:18 +0300 Subject: [PATCH 2/2] Connectionstate binding fix --- .../src/io/cloudbeaver/service/core/WebServiceBindingCore.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java index db89966973..2847ace5e9 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/WebServiceBindingCore.java @@ -50,6 +50,8 @@ public class WebServiceBindingCore extends WebServiceBindingBase .dataFetcher("sessionPermissions", env -> getService(env).getSessionPermissions(getWebSession(env))) .dataFetcher("sessionState", env -> getService(env).getSessionState(getWebSession(env))) + .dataFetcher("connectionState", env -> getService(env).getConnectionState(getWebSession(env), env.getArgument("id"))) + .dataFetcher("readSessionLog", env -> getService(env).readSessionLog( getWebSession(env), env.getArgument("maxEntries"), @@ -62,7 +64,6 @@ public class WebServiceBindingCore extends WebServiceBindingBase .dataFetcher("touchSession", env -> getService(env).touchSession(GraphQLEndpoint.getServletRequest(env))) .dataFetcher("changeSessionLanguage", env -> getService(env).changeSessionLanguage(getWebSession(env), env.getArgument("locale"))) - .dataFetcher("connectionState", env -> getService(env).getConnectionState(getWebSession(env), env.getArgument("id"))) .dataFetcher("openConnection", env -> getService(env).openConnection(getWebSession(env), getConnectionConfig(env))) .dataFetcher("createConnection", env -> getService(env).createConnection(getWebSession(env), getConnectionConfig(env))) .dataFetcher("testConnection", env -> getService(env).testConnection(getWebSession(env), getConnectionConfig(env)))