Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
14 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ mutation getSqlExecuteTaskResults($taskId: ID!) {
singleEntity
hasMoreData
hasRowIdentifier
rowIdentifierState
rowIdentifier {
attributes {
name
ordinalPosition
}
constraintType
}
isSupportsDataFilter
hasChildrenCollection
hasDynamicTrace
Expand Down
2 changes: 1 addition & 1 deletion webapp/packages/core-theming/src/styles/_theme-dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ $color-scheme: dark;
$color-positive: #52c41a;
$color-on-positive: #fff;
$color-negative: hsl(0, 95%, 65%);
$color-status: #a08600;
$color-status: #f5bb41;

$link-color: lighten($mdc-theme-primary, 10%);
$link-color-focus: #3f96d1;
Expand Down
2 changes: 1 addition & 1 deletion webapp/packages/core-theming/src/styles/_theme-light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ $color-scheme: light;
$color-positive: #52c41a;
$color-on-positive: #fff;
$color-negative: #e73e52;
$color-status: #ff9900;
$color-status: #fab31a;

$link-color: $mdc-theme-primary;
$link-color-focus: #3f96d1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
ResultSetDataSource,
getNextOrder,
isResultSetDataModel,
isResultSetDataSource,
IDatabaseDataCacheAction,
IDatabaseDataSelectAction,
IDatabaseDataViewAction,
Expand Down Expand Up @@ -441,7 +442,9 @@ export const DataGridTable = observer<IDataPresentationProps>(function DataGridT

const editionState = tableData.getEditionState(cell);

if (!gridContext.model.hasElementIdentifier(tableData.view.resultIndex) && editionState !== DatabaseEditChangeType.add) {
const source = gridContext.model.source;
const hasElementIdentifier = isResultSetDataSource(source) ? source.hasElementIdentifier(tableData.view.resultIndex) : false;
if (!hasElementIdentifier && editionState !== DatabaseEditChangeType.add) {
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useContext } from 'react';
import { clsx } from '@dbeaver/ui-kit';

import { getComputed, s, StaticImage, useS } from '@cloudbeaver/core-blocks';
import { isResultSetDataSource } from '@cloudbeaver/plugin-data-viewer';

import { DataGridContext } from '../DataGridContext.js';
import { DataGridSelectionContext } from '../DataGridSelection/DataGridSelectionContext.js';
Expand All @@ -35,7 +36,10 @@ export const TableColumnHeader = observer<Props>(function TableColumnHeader({ co
const dnd = useTableColumnDnD(model, resultIndex, columnInfo.key);

const dataReadonly = getComputed(() => model.isReadonly(resultIndex));
const hasElementIdentifier = getComputed(() => model.hasElementIdentifier(resultIndex));
const hasElementIdentifier = getComputed(() => {
const source = model.source;
return isResultSetDataSource(source) ? source.hasElementIdentifier(resultIndex) : false;
});

let icon: string | undefined;
let columnName: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,3 @@
bottom: 0;
right: 0;
}

.iconOrImage {
cursor: auto;
width: 10px;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 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-lite';
import { useContext } from 'react';

import { getComputed, IconOrImage, s, useS, useTranslate } from '@cloudbeaver/core-blocks';
import { s, useS, useTranslate } from '@cloudbeaver/core-blocks';

import { DataGridContext } from '../DataGridContext.js';
import { DataGridSelectionContext } from '../DataGridSelection/DataGridSelectionContext.js';
import { TableDataContext } from '../TableDataContext.js';
import style from './TableIndexColumnHeader.module.css';
import { TableStatusIndicator } from './TableStatusIndicator.js';

export const TableIndexColumnHeader = observer(function TableIndexColumnHeader() {
const dataGridContext = useContext(DataGridContext);
Expand All @@ -26,20 +27,14 @@ export const TableIndexColumnHeader = observer(function TableIndexColumnHeader()
throw new Error('Contexts required');
}

const readonly = getComputed(
() => dataGridContext.model.isReadonly(dataGridContext.resultIndex) || !dataGridContext.model.hasElementIdentifier(dataGridContext.resultIndex),
);

function handleClick(event: React.MouseEvent<HTMLDivElement>) {
function handleClick() {
selectionContext.selectTable();
dataGridContext.focus();
}

return (
<>
{readonly && (
<IconOrImage title={translate('data_grid_table_readonly_tooltip')} icon="/icons/lock.png" className={s(styles, { iconOrImage: true })} />
)}
<TableStatusIndicator />
<div
role="button"
title={translate('data_grid_table_index_column_tooltip')}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/

.indicator {
width: 12px;
height: 12px;
border-radius: 50%;
flex-shrink: 0;
border: 1px solid;
box-sizing: border-box;
}

.primaryKey {
border-color: var(--theme-positive);
background: radial-gradient(circle, var(--theme-positive) 2.5px, transparent 3.5px);
}

.virtualKey {
border-color: var(--theme-link-color);
background: radial-gradient(circle, var(--theme-link-color) 2.5px, transparent 3.5px);
}

.defaultStatus {
border-color: var(--theme-status);
background: radial-gradient(circle, var(--theme-status) 2.5px, transparent 3.5px);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2026 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 { SqlRowIdentifierState, type SqlResultColumn } from '@cloudbeaver/core-sdk';
import { observer } from 'mobx-react-lite';
import { useContext } from 'react';

import { IconOrImage, s, useS, useTranslate } from '@cloudbeaver/core-blocks';
import { isResultSetDataSource } from '@cloudbeaver/plugin-data-viewer';

import { DataGridContext } from '../DataGridContext.js';
import { TableDataContext } from '../TableDataContext.js';
import { isNotNullDefined } from '@dbeaver/js-helpers';
import styles from './TableStatusIndicator.module.css';

export const TableStatusIndicator = observer(function TableStatusIndicator() {
const dataGridContext = useContext(DataGridContext);
const tableDataContext = useContext(TableDataContext);
const readOnlyConnection = dataGridContext.model.isReadonly(dataGridContext.resultIndex);
const translate = useTranslate();
const style = useS(styles);

if (!tableDataContext || !dataGridContext) {
return null;
}

const source = dataGridContext.model.source;
const resultSetSource = isResultSetDataSource(source) ? source : null;
const rowIdentifierInfo = resultSetSource?.getRowIdentifierInfo(dataGridContext.resultIndex);
const hasRowIdentifier = resultSetSource?.hasElementIdentifier(dataGridContext.resultIndex);

const firstColumn = tableDataContext.columns[1];
const firstColumnData = isNotNullDefined(firstColumn?.key)
? (tableDataContext.data.getColumn(firstColumn.key) as SqlResultColumn | undefined)
: undefined;
const readOnlyStatus = firstColumnData?.readOnlyStatus;

const isVirtualKey = rowIdentifierInfo?.state === SqlRowIdentifierState.VirtualKey;
const isPrimaryKey = rowIdentifierInfo?.state === SqlRowIdentifierState.PrimaryKey;
const tooltipParts: string[] = [];

if (readOnlyConnection) {
tooltipParts.push(translate('data_grid_table_readonly_connection_tooltip'));
}

if (readOnlyStatus) {
tooltipParts.push(readOnlyStatus);
}

if (hasRowIdentifier && rowIdentifierInfo?.identifier) {
const constraintType = rowIdentifierInfo.identifier.constraintType;
const attributeNames = rowIdentifierInfo.identifier.attributes.map(attr => attr.name).join(', ');
tooltipParts.push(`${constraintType}: ${attributeNames}`);
} else if (isVirtualKey) {
tooltipParts.push(translate('data_grid_table_virtual_key_tooltip'));
}
Comment thread
Wroud marked this conversation as resolved.

const tooltip = tooltipParts.join('\n');

return (
<div
title={tooltip}
className="tw:absolute tw:top-1/2 tw:left-1 tw:-translate-y-1/2 tw:z-1 tw:pointer-events-auto tw:flex tw:items-center tw:gap-1 tw:cursor-help"
>
{readOnlyConnection && <IconOrImage icon="/icons/lock.png" className="tw:w-2.5 tw:cursor-help" />}
<div
className={s(
style,
{ indicator: true },
isPrimaryKey && style['primaryKey'],
isVirtualKey && style['virtualKey'],
!isPrimaryKey && !isVirtualKey && style['defaultStatus'],
)}
/>
Comment thread
Wroud marked this conversation as resolved.
</div>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ export default [
['data_grid_table_delete_filters_and_orders', 'Filter / Sortierung zurücksetzen'],
['data_grid_table_context_menu_filter_dialog_title', 'Wert bearbeiten'],
['data_grid_table_index_column_tooltip', 'Wählen ganze Tabelle aus'],
['data_grid_table_readonly_tooltip', 'Schreibgeschützt'],
['data_grid_table_readonly_connection_tooltip', 'Schreibgeschützte Verbindung'],
['data_grid_table_no_key_found_tooltip', 'Kein eindeutiger Schlüssel gefunden. Datenänderung nicht möglich.'],
['data_grid_table_virtual_key_tooltip', 'Virtueller Schlüssel'],
['plugin_data_spreadsheet_new_settings_disable', 'Tabellenpräsentation deaktivieren'],
['plugin_data_spreadsheet_new_settings_disable_description', 'Deaktivieren Sie die Tabellenpräsentation von Daten für alle Benutzer'],
['plugin_data_spreadsheet_new_settings_description_label', 'Show columns description'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export default [
['data_grid_table_context_menu_filter_clipboard_permission', 'Give access to clipboard'],
['data_grid_table_context_menu_save_value_error', 'Failed to save value'],
['data_grid_table_index_column_tooltip', 'Select whole table'],
['data_grid_table_readonly_tooltip', 'Read-only'],
['data_grid_table_readonly_connection_tooltip', 'Read-only connection'],
['data_grid_table_no_key_found_tooltip', 'No unique key was found. Data modification is not possible.'],
['data_grid_table_virtual_key_tooltip', 'Virtual key'],
['plugin_data_spreadsheet_new_settings_disable', 'Disable Table presentation'],
['plugin_data_spreadsheet_new_settings_disable_description', 'Disable table presentation of data for all users'],
['plugin_data_spreadsheet_new_settings_description_label', 'Show columns description'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export default [
['data_grid_table_context_menu_filter_clipboard_permission', 'Donner accès au presse-papiers'],
['data_grid_table_context_menu_save_value_error', 'Échec de la sauvegarde de la valeur'],
['data_grid_table_index_column_tooltip', 'Sélectionner toute la table'],
['data_grid_table_readonly_tooltip', 'Lecture seule'],
['data_grid_table_no_key_found_tooltip', "Aucune clé unique n'a été trouvée. La modification des données n'est pas possible."],
['data_grid_table_virtual_key_tooltip', 'Clé virtuelle'],
['data_grid_table_readonly_connection_tooltip', 'Connexion en lecture seule'],
['plugin_data_spreadsheet_new_settings_disable', 'Désactiver la présentation de la table'],
['plugin_data_spreadsheet_new_settings_description_label', 'Show columns description'],
['plugin_data_spreadsheet_new_settings_description_label_description', 'Description will be shown under the column names in the table header'],
Expand Down
13 changes: 9 additions & 4 deletions webapp/packages/plugin-data-spreadsheet-new/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ export default [
['data_grid_table_context_menu_filter_clipboard_permission', 'Dai accesso agli appunti'],
['data_grid_table_context_menu_save_value_error', 'Failed to save value'],
['data_grid_table_index_column_tooltip', 'Seleziona tutta la tabella'],
['data_grid_table_readonly_tooltip', 'In sola lettura'],
['plugin_data_spreadsheet_new_settings_disable', 'Disable Table presentation'],
['plugin_data_spreadsheet_new_settings_description_label', 'Show columns description'],
['plugin_data_spreadsheet_new_settings_description_label_description', 'Description will be shown under the column names in the table header'],
['data_grid_table_readonly_connection_tooltip', 'Connessione in sola lettura'],
['data_grid_table_no_key_found_tooltip', 'Nessuna chiave univoca è stata trovata. La modifica dei dati non è possibile.'],
['data_grid_table_virtual_key_tooltip', 'Chiave virtuale'],
['plugin_data_spreadsheet_new_settings_disable', 'Disabilita la presentazione della tabella'],
['plugin_data_spreadsheet_new_settings_description_label', 'Mostra la descrizione delle colonne'],
[
'plugin_data_spreadsheet_new_settings_description_label_description',
"La descrizione verrà mostrata sotto i nomi delle colonne nell'intestazione della tabella",
],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_title', 'Usa formattazione locale'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_os', 'Usa formattazione del sistema operativo'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_none', 'Nessuno'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ export default [
['data_grid_table_context_menu_filter_clipboard_permission', 'Дать доступ к буферу обмена'],
['data_grid_table_context_menu_save_value_error', 'Не удалось сохранить значение'],
['data_grid_table_index_column_tooltip', 'Выбрать всю таблицу'],
['data_grid_table_readonly_tooltip', 'Доступно только для чтения'],
['data_grid_table_readonly_connection_tooltip', 'Подключение только для чтения'],
['data_grid_table_no_key_found_tooltip', 'Не найден уникальный ключ. Изменение данных невозможно.'],
['data_grid_table_virtual_key_tooltip', 'Виртуальный ключ'],
['plugin_data_spreadsheet_new_settings_disable', 'Отключить табличное представление'],
['plugin_data_spreadsheet_new_settings_disable_description', 'Отключить табличное представление данных для всех пользователей'],
['plugin_data_spreadsheet_new_settings_description_label', 'Показать описание колонки'],
Expand Down
8 changes: 5 additions & 3 deletions webapp/packages/plugin-data-spreadsheet-new/src/locales/vi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ export default [
['data_grid_table_context_menu_filter_clipboard_permission', 'Cấp quyền truy cập vào clipboard'],
['data_grid_table_context_menu_save_value_error', 'Không thể lưu giá trị'],
['data_grid_table_index_column_tooltip', 'Chọn toàn bộ bảng'],
['data_grid_table_readonly_tooltip', 'Chỉ đọc'],
['data_grid_table_readonly_connection_tooltip', 'Kết nối chỉ đọc'],
['data_grid_table_no_key_found_tooltip', 'Không tìm thấy khóa duy nhất. Không thể sửa đổi dữ liệu.'],
['data_grid_table_virtual_key_tooltip', 'Khóa ảo'],
['plugin_data_spreadsheet_new_settings_disable', 'Tắt chế độ hiển thị dạng bảng'],
['plugin_data_spreadsheet_new_settings_disable_description', 'Tắt chế độ hiển thị dữ liệu dạng bảng cho tất cả người dùng'],
['plugin_data_spreadsheet_new_settings_description_label', 'Show columns description'],
['plugin_data_spreadsheet_new_settings_description_label_description', 'Description will be shown under the column names in the table header'],
['plugin_data_spreadsheet_new_settings_description_label', 'Hiển thị mô tả cột'],
['plugin_data_spreadsheet_new_settings_description_label_description', 'Mô tả sẽ được hiển thị dưới tên các cột trong tiêu đề bảng'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_title', 'Sử dụng định dạng ngôn ngữ'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_os', 'Sử dụng định dạng hệ điều hành'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_none', 'Không'],
Expand Down
8 changes: 5 additions & 3 deletions webapp/packages/plugin-data-spreadsheet-new/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@ export default [
['data_grid_table_context_menu_filter_clipboard_permission', '授予访问剪贴板的权限'],
['data_grid_table_context_menu_save_value_error', '保存失败'],
['data_grid_table_index_column_tooltip', '选择整个表'],
['data_grid_table_readonly_tooltip', '只读'],
['data_grid_table_no_key_found_tooltip', '未找到唯一键。无法修改数据。'],
['data_grid_table_virtual_key_tooltip', '虚拟键'],
['data_grid_table_readonly_connection_tooltip', '只读连接'],
['plugin_data_spreadsheet_new_settings_disable', '禁用表显示'],
['plugin_data_spreadsheet_new_settings_description_label', 'Show columns description'],
['plugin_data_spreadsheet_new_settings_description_label_description', 'Description will be shown under the column names in the table header'],
['plugin_data_spreadsheet_new_settings_description_label', '显示列描述'],
['plugin_data_spreadsheet_new_settings_description_label_description', '描述将显示在表头的列名下方'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_title', '使用本地格式化'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_os', '使用操作系统格式化'],
['plugin_data_spreadsheet_new_settings_use_locale_formatting_none', '无'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -59,10 +59,6 @@ export class DatabaseDataModel<TSource extends IDatabaseDataSource<any, any> = I
return this.source.isReadonly(resultIndex);
}

hasElementIdentifier(resultIndex: number): boolean {
return this.source.hasElementIdentifier(resultIndex);
}

isDataAvailable(offset: number, count: number): boolean {
return this.source.isDataAvailable(offset, count);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2025 DBeaver Corp and others
* Copyright (C) 2020-2026 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -196,12 +196,7 @@
return !this.isLoading() && !this.disabled;
}

// TODO: probably should be moved to the DataResultAction
hasElementIdentifier(resultIndex: number): boolean {
return false;
}

isReadonly(resultIndex: number): boolean {

Check warning on line 199 in webapp/packages/plugin-data-viewer/src/DatabaseDataModel/DatabaseDataSource.ts

View workflow job for this annotation

GitHub Actions / Frontend / Lint

'resultIndex' is defined but never used
return this.access === DatabaseDataAccessMode.Readonly || this.results.length > 1 || this.disabled;
}

Expand Down Expand Up @@ -303,10 +298,6 @@

return this.save(this.results).then(data => {
this.setResults(data);
//TODO: Remove this when we have virtual keys. We need to refresh the data in tables without a primary key to avoid UI glitch #5140.
if (!this.hasElementIdentifier(0)) {
this.setOutdated();
}
});
});
}
Expand Down
Loading
Loading