From f8e914075b03cff76b67d8f69c4c1d0e60bfdddd Mon Sep 17 00:00:00 2001 From: Satyam Date: Fri, 10 Apr 2026 13:25:55 +0530 Subject: [PATCH 1/8] Add copy structure controller and clipboard functionality Signed-off-by: Satyam --- app/services_controllers.php | 8 +++ resources/js/database/structure.ts | 39 ++++++++++- resources/js/table/structure.ts | 41 ++++++++++- .../templates/database/structure/index.twig | 3 + .../table/structure/display_structure.twig | 7 ++ .../Structure/CopyStructureController.php | 70 +++++++++++++++++++ tests/unit/Routing/RoutesTest.php | 2 + 7 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 src/Controllers/Table/Structure/CopyStructureController.php diff --git a/app/services_controllers.php b/app/services_controllers.php index b3c851ba04..bd27d883c6 100644 --- a/app/services_controllers.php +++ b/app/services_controllers.php @@ -326,6 +326,10 @@ return [ 'class' => Database\Structure\ShowCreateController::class, 'arguments' => [ResponseRenderer::class, Template::class, DatabaseInterface::class], ], + Database\Structure\CopyStructureController::class => [ + 'class' => Database\Structure\CopyStructureController::class, + 'arguments' => [ResponseRenderer::class, DatabaseInterface::class, DbTableExists::class], + ], Database\StructureController::class => [ 'class' => Database\StructureController::class, 'arguments' => [ @@ -1131,6 +1135,10 @@ return [ DbTableExists::class, ], ], + Table\Structure\CopyStructureController::class => [ + 'class' => Table\Structure\CopyStructureController::class, + 'arguments' => [ResponseRenderer::class, DatabaseInterface::class, DbTableExists::class], + ], Table\Structure\ReservedWordCheckController::class => [ 'class' => Table\Structure\ReservedWordCheckController::class, 'arguments' => [ResponseRenderer::class, Config::class], diff --git a/resources/js/database/structure.ts b/resources/js/database/structure.ts index 79dd95bf3c..6884e1ca2b 100644 --- a/resources/js/database/structure.ts +++ b/resources/js/database/structure.ts @@ -1,7 +1,7 @@ import $ from 'jquery'; import * as bootstrap from 'bootstrap'; import { AJAX } from '../modules/ajax.ts'; -import { getForeignKeyCheckboxLoader, loadForeignKeyCheckbox } from '../modules/functions.ts'; +import { copyToClipboard, displayCopyNotification, getForeignKeyCheckboxLoader, loadForeignKeyCheckbox } from '../modules/functions.ts'; import { Navigation } from '../modules/navigation.ts'; import { CommonParams } from '../modules/common.ts'; import { ajaxRemoveMessage, ajaxShowMessage } from '../modules/ajax-message.ts'; @@ -33,6 +33,7 @@ AJAX.registerTeardown('database/structure.js', function () { $(document).off('click', 'a.truncate_table_anchor.ajax'); $(document).off('click', 'a.drop_table_anchor.ajax'); $(document).off('click', 'a.favorite_table_anchor.ajax'); + $(document).off('click', '#copyStructureBtn'); $('a.real_row_count').off('click'); $('a.row_count_sum').off('click'); $('select[name=submit_mult]').off('change'); @@ -323,4 +324,40 @@ AJAX.registerOnload('database/structure.js', function () { event.preventDefault(); fetchRealRowCount($(this)); }); + + function copyStructureSql (sql: string): void { + if (typeof navigator.clipboard !== 'undefined' && typeof navigator.clipboard.writeText === 'function') { + navigator.clipboard.writeText(sql).then(() => { + displayCopyNotification(true); + }).catch(() => { + displayCopyNotification(copyToClipboard(sql, '