Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CB-4005 add wrap mode #2081

Merged
merged 8 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ export default [
['ui_upload_files', 'Upload files'],
['ui_upload_files_duplicate_error', 'Files with the same name already exist'],
['ui_upload_file_fail', 'Failed to upload file'],
['ui_filter', 'Filter'],

['root_permission_denied', "You don't have permissions"],
['root_permission_no_permission', "You don't have permission for this action"],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default [
['ui_upload_files', 'Upload files'],
['ui_upload_files_duplicate_error', 'Files with the same name already exist'],
['ui_upload_file_fail', 'Failed to upload file'],
['ui_filter', 'Filter'],

['root_permission_denied', 'Non hai i permessi'],
['app_root_session_expire_warning_title', 'La sessione sta per scadere'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export default [
['ui_upload_files', 'Загрузить файлы'],
['ui_upload_files_duplicate_error', 'Файлы с такими именами уже существуют'],
['ui_upload_file_fail', 'Не удалось загрузить файл'],
['ui_filter', 'Фильтр'],

['root_permission_denied', 'Отказано в доступе'],
['root_permission_no_permission', 'У вас нет разрешения на это действие'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-localization/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ export default [
['ui_upload_files', 'Upload files'],
['ui_upload_files_duplicate_error', 'Files with the same name already exist'],
['ui_upload_file_fail', 'Failed to upload file'],
['ui_filter', 'Filter'],

['root_permission_denied', '您没有权限'],
['root_permission_no_permission', '您没有权限执行此操作'],
Expand Down
22 changes: 8 additions & 14 deletions webapp/packages/core-ui/src/ContextMenu/MenuBar/MenuBarItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,23 @@ export const MenuBarItem = observer<Props, HTMLButtonElement>(
const title = translate(rest.title);
return (
<button ref={ref} className={s(styles, { menuBarItem: true, hidden }, className)} {...rest} title={title} aria-label={title}>
<div className={s(styles, { menuBarItemBox: true }, className)}>
<div className={s(styles, { menuBarItemBox: true })}>
{loading ? (
<div className={s(styles, { menuBarItemIcon: true }, className)}>
<Loader className={s(styles, { loader: true }, className)} small fullSize />
<div className={s(styles, { menuBarItemIcon: true })}>
<Loader className={s(styles, { loader: true })} small fullSize />
</div>
) : (
icon && (
<div className={s(styles, { menuBarItemIcon: true }, className)}>
<Loader className={s(styles, { loader: true }, className)} suspense small fullSize>
{typeof icon === 'string' ? (
<IconOrImage className={s(styles, { iconOrImage: true }, className)} icon={icon} viewBox={viewBox} />
) : (
icon
)}
<div className={s(styles, { menuBarItemIcon: true })}>
<Loader className={s(styles, { loader: true })} suspense small fullSize>
{typeof icon === 'string' ? <IconOrImage className={s(styles, { iconOrImage: true })} icon={icon} viewBox={viewBox} /> : icon}
</Loader>
</div>
)
)}
{label && displayLabel && (
<div className={s(styles, { menuBarItemLabel: true }, className)}>{translate(label)}</div>
)}
{label && displayLabel && <div className={s(styles, { menuBarItemLabel: true })}>{translate(label)}</div>}
{displaySubmenuMark && (
<div className={s(styles, { menuBarItemMark: true }, className)}>
<div className={s(styles, { menuBarItemMark: true })}>
<Icon className={s(styles, { icon: true }, className)} name="angle" viewBox="0 0 15 8" />
</div>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 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 { createAction } from '@cloudbeaver/core-view';

export const ACTION_SHOW_OUTPUT_LOGS = createAction('action-show_output_logs', {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
export const OUTPUT_LOG_TYPES = ['Debug', 'Log', 'Info', 'Notice', 'Warning', 'Error'] as const;
export type IOutputLogType = (typeof OUTPUT_LOG_TYPES)[number];
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@
*/
import { createMenu } from '@cloudbeaver/core-view';

export const OUTPUT_LOGS_FILTER_MENU = createMenu('output_logs_filter_menu', 'Output Logs');
export const OUTPUT_LOGS_FILTER_MENU = createMenu('output_logs_filter_menu', '', 'filter', 'ui_filter');
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 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 { createMenu } from '@cloudbeaver/core-view';

export const OUTPUT_LOGS_MENU = createMenu('output_logs_menu', 'Output Logs');
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2023 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 { createMenu } from '@cloudbeaver/core-view';

export const OUTPUT_LOGS_SETTINGS_MENU = createMenu('output_logs_settings_menu', '', '/icons/settings_cog_sm.svg', 'ui_settings');

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.menuBar {
align-items: center;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,33 @@
import { observer } from 'mobx-react-lite';
import React, { useEffect } from 'react';

import { Icon, s, useS } from '@cloudbeaver/core-blocks';
import { ContextMenu } from '@cloudbeaver/core-ui';
import { s } from '@cloudbeaver/core-blocks';
import { MenuBar, MenuBarItemStyles } from '@cloudbeaver/core-ui';
import { useMenu } from '@cloudbeaver/core-view';

import { DATA_CONTEXT_SQL_EDITOR_STATE } from '../../DATA_CONTEXT_SQL_EDITOR_STATE';
import type { ISqlEditorTabState } from '../../ISqlEditorTabState';
import { OUTPUT_LOGS_FILTER_MENU } from './OUTPUT_LOGS_FILTER_MENU';
import style from './OutputLogTypesFilterMenu.m.css';
import { OUTPUT_LOGS_MENU } from './OUTPUT_LOGS_MENU';
import styles from './OutputLogsMenu.m.css';

interface Props {
sqlEditorTabState: ISqlEditorTabState;
}

export const OutputLogsFilterMenu = observer<Props>(function OutputLogTypesFilterMenu({ sqlEditorTabState }) {
const styles = useS(style);
export const OutputLogsMenu = observer<Props>(function OutputLogsMenu({ sqlEditorTabState }) {
const menu = useMenu({
menu: OUTPUT_LOGS_FILTER_MENU,
menu: OUTPUT_LOGS_MENU,
});

useEffect(() => {
menu.context.set(DATA_CONTEXT_SQL_EDITOR_STATE, sqlEditorTabState);
}, []);

return (
<ContextMenu className={s(styles, { contextMenu: true })} menu={menu} placement="bottom-end" modal>
<Icon className={s(styles, { icon: true })} name="filter" viewBox="0 0 16 16" />
</ContextMenu>
<MenuBar
menu={menu}
nestedMenuSettings={{ modal: true, placement: 'top-start' }}
className={s(styles, { menuBar: true }, MenuBarItemStyles.floating)}
/>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { observer } from 'mobx-react-lite';

import { Container, Group, s, useResource, useS } from '@cloudbeaver/core-blocks';
import { Container, useResource } from '@cloudbeaver/core-blocks';
import { useService } from '@cloudbeaver/core-di';
import { EditorLoader } from '@cloudbeaver/plugin-codemirror6';

Expand All @@ -29,11 +29,19 @@ export const OutputLogsPanel = observer<Props>(function SqlOutputLogsPanel({ sql
const state = useOutputLogsPanelState(outputLogs, sqlEditorTabState);

return (
<Container className="theme-background-secondary" parent vertical gap dense>
<OutputLogsToolbar state={state} sqlEditorTabState={sqlEditorTabState}/>
<Group overflow box>
{data && <EditorLoader value={state.resultValue} foldGutter={false} highlightActiveLine={false} lineWrapping readonly />}
</Group>
<Container className="theme-background-secondary" overflow vertical noWrap dense parent gap>
<OutputLogsToolbar state={state} sqlEditorTabState={sqlEditorTabState} />
{data && (
<Container overflow>
<EditorLoader
value={state.resultValue}
foldGutter={false}
lineWrapping={outputLogsService.settings.wrapMode}
highlightActiveLine={false}
readonly
/>
</Container>
)}
</Container>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { UserDataService } from '@cloudbeaver/core-authentication';
import { injectable } from '@cloudbeaver/core-di';

import type { ISqlEditorTabState } from '../../ISqlEditorTabState';
Expand All @@ -13,9 +14,19 @@ import { OUTPUT_LOG_TYPES } from './IOutputLogTypes';
import { OUTPUT_LOGS_TAB_ID } from './OUTPUT_LOGS_TAB_ID';
import type { IOutputLog } from './OutputLogsResource';

const OUTPUT_LOGS_KEY = 'output_logs';

interface ISettings {
wrapMode: boolean;
}

@injectable()
export class OutputLogsService {
constructor(private readonly sqlDataSourceService: SqlDataSourceService) {}
get settings() {
return this.userDataService.getUserData(OUTPUT_LOGS_KEY, getOutputLogsDefaultSettings);
}

constructor(private readonly sqlDataSourceService: SqlDataSourceService, private readonly userDataService: UserDataService) {}

async showOutputLogs(editorState: ISqlEditorTabState): Promise<void> {
this.createOutputLogsTab(editorState);
Expand All @@ -28,6 +39,10 @@ export class OutputLogsService {
}
}

toggleWrapMode() {
this.settings.wrapMode = !this.settings.wrapMode;
}

private createOutputLogsTab(state: ISqlEditorTabState) {
const order = Math.max(0, ...state.tabs.map(tab => tab.order + 1));

Expand All @@ -52,3 +67,9 @@ export class OutputLogsService {
return events.filter(event => event.contextId === dataSource?.executionContext?.id);
}
}

function getOutputLogsDefaultSettings(): ISettings {
return {
wrapMode: true,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import React from 'react';
import { Container, Icon, InputField, s, useS, useTranslate } from '@cloudbeaver/core-blocks';

import type { ISqlEditorTabState } from '../../ISqlEditorTabState';
import { OutputLogsMenu } from './OutputLogsMenu';
import style from './OutputLogsToolbar.m.css';
import { OutputLogsFilterMenu } from './OutputLogTypesFilterMenu';
import type { SqlOutputLogsPanelState } from './useOutputLogsPanelState';

interface Props {
state: SqlOutputLogsPanelState;
sqlEditorTabState: ISqlEditorTabState;
}

export const OutputLogsToolbar = observer<Props>(function SqlOutputLogsToolbar({ state, sqlEditorTabState }) {
export const OutputLogsToolbar = observer<Props>(function OutputLogsToolbar({ state, sqlEditorTabState }) {
const styles = useS(style);
const translate = useTranslate();

Expand All @@ -38,7 +38,7 @@ export const OutputLogsToolbar = observer<Props>(function SqlOutputLogsToolbar({
onChange={value => state.setSearchValue(value.toString())}
/>
<Container keepSize>
<OutputLogsFilterMenu sqlEditorTabState={sqlEditorTabState} />
<OutputLogsMenu sqlEditorTabState={sqlEditorTabState} />
</Container>
</Container>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* you may not use this file except in compliance with the License.
*/
import { Bootstrap, injectable } from '@cloudbeaver/core-di';
import { ActionService, KeyBindingService, MenuCheckboxItem, MenuService } from '@cloudbeaver/core-view';
import { ActionService, DATA_CONTEXT_MENU, KeyBindingService, MenuCheckboxItem, MenuService } from '@cloudbeaver/core-view';

import { ACTION_SQL_EDITOR_SHOW_OUTPUT } from '../../actions/ACTION_SQL_EDITOR_SHOW_OUTPUT';
import { KEY_BINDING_SQL_EDITOR_SHOW_OUTPUT } from '../../actions/bindings/KEY_BINDING_SQL_EDITOR_SHOW_OUTPUT';
Expand All @@ -17,6 +17,8 @@ import { SQL_EDITOR_ACTIONS_MENU } from '../../SqlEditor/SQL_EDITOR_ACTIONS_MENU
import { ACTION_SHOW_OUTPUT_LOGS } from './ACTION_SHOW_OUTPUT_LOGS';
import { OUTPUT_LOG_TYPES } from './IOutputLogTypes';
import { OUTPUT_LOGS_FILTER_MENU } from './OUTPUT_LOGS_FILTER_MENU';
import { OUTPUT_LOGS_MENU } from './OUTPUT_LOGS_MENU';
import { OUTPUT_LOGS_SETTINGS_MENU } from './OUTPUT_LOGS_SETTINGS_MENU';
import { OutputLogsService } from './OutputLogsService';

@injectable()
Expand All @@ -32,20 +34,27 @@ export class OutputMenuBootstrap extends Bootstrap {
}

register(): void | Promise<void> {
this.menuService.addCreator({
isApplicable: context => context.get(DATA_CONTEXT_MENU) === OUTPUT_LOGS_MENU,
getItems(context, items) {
return [...items, OUTPUT_LOGS_FILTER_MENU, OUTPUT_LOGS_SETTINGS_MENU];
},
});

this.menuService.addCreator({
menus: [OUTPUT_LOGS_FILTER_MENU],
getItems: context => {
getItems: (context, items) => {
const state = context.tryGet(DATA_CONTEXT_SQL_EDITOR_STATE);

if (!state) {
return [];
}

const outputLogsTabState = state?.outputLogsTab;
const items = [];
const result = [];

for (const logType of OUTPUT_LOG_TYPES) {
items.push(
result.push(
new MenuCheckboxItem(
{
id: logType,
Expand All @@ -70,7 +79,36 @@ export class OutputMenuBootstrap extends Bootstrap {
);
}

return items;
return [...items, ...result];
},
});

this.menuService.addCreator({
menus: [OUTPUT_LOGS_SETTINGS_MENU],
getItems: (context, items) => {
const state = context.tryGet(DATA_CONTEXT_SQL_EDITOR_STATE);

if (!state) {
return [];
}

const wrapMode = new MenuCheckboxItem(
{
id: 'wrap-mode',
label: 'sql_editor_output_logs_wrap_mode',
tooltip: 'sql_editor_output_logs_wrap_mode',
},
{
onSelect: () => {
this.outputLogsService.toggleWrapMode();
},
},
{
isChecked: () => this.outputLogsService.settings.wrapMode,
},
);

return [...items, wrapMode];
},
});

Expand Down
1 change: 1 addition & 0 deletions webapp/packages/plugin-sql-editor/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default [
['sql_editor_output_logs_button_tooltip', 'Show server output (Shift + Ctrl + O)'],
['sql_editor_output_logs_tab_title', 'Output'],
['sql_editor_output_logs_input_placeholder', 'Enter a part of a message to search for here'],
['sql_editor_output_logs_wrap_mode', 'Wrap mode'],
['sql_editor_sql_execution_button_tooltip', 'Execute SQL Statement (Ctrl + Enter)'],
['sql_editor_sql_execution_new_tab_button_tooltip', 'Execute SQL Statement in new tab (Ctrl + \\)(Shift + Ctrl + Enter)'],
['sql_editor_sql_execution_script_button_tooltip', 'Execute SQL Script (Alt + X)'],
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/plugin-sql-editor/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export default [
['sql_editor_output_logs_button_tooltip', 'Show server output (Shift + Ctrl + O)'],
['sql_editor_output_logs_tab_title', 'Output'],
['sql_editor_output_logs_input_placeholder', 'Enter a part of a message to search for here'],
['sql_editor_output_logs_wrap_mode', 'Wrap mode'],
['sql_editor_sql_execution_button_tooltip', "Esegui l'istruzione SQL (Ctrl + Enter)"],
['sql_editor_sql_execution_new_tab_button_tooltip', "Esegui l'istruzione SQL in una nuova tab (Ctrl + \\)(Shift + Ctrl + Enter)"],
['sql_editor_sql_execution_script_button_tooltip', 'Esegui lo script SQL (Alt + X)'],
Expand Down
Loading
Loading