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-5181 Display User Notification Pop-up When Copy/Paste Functionality is Disabled by Administrator #2730

Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface IReactCodeMirrorProps extends React.PropsWithChildren {
getValue?: () => string;
extensions?: Map<Compartment, Extension>;
readonly?: boolean;
disableCopy?: boolean;
copyEventHandler?: (event: ClipboardEvent) => boolean;
autoFocus?: boolean;
onChange?: (value: string, update: ViewUpdate) => void;
onCursorChange?: (selection: SelectionRange, update: ViewUpdate) => void;
Expand Down
8 changes: 3 additions & 5 deletions webapp/packages/plugin-codemirror6/src/ReactCodemirror.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
incomingValue,
extensions = new Map<Compartment, Extension>(),
readonly,
disableCopy,
copyEventHandler,
autoFocus,
onChange,
onCursorChange,
Expand All @@ -45,11 +45,9 @@ export const ReactCodemirror = observer<IReactCodeMirrorProps, IEditorRef>(
const eventHandlers = useMemo(
() =>
EditorView.domEventHandlers({
copy() {
return disableCopy;
},
copy: copyEventHandler,
}),
[disableCopy],
[copyEventHandler],
);
extensions = useCodemirrorExtensions(extensions, [readOnlyFacet, eventHandlers]);
const [container, setContainer] = useState<HTMLDivElement | null>(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
IResultSetElementKey,
ResultSetDataKeysUtils,
ResultSetSelectAction,
useDataViewerCopyHandler,
} from '@cloudbeaver/plugin-data-viewer';

import type { IDataGridSelectionContext } from './DataGridSelection/DataGridSelectionContext';
Expand Down Expand Up @@ -71,6 +72,7 @@ export function useGridSelectedCellsCopy(
) {
const dataViewerService = useService(DataViewerService);
const props = useObjectRef({ tableData, selectionContext, resultSetSelectAction });
const copyEventHandler = useDataViewerCopyHandler();

const onKeydownHandler = useCallback((event: React.KeyboardEvent) => {
if ((event.ctrlKey || event.metaKey) && event.nativeEvent.code === EVENT_KEY_CODE.C) {
Expand Down Expand Up @@ -98,6 +100,8 @@ export function useGridSelectedCellsCopy(
copyToClipboard(value);
}
}

copyEventHandler(event);
}
}, []);

Expand Down
6 changes: 1 addition & 5 deletions webapp/packages/plugin-data-viewer/src/DataViewerService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ import { DataViewerSettingsService } from './DataViewerSettingsService';
@injectable()
export class DataViewerService {
get canCopyData() {
if (this.sessionPermissionsResource.has(EAdminPermission.admin)) {
return true;
}

return !this.dataViewerSettingsService.disableCopyData;
return this.sessionPermissionsResource.has(EAdminPermission.admin) || !this.dataViewerSettingsService.disableCopyData;
}

constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@
import { observer } from 'mobx-react-lite';
import { useMemo } from 'react';

import { useService } from '@cloudbeaver/core-di';
import { EditorLoader, useCodemirrorExtensions } from '@cloudbeaver/plugin-codemirror6';

import { DataViewerService } from '../../DataViewerService';
import { useDataViewerCopyHandler } from '../../useDataViewerCopyHandler';
import { getTypeExtension } from './getTypeExtension';

interface Props {
Expand All @@ -27,15 +26,15 @@ export const TextValueEditor = observer<Props>(function TextValueEditor({ conten
const typeExtension = useMemo(() => getTypeExtension(contentType!) ?? [], [contentType]);

const extensions = useCodemirrorExtensions(undefined, typeExtension);
const dataViewerService = useService(DataViewerService);
const copyEventHandler = useDataViewerCopyHandler();

return (
<EditorLoader
value={value}
lineWrapping={lineWrapping}
readonly={readonly}
extensions={extensions}
disableCopy={!dataViewerService.canCopyData}
copyEventHandler={copyEventHandler}
onChange={onChange}
/>
);
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/plugin-data-viewer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,6 @@ export * from './ResultSetDataSource';
export * from './DataPresentationService';
export * from './DataViewerDataChangeConfirmationService';
export * from './ValuePanelPresentation/BooleanValue/isBooleanValuePresentationAvailable';
export * from './useDataViewerCopyHandler';
export * from './DataViewerSettingsService';
export * from './DATA_EDITOR_SETTINGS_GROUP';
2 changes: 2 additions & 0 deletions webapp/packages/plugin-data-viewer/src/locales/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ export default [
['data_viewer_script_preview_error_title', 'Kann das Skript nicht bekommen'],
['data_viewer_total_count_tooltip', 'Totalzahl erhalten'],
['data_viewer_model_not_loaded', 'Das Tabellenmodell ist nicht geladen'],
['data_viewer_copy_not_allowed', 'An ability to copy data is disabled'],
['data_viewer_copy_not_allowed_message', 'If this was unexpected, contact the administrator'],
['settings_data_editor', 'Dateneditor'],
['settings_data_editor_disable_edit_name', 'Bearbeiten deaktivieren'],
['settings_data_editor_disable_edit_description', 'Deaktivieren Sie die Bearbeitung von Daten in Data Viewer für Nicht-Admin-Benutzer'],
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-data-viewer/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export default [
['data_viewer_total_count_canceled_message', 'Statement was cancelled due to user request'],
['data_viewer_total_count_failed', 'Failed to get total count'],
['data_viewer_model_not_loaded', 'Table model is not loaded'],
['data_viewer_copy_not_allowed', 'An ability to copy data is disabled'],
['data_viewer_copy_not_allowed_message', 'If this was unexpected, contact the administrator'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer for non-admin users'],
Expand Down
33 changes: 19 additions & 14 deletions webapp/packages/plugin-data-viewer/src/locales/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
export default [
['plugin_data_viewer_data_viewer_settings_group', 'Affichage des données'],
['table_header_sql_expression', 'Entrez une expression SQL pour filtrer les résultats, par exemple column_name=10'],
['table_header_sql_expression_not_supported', 'Le filtrage des données n\'est pas supporté'],
['table_header_sql_expression_not_supported', "Le filtrage des données n'est pas supporté"],
['data_viewer_tab_title', 'Données'],
['data_viewer_value_edit', 'Modifier'],
['data_viewer_value_apply', 'Appliquer'],
Expand All @@ -20,16 +20,16 @@ export default [
['data_viewer_statistics_updated_rows', 'Lignes mises à jour :'],
['data_viewer_action_refresh', 'Actualiser'],
['data_viewer_action_auto_refresh', 'Actualisation automatique'],
['data_viewer_action_auto_refresh_stop', 'Arrêter l\'actualisation automatique'],
['data_viewer_action_auto_refresh_stop', "Arrêter l'actualisation automatique"],
['data_viewer_action_edit_delete', 'Supprimer la sélection'],
['data_viewer_action_edit_add', 'Ajouter'],
['data_viewer_action_edit_add_copy', 'Dupliquer'],
['data_viewer_action_edit_revert', 'Annuler la sélection'],
['data_viewer_result_edited_title', 'Enregistrer les modifications'],
['data_viewer_result_edited_message', 'Le jeu de résultats a été modifié. Voulez-vous enregistrer les modifications dans la base de données ?'],
['data_viewer_data_save_error_title', 'Erreur lors de l\'enregistrement des modifications'],
['data_viewer_auto_refresh_settings', 'Paramètres d\'actualisation automatique'],
['data_viewer_auto_refresh_settings_stop_on_error', 'Arrêter en cas d\'erreur'],
['data_viewer_data_save_error_title', "Erreur lors de l'enregistrement des modifications"],
['data_viewer_auto_refresh_settings', "Paramètres d'actualisation automatique"],
['data_viewer_auto_refresh_settings_stop_on_error', "Arrêter en cas d'erreur"],
['data_viewer_presentation_value_title', 'Valeur'],
['data_viewer_presentation_value_text_line_wrapping_wrap', 'Retour à la ligne'],
['data_viewer_presentation_value_text_line_wrapping_no_wrap', 'Ne pas revenir à la ligne'],
Expand All @@ -42,25 +42,30 @@ export default [
['data_viewer_presentation_value_text_base64_title', 'Base64'],
['data_viewer_presentation_value_image_title', 'Image'],
['data_viewer_presentation_value_image_fit', 'Ajuster à la fenêtre'],
['data_viewer_presentation_value_image_original_size', 'Taille d\'origine'],
['data_viewer_presentation_value_boolean_placeholder', 'Impossible d\'afficher la valeur actuelle en tant que booléen'],
['data_viewer_presentation_value_image_original_size', "Taille d'origine"],
['data_viewer_presentation_value_boolean_placeholder', "Impossible d'afficher la valeur actuelle en tant que booléen"],
['data_viewer_presentation_value_content_truncated_placeholder', 'La valeur a été tronquée en raison de la'],
['data_viewer_presentation_value_content_download_error', 'Échec du téléchargement'],
['data_viewer_presentation_value_content_paste_error', 'Impossible de charger le texte complet'],
['data_viewer_script_preview', 'Script'],
['data_viewer_script_preview_dialog_title', 'Aperçu des modifications'],
['data_viewer_script_preview_error_title', 'Impossible d\'obtenir le script'],
['data_viewer_script_preview_error_title', "Impossible d'obtenir le script"],
['data_viewer_refresh_result_set', 'Actualiser le jeu de résultats'],
['data_viewer_total_count_tooltip', 'Obtenir le compte total'],
['data_viewer_total_count_canceled_title', 'Total annulé'],
['data_viewer_total_count_canceled_message', 'La déclaration a été annulée à la demande de l\'utilisateur'],
['data_viewer_total_count_failed', 'Échec de l\'obtention du compte total'],
['data_viewer_model_not_loaded', 'Le modèle de la table n\'est pas chargé'],
['data_viewer_total_count_canceled_message', "La déclaration a été annulée à la demande de l'utilisateur"],
['data_viewer_total_count_failed', "Échec de l'obtention du compte total"],
['data_viewer_model_not_loaded', "Le modèle de la table n'est pas chargé"],
['data_viewer_copy_not_allowed', 'An ability to copy data is disabled'],
['data_viewer_copy_not_allowed_message', 'If this was unexpected, contact the administrator'],
['settings_data_editor', 'Éditeur de données'],
['settings_data_editor_disable_edit_name', 'Désactiver l\'édition'],
['settings_data_editor_disable_edit_description', 'Désactiver l\'édition des données dans le Data Viewer pour les utilisateurs non administrateurs'],
['settings_data_editor_disable_edit_name', "Désactiver l'édition"],
['settings_data_editor_disable_edit_description', "Désactiver l'édition des données dans le Data Viewer pour les utilisateurs non administrateurs"],
['settings_data_editor_disable_data_copy_name', 'Désactiver la copie'],
['settings_data_editor_disable_data_copy_description', 'Désactiver la copie des données dans le Data Viewer pour les utilisateurs non administrateurs'],
[
'settings_data_editor_disable_data_copy_description',
'Désactiver la copie des données dans le Data Viewer pour les utilisateurs non administrateurs',
],
['settings_data_editor_fetch_min_name', 'Taille de récupération minimale'],
['settings_data_editor_fetch_min_description', 'Nombre minimal de lignes à récupérer'],
['settings_data_editor_fetch_max_name', 'Taille de récupération maximale'],
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-data-viewer/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ export default [
['data_viewer_total_count_canceled_message', 'Statement was cancelled due to user request'],
['data_viewer_total_count_failed', 'Failed to get total count'],
['data_viewer_model_not_loaded', 'Table model is not loaded'],
['data_viewer_copy_not_allowed', 'An ability to copy data is disabled'],
['data_viewer_copy_not_allowed_message', 'If this was unexpected, contact the administrator'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer for non-admin users'],
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-data-viewer/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export default [
['data_viewer_total_count_canceled_message', 'Запрос был отменен пользователем'],
['data_viewer_total_count_failed', 'Не удалось получить количество записей'],
['data_viewer_model_not_loaded', 'Не удалось загрузить модель таблицы'],
['data_viewer_copy_not_allowed', 'Возможность копирования данных отключена'],
['data_viewer_copy_not_allowed_message', 'Если это не ожидаемо, обратитесь к администратору'],
['settings_data_editor', 'Редактор данных'],
['settings_data_editor_disable_edit_name', 'Отключить редактирование'],
['settings_data_editor_disable_edit_description', 'Отключить редактирование данных для пользователей без прав администратора'],
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/plugin-data-viewer/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export default [
['data_viewer_total_count_canceled_title', 'Total count canceled'],
['data_viewer_total_count_canceled_message', 'Statement was cancelled due to user request'],
['data_viewer_model_not_loaded', 'Table model is not loaded'],
['data_viewer_copy_not_allowed', 'An ability to copy data is disabled'],
['data_viewer_copy_not_allowed_message', 'If this was unexpected, contact the administrator'],
['settings_data_editor', 'Data Editor'],
['settings_data_editor_disable_edit_name', 'Disable Edit'],
['settings_data_editor_disable_edit_description', 'Disable editing of data in Data Viewer for non-admin users'],
Expand Down
31 changes: 31 additions & 0 deletions webapp/packages/plugin-data-viewer/src/useDataViewerCopyHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 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 type React from 'react';

import { useService } from '@cloudbeaver/core-di';
import { NotificationService } from '@cloudbeaver/core-events';

import { DataViewerService } from './DataViewerService';

export function useDataViewerCopyHandler() {
const notificationService = useService(NotificationService);
const dataViewerService = useService(DataViewerService);

return function (event?: ClipboardEvent | React.KeyboardEvent | React.ClipboardEvent) {
if (!dataViewerService.canCopyData) {
event?.preventDefault();

notificationService.logError({
title: 'data_viewer_copy_not_allowed',
message: 'data_viewer_copy_not_allowed_message',
});
}

return !dataViewerService.canCopyData;
};
}
Loading