From 80ca2e5215531cb18820b20187abaa1ba01b97ab Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 24 Nov 2025 14:26:25 +0100 Subject: [PATCH 01/76] Add the LANG environment variable for the web version. #1266 --- packages/api/src/controllers/config.js | 1 + packages/web/src/App.svelte | 2 +- packages/web/src/translations.ts | 10 +++++----- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/api/src/controllers/config.js b/packages/api/src/controllers/config.js index 7f9b2547c..0d6605392 100644 --- a/packages/api/src/controllers/config.js +++ b/packages/api/src/controllers/config.js @@ -121,6 +121,7 @@ module.exports = { allowPrivateCloud: platformInfo.isElectron || !!process.env.ALLOW_DBGATE_PRIVATE_CLOUD, ...currentVersion, redirectToDbGateCloudLogin: !!process.env.REDIRECT_TO_DBGATE_CLOUD_LOGIN, + preferrendLanguage: adminConfig?.preferredLanguage || process.env.LANGUAGE || null, }; return configResult; diff --git a/packages/web/src/App.svelte b/packages/web/src/App.svelte index 5b08bb170..abc17dbe8 100644 --- a/packages/web/src/App.svelte +++ b/packages/web/src/App.svelte @@ -61,7 +61,7 @@ initializeAppUpdates(); installCloudListeners(); refreshPublicCloudFiles(); - saveSelectedLanguageToCache(); + saveSelectedLanguageToCache(config.preferrendLanguage); const electron = getElectron(); if (electron) { diff --git a/packages/web/src/translations.ts b/packages/web/src/translations.ts index 2abe830d3..46a99f1ee 100644 --- a/packages/web/src/translations.ts +++ b/packages/web/src/translations.ts @@ -31,13 +31,13 @@ const defaultLanguage = 'en'; let selectedLanguageCache: string | null = null; -export function getSelectedLanguage(): string { +export function getSelectedLanguage(preferrendLanguage?: string): string { if (selectedLanguageCache) return selectedLanguageCache; // const browserLanguage = getBrowserLanguage(); const selectedLanguage = getElectron() - ? getStringSettingsValue('localization.language', null) - : localStorage.getItem('selectedLanguage'); + ? getStringSettingsValue('localization.language', preferrendLanguage) + : localStorage.getItem('selectedLanguage') ?? preferrendLanguage; if (!selectedLanguage || !supportedLanguages.includes(selectedLanguage)) return defaultLanguage; return selectedLanguage; @@ -51,8 +51,8 @@ export async function setSelectedLanguage(language: string) { } } -export function saveSelectedLanguageToCache() { - selectedLanguageCache = getSelectedLanguage(); +export function saveSelectedLanguageToCache(preferrendLanguage?: string) { + selectedLanguageCache = getSelectedLanguage(preferrendLanguage); } export function getBrowserLanguage(): string { From 3c541117d0b5b43f082b5e17db9b258b815b48dc Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 24 Nov 2025 15:18:55 +0100 Subject: [PATCH 02/76] SYNC: change language for Team Premium --- packages/api/src/controllers/config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/api/src/controllers/config.js b/packages/api/src/controllers/config.js index 0d6605392..f47c5245a 100644 --- a/packages/api/src/controllers/config.js +++ b/packages/api/src/controllers/config.js @@ -71,6 +71,7 @@ module.exports = { const isLicenseValid = checkedLicense?.status == 'ok'; const logoutUrl = storageConnectionError ? null : await authProvider.getLogoutUrl(); const adminConfig = storageConnectionError ? null : await storage.readConfig({ group: 'admin' }); + const settingsConfig = storageConnectionError ? null : await storage.readConfig({ group: 'settings' }); storage.startRefreshLicense(); @@ -121,7 +122,7 @@ module.exports = { allowPrivateCloud: platformInfo.isElectron || !!process.env.ALLOW_DBGATE_PRIVATE_CLOUD, ...currentVersion, redirectToDbGateCloudLogin: !!process.env.REDIRECT_TO_DBGATE_CLOUD_LOGIN, - preferrendLanguage: adminConfig?.preferredLanguage || process.env.LANGUAGE || null, + preferrendLanguage: settingsConfig?.['storage.language'] || process.env.LANGUAGE || null, }; return configResult; From 859d02003136c58968a4345b4e7f6e707f95c716 Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:19:44 +0000 Subject: [PATCH 03/76] Update pro ref --- workflow-templates/includes.tpl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-templates/includes.tpl.yaml b/workflow-templates/includes.tpl.yaml index 378d33bb1..766060d07 100644 --- a/workflow-templates/includes.tpl.yaml +++ b/workflow-templates/includes.tpl.yaml @@ -7,7 +7,7 @@ checkout-and-merge-pro: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: f27a03d4aff5b00a009643df146a9c17bdbf7801 + ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 04a8d386417cfb18974e45feaf3b7ca3eeaed654 Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:20:00 +0000 Subject: [PATCH 04/76] chore: auto-update github workflows --- .github/workflows/build-app-pro-beta.yaml | 2 +- .github/workflows/build-app-pro.yaml | 2 +- .github/workflows/build-cloud-pro.yaml | 2 +- .github/workflows/build-docker-pro.yaml | 2 +- .github/workflows/build-npm-pro.yaml | 2 +- .github/workflows/e2e-pro.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-app-pro-beta.yaml b/.github/workflows/build-app-pro-beta.yaml index 9cdbdf1f6..11661fc99 100644 --- a/.github/workflows/build-app-pro-beta.yaml +++ b/.github/workflows/build-app-pro-beta.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: f27a03d4aff5b00a009643df146a9c17bdbf7801 + ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-app-pro.yaml b/.github/workflows/build-app-pro.yaml index 72fa001f0..64d033a32 100644 --- a/.github/workflows/build-app-pro.yaml +++ b/.github/workflows/build-app-pro.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: f27a03d4aff5b00a009643df146a9c17bdbf7801 + ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-cloud-pro.yaml b/.github/workflows/build-cloud-pro.yaml index e69e17de9..a9deb41d5 100644 --- a/.github/workflows/build-cloud-pro.yaml +++ b/.github/workflows/build-cloud-pro.yaml @@ -39,7 +39,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: f27a03d4aff5b00a009643df146a9c17bdbf7801 + ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-docker-pro.yaml b/.github/workflows/build-docker-pro.yaml index 1dd394cf6..41323200c 100644 --- a/.github/workflows/build-docker-pro.yaml +++ b/.github/workflows/build-docker-pro.yaml @@ -44,7 +44,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: f27a03d4aff5b00a009643df146a9c17bdbf7801 + ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-npm-pro.yaml b/.github/workflows/build-npm-pro.yaml index dfa2cdb31..6ef70faff 100644 --- a/.github/workflows/build-npm-pro.yaml +++ b/.github/workflows/build-npm-pro.yaml @@ -35,7 +35,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: f27a03d4aff5b00a009643df146a9c17bdbf7801 + ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/e2e-pro.yaml b/.github/workflows/e2e-pro.yaml index f2566871d..34b5ebb4e 100644 --- a/.github/workflows/e2e-pro.yaml +++ b/.github/workflows/e2e-pro.yaml @@ -26,7 +26,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: f27a03d4aff5b00a009643df146a9c17bdbf7801 + ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 66255769adbc3835bddd8d12579c14c7462d6f1d Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 24 Nov 2025 15:26:24 +0100 Subject: [PATCH 05/76] SYNC: support for browser default language --- packages/web/src/translations.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/web/src/translations.ts b/packages/web/src/translations.ts index 46a99f1ee..00de62ab1 100644 --- a/packages/web/src/translations.ts +++ b/packages/web/src/translations.ts @@ -34,7 +34,10 @@ let selectedLanguageCache: string | null = null; export function getSelectedLanguage(preferrendLanguage?: string): string { if (selectedLanguageCache) return selectedLanguageCache; - // const browserLanguage = getBrowserLanguage(); + if (preferrendLanguage == 'browser') { + preferrendLanguage = getBrowserLanguage(); + } + const selectedLanguage = getElectron() ? getStringSettingsValue('localization.language', preferrendLanguage) : localStorage.getItem('selectedLanguage') ?? preferrendLanguage; From 765fb6297c8e04e3d2348703fab5de8ef6bccb56 Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:27:06 +0000 Subject: [PATCH 06/76] Update pro ref --- workflow-templates/includes.tpl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-templates/includes.tpl.yaml b/workflow-templates/includes.tpl.yaml index 766060d07..ea768115d 100644 --- a/workflow-templates/includes.tpl.yaml +++ b/workflow-templates/includes.tpl.yaml @@ -7,7 +7,7 @@ checkout-and-merge-pro: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 + ref: cd1484e01f3d3ed205512ff9e60cabb994449fca - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 36c391ccffde5f4872cc53deba1ee014a5a79d82 Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:27:45 +0000 Subject: [PATCH 07/76] chore: auto-update github workflows --- .github/workflows/build-app-pro-beta.yaml | 2 +- .github/workflows/build-app-pro.yaml | 2 +- .github/workflows/build-cloud-pro.yaml | 2 +- .github/workflows/build-docker-pro.yaml | 2 +- .github/workflows/build-npm-pro.yaml | 2 +- .github/workflows/e2e-pro.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-app-pro-beta.yaml b/.github/workflows/build-app-pro-beta.yaml index 11661fc99..543df1f16 100644 --- a/.github/workflows/build-app-pro-beta.yaml +++ b/.github/workflows/build-app-pro-beta.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 + ref: cd1484e01f3d3ed205512ff9e60cabb994449fca - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-app-pro.yaml b/.github/workflows/build-app-pro.yaml index 64d033a32..401bb47a3 100644 --- a/.github/workflows/build-app-pro.yaml +++ b/.github/workflows/build-app-pro.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 + ref: cd1484e01f3d3ed205512ff9e60cabb994449fca - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-cloud-pro.yaml b/.github/workflows/build-cloud-pro.yaml index a9deb41d5..39cce0915 100644 --- a/.github/workflows/build-cloud-pro.yaml +++ b/.github/workflows/build-cloud-pro.yaml @@ -39,7 +39,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 + ref: cd1484e01f3d3ed205512ff9e60cabb994449fca - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-docker-pro.yaml b/.github/workflows/build-docker-pro.yaml index 41323200c..cf03a56c8 100644 --- a/.github/workflows/build-docker-pro.yaml +++ b/.github/workflows/build-docker-pro.yaml @@ -44,7 +44,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 + ref: cd1484e01f3d3ed205512ff9e60cabb994449fca - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-npm-pro.yaml b/.github/workflows/build-npm-pro.yaml index 6ef70faff..8f151fbfe 100644 --- a/.github/workflows/build-npm-pro.yaml +++ b/.github/workflows/build-npm-pro.yaml @@ -35,7 +35,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 + ref: cd1484e01f3d3ed205512ff9e60cabb994449fca - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/e2e-pro.yaml b/.github/workflows/e2e-pro.yaml index 34b5ebb4e..4e47e8f9a 100644 --- a/.github/workflows/e2e-pro.yaml +++ b/.github/workflows/e2e-pro.yaml @@ -26,7 +26,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 98f5da5e7f01c71c2320ef5bab8e8490575518b7 + ref: cd1484e01f3d3ed205512ff9e60cabb994449fca - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 12803d815412fd6853b730b4119a34f35e5a3858 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 24 Nov 2025 15:30:05 +0100 Subject: [PATCH 08/76] SYNC: admin settings --- packages/web/src/translations.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/web/src/translations.ts b/packages/web/src/translations.ts index 00de62ab1..ff916bc78 100644 --- a/packages/web/src/translations.ts +++ b/packages/web/src/translations.ts @@ -34,10 +34,10 @@ let selectedLanguageCache: string | null = null; export function getSelectedLanguage(preferrendLanguage?: string): string { if (selectedLanguageCache) return selectedLanguageCache; - if (preferrendLanguage == 'browser') { + if (preferrendLanguage == 'auto') { preferrendLanguage = getBrowserLanguage(); } - + const selectedLanguage = getElectron() ? getStringSettingsValue('localization.language', preferrendLanguage) : localStorage.getItem('selectedLanguage') ?? preferrendLanguage; From 5ba10d0acb4adabc06c902cce220e0f873cc59dd Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:30:50 +0000 Subject: [PATCH 09/76] Update pro ref --- workflow-templates/includes.tpl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-templates/includes.tpl.yaml b/workflow-templates/includes.tpl.yaml index ea768115d..1fefadcca 100644 --- a/workflow-templates/includes.tpl.yaml +++ b/workflow-templates/includes.tpl.yaml @@ -7,7 +7,7 @@ checkout-and-merge-pro: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: cd1484e01f3d3ed205512ff9e60cabb994449fca + ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 1fdc30804a7af799eb63fd369b27b0ee5ef48bdd Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:31:03 +0000 Subject: [PATCH 10/76] chore: auto-update github workflows --- .github/workflows/build-app-pro-beta.yaml | 2 +- .github/workflows/build-app-pro.yaml | 2 +- .github/workflows/build-cloud-pro.yaml | 2 +- .github/workflows/build-docker-pro.yaml | 2 +- .github/workflows/build-npm-pro.yaml | 2 +- .github/workflows/e2e-pro.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-app-pro-beta.yaml b/.github/workflows/build-app-pro-beta.yaml index 543df1f16..0ac99c36f 100644 --- a/.github/workflows/build-app-pro-beta.yaml +++ b/.github/workflows/build-app-pro-beta.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: cd1484e01f3d3ed205512ff9e60cabb994449fca + ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-app-pro.yaml b/.github/workflows/build-app-pro.yaml index 401bb47a3..50badac14 100644 --- a/.github/workflows/build-app-pro.yaml +++ b/.github/workflows/build-app-pro.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: cd1484e01f3d3ed205512ff9e60cabb994449fca + ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-cloud-pro.yaml b/.github/workflows/build-cloud-pro.yaml index 39cce0915..60ca78993 100644 --- a/.github/workflows/build-cloud-pro.yaml +++ b/.github/workflows/build-cloud-pro.yaml @@ -39,7 +39,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: cd1484e01f3d3ed205512ff9e60cabb994449fca + ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-docker-pro.yaml b/.github/workflows/build-docker-pro.yaml index cf03a56c8..5bb638808 100644 --- a/.github/workflows/build-docker-pro.yaml +++ b/.github/workflows/build-docker-pro.yaml @@ -44,7 +44,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: cd1484e01f3d3ed205512ff9e60cabb994449fca + ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-npm-pro.yaml b/.github/workflows/build-npm-pro.yaml index 8f151fbfe..595094415 100644 --- a/.github/workflows/build-npm-pro.yaml +++ b/.github/workflows/build-npm-pro.yaml @@ -35,7 +35,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: cd1484e01f3d3ed205512ff9e60cabb994449fca + ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/e2e-pro.yaml b/.github/workflows/e2e-pro.yaml index 4e47e8f9a..a63c35d3d 100644 --- a/.github/workflows/e2e-pro.yaml +++ b/.github/workflows/e2e-pro.yaml @@ -26,7 +26,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: cd1484e01f3d3ed205512ff9e60cabb994449fca + ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From f789ecd2f1aa81c7c716b0431bb137196cc4ccef Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 24 Nov 2025 15:39:35 +0100 Subject: [PATCH 11/76] SYNC: japanese settings --- packages/web/src/settings/SettingsModal.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web/src/settings/SettingsModal.svelte b/packages/web/src/settings/SettingsModal.svelte index ff2f1f649..41772d672 100644 --- a/packages/web/src/settings/SettingsModal.svelte +++ b/packages/web/src/settings/SettingsModal.svelte @@ -197,6 +197,7 @@ ORDER BY { value: 'it', label: 'Italiano' }, { value: 'pt', label: 'Português (Brasil)' }, { value: 'sk', label: 'Slovenčina' }, + { value: 'ja', label: '日本語' }, { value: 'zh', label: '中文' }, ]} defaultValue={getSelectedLanguage()} From c61f58854e4296f75a8c6a87d948b8f9b292ea69 Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:40:16 +0000 Subject: [PATCH 12/76] Update pro ref --- workflow-templates/includes.tpl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-templates/includes.tpl.yaml b/workflow-templates/includes.tpl.yaml index 1fefadcca..a73f87b0b 100644 --- a/workflow-templates/includes.tpl.yaml +++ b/workflow-templates/includes.tpl.yaml @@ -7,7 +7,7 @@ checkout-and-merge-pro: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 + ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 18d908fa63c1aaec75c4511f7fecfee2550c5742 Mon Sep 17 00:00:00 2001 From: CI workflows Date: Mon, 24 Nov 2025 14:40:35 +0000 Subject: [PATCH 13/76] chore: auto-update github workflows --- .github/workflows/build-app-pro-beta.yaml | 2 +- .github/workflows/build-app-pro.yaml | 2 +- .github/workflows/build-cloud-pro.yaml | 2 +- .github/workflows/build-docker-pro.yaml | 2 +- .github/workflows/build-npm-pro.yaml | 2 +- .github/workflows/e2e-pro.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-app-pro-beta.yaml b/.github/workflows/build-app-pro-beta.yaml index 0ac99c36f..d406ee593 100644 --- a/.github/workflows/build-app-pro-beta.yaml +++ b/.github/workflows/build-app-pro-beta.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 + ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-app-pro.yaml b/.github/workflows/build-app-pro.yaml index 50badac14..c2db2e1f7 100644 --- a/.github/workflows/build-app-pro.yaml +++ b/.github/workflows/build-app-pro.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 + ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-cloud-pro.yaml b/.github/workflows/build-cloud-pro.yaml index 60ca78993..4a71928df 100644 --- a/.github/workflows/build-cloud-pro.yaml +++ b/.github/workflows/build-cloud-pro.yaml @@ -39,7 +39,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 + ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-docker-pro.yaml b/.github/workflows/build-docker-pro.yaml index 5bb638808..293195337 100644 --- a/.github/workflows/build-docker-pro.yaml +++ b/.github/workflows/build-docker-pro.yaml @@ -44,7 +44,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 + ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-npm-pro.yaml b/.github/workflows/build-npm-pro.yaml index 595094415..9c5acbed8 100644 --- a/.github/workflows/build-npm-pro.yaml +++ b/.github/workflows/build-npm-pro.yaml @@ -35,7 +35,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 + ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/e2e-pro.yaml b/.github/workflows/e2e-pro.yaml index a63c35d3d..c720859ae 100644 --- a/.github/workflows/e2e-pro.yaml +++ b/.github/workflows/e2e-pro.yaml @@ -26,7 +26,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 9cfae3ebcd40cbe3b11f51d6bfaad564a0207053 + ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 67ee130a9e0b5313f8956b4e664ca32072f235d8 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 24 Nov 2025 16:20:54 +0100 Subject: [PATCH 14/76] japanese localization --- CHANGELOG.md | 10 + packages/web/src/translations.ts | 2 + translations/ja.json | 907 +++++++++++++++++++++++++++++++ 3 files changed, 919 insertions(+) create mode 100644 translations/ja.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 59bddc515..7e97f9e4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,16 @@ Builds: - linux - application for linux - win - application for Windows +## 6.7.1 - not released yet +- ADDED: LANGUAGE environment variable for the web version. #1266 +- ADDED: New localizations (Italian, Portugese (Brazil), Japanese) +- ADDED: Option to detect language from browser settings in web version +- FIXED: Check updates option no longer available in 6.7.0 #1263 +- FIXED: A MERGE statement must be terminated by a semi-colon (;), but dbgate stripped it. #1257 +- ADDED: Show table size #552 +- ADDED: Sort tables by size and by row count +- ADDED: Connect to Legacy MongoDB (Premium) #540 + ## 6.7.0 - ADDED: Added localization support, now you can use DbGate in multiple languages (French, Spanish, German, Czech, Slovak, Simplified Chinese) #347 #705 #939 #1079 - CHANGED: Solved many issues with binary fields, huge performance improvements in binary fields processing diff --git a/packages/web/src/translations.ts b/packages/web/src/translations.ts index ff916bc78..00b30f9e2 100644 --- a/packages/web/src/translations.ts +++ b/packages/web/src/translations.ts @@ -6,6 +6,7 @@ import es from '../../../translations/es.json'; import zh from '../../../translations/zh.json'; import pt from '../../../translations/pt.json'; import it from '../../../translations/it.json'; +import ja from '../../../translations/ja.json'; import MessageFormat, { MessageFunction } from '@messageformat/core'; import { getStringSettingsValue } from './settings/settingsTools'; @@ -22,6 +23,7 @@ const translations = { es, pt, it, + ja, }; const supportedLanguages = Object.keys(translations); diff --git a/translations/ja.json b/translations/ja.json new file mode 100644 index 000000000..126efcdba --- /dev/null +++ b/translations/ja.json @@ -0,0 +1,907 @@ +{ + "app.databaseName": "データベース名", + "app.loading_plugin": "プラグイン {plugin} を読み込み中...", + "app.preparingPlugins": "プラグインを準備中...", + "app.starting": "DbGateを起動中", + "connection.authToken": "認証トークン", + "chart.detect": "チャートを検出", + "chart.open": "チャートを開く", + "clipboard.SQLInsert": "SQL INSERT文", + "clipboard.SQLUpdate": "SQL UPDATE文", + "clipboard.copyCSV": "CSVとしてコピー", + "clipboard.copyJSON": "JSONとしてコピー", + "clipboard.copyJSONLines": "JSON lines/NDJSONとしてコピー", + "clipboard.copyMongoInsert": "Mongo INSERT文としてコピー", + "clipboard.copyOnlyHeadres": "ヘッダーのみコピー", + "clipboard.copySQLInsert": "SQL INSERT文としてコピー", + "clipboard.copySQLUpdate": "SQL UPDATE文としてコピー", + "clipboard.copyWithHeaders": "ヘッダー付きでコピー", + "clipboard.copyWithoutHeaders": "ヘッダーなしでコピー", + "clipboard.copyYAML": "YAMLとしてコピー", + "clipboard.mongoInsert": "Mongo INSERT文", + "clipboard.onlyHeaders": "ヘッダーのみ", + "clipboard.withHeaders": "ヘッダー付き", + "clipboard.withoutHeaders": "ヘッダーなし", + "column.addNew": "新しいカラムを追加", + "column.copyName": "名前をコピー", + "column.dropColumn": "カラムを削除", + "column.fixed": "固定カラム(SQLのような)", + "column.name": "カラム名", + "column.renameColumn": "カラム名を変更", + "column.search": "カラムを検索", + "column.variable": "可変カラム(MongoDBのような)", + "columnEditor.addColumn": "カラム {columnNumber} を追加", + "columnEditor.autoIncrement": "自動増分", + "columnEditor.columnComment": "コメント", + "columnEditor.columnName": "カラム名", + "columnEditor.computedExpression": "計算式", + "columnEditor.defaultValue": "デフォルト値。有効なSQL式を使用してください。例:文字列値の場合は 'Hello World'、空文字列の場合は ''", + "columnEditor.editColumn": "カラムを編集", + "columnEditor.isPrimaryKey": "主キー", + "columnEditor.isSparse": "スパース", + "columnEditor.isUnsigned": "符号なし", + "columnEditor.isZerofill": "ゼロ埋め", + "columnsConstraintEditor.addNewColumn": "新しいカラムを追加", + "columnsConstraintEditor.chooseColumn": "カラムを選択", + "columnsConstraintEditor.selectColumn": "カラムを選択", + "command.about": "について", + "command.about.show": "表示", + "command.about.toolbar": "について", + "command.app.checkForUpdates": "更新を確認", + "command.app.disconnect": "切断", + "command.app.loggedUser": "ログインユーザー", + "command.app.logout": "ログアウト", + "command.application": "アプリケーション", + "command.application.becomeSponsor": "スポンサーになる", + "command.application.documentation": "ドキュメント", + "command.application.maximize": "最大化", + "command.application.minimize": "最小化", + "command.application.openIssue": "問題や機能リクエストを報告", + "command.application.reload": "再読み込み", + "command.application.toggleDevTools": "開発者ツールの切り替え", + "command.application.toggleFullScreen": "全画面表示の切り替え", + "command.application.unsetCurrentDatabase": "現在のデータベースを解除", + "command.application.web": "DbGate web", + "command.application.zoomIn": "拡大", + "command.application.zoomOut": "縮小", + "command.application.zoomReset": "ズームをリセット", + "command.archiveFile": "アーカイブファイル", + "command.archiveFile.save": "保存", + "command.archiveFile.saveAs": "名前を付けて保存", + "command.cloud": "クラウド", + "command.cloud.logout": "ログアウト", + "command.collectionData": "コレクションデータ", + "command.collectionData.collapseAll": "すべて折りたたむ", + "command.collectionData.expandAll": "すべて展開", + "command.collectionData.save": "保存", + "command.commandPalette": "コマンドパレット", + "command.commandPalette.show": "表示", + "command.copy": "コピー", + "command.dataForm": "データフォーム", + "command.dataForm.addToFilter": "フィルターに追加", + "command.dataForm.copyToClipboard": "クリップボードにコピー", + "command.dataForm.filterSelected": "この値でフィルター", + "command.dataForm.goToFirst": "最初", + "command.dataForm.goToLast": "最後", + "command.dataForm.goToNext": "次へ", + "command.dataForm.goToPrevious": "前へ", + "command.dataForm.redo": "やり直す", + "command.dataForm.removeField": "フィールドを削除", + "command.dataForm.revertRowChanges": "行の変更を元に戻す", + "command.dataForm.setNull": "NULLに設定", + "command.dataForm.undo": "元に戻す", + "command.dataGrid": "データグリッド", + "command.dataGrid.export": "エクスポート", + "command.dataGrid.openQuery": "クエリを開く", + "command.dataGrid.reconnect": "再接続", + "command.database": "データベース", + "command.database.changeRecent": "最近使用したものに変更", + "command.database.changeStatus": "ステータスを変更", + "command.database.chat": "データベースチャット", + "command.database.compare": "データベースを比較", + "command.database.databaseSearch": "データベース検索", + "command.database.export": "データベースをエクスポート", + "command.database.search": "検索", + "command.database.switchRecent": "最近使用したデータベースに切り替え", + "command.datagrid": "データグリッド", + "command.datagrid.addJsonDocument": "JSONドキュメントを追加", + "command.datagrid.addNewColumn": "新しいカラムを追加", + "command.datagrid.addNewColumn.toolbar": "新しいカラム", + "command.datagrid.autoRefresh.seconds": "秒", + "command.datagrid.clearFilter": "フィルターをクリア", + "command.datagrid.cloneRows": "行を複製", + "command.datagrid.cloneRows.toolbar": "行を複製", + "command.datagrid.copyToClipboard": "クリップボードにコピー", + "command.datagrid.deleteSelectedRows": "選択した行を削除", + "command.datagrid.deleteSelectedRows.toolbar": "行を削除", + "command.datagrid.editCell": "セルの値を編集", + "command.datagrid.editJsonDocument": "行をJSONドキュメントとして編集", + "command.datagrid.editSelection": "選択範囲をテーブルとして編集", + "command.datagrid.filterSelected": "選択した値でフィルター", + "command.datagrid.findColumn": "カラムを検索", + "command.datagrid.generateSql": "SQLを生成", + "command.datagrid.insertNewRow": "新しい行を挿入", + "command.datagrid.insertNewRow.toolbar": "新しい行", + "command.datagrid.loadCellFromFile": "ファイルからセルを読み込み", + "command.datagrid.openJsonArrayInSheet": "配列をテーブルとして開く", + "command.datagrid.openSelectionInMap": "選択範囲をマップで開く", + "command.datagrid.reconnect": "再接続", + "command.datagrid.redo": "やり直す", + "command.datagrid.removeField": "フィールドを削除", + "command.datagrid.revertAllChanges": "すべての変更を元に戻す", + "command.datagrid.revertAllChanges.toolbar": "すべて元に戻す", + "command.datagrid.revertRowChanges": "行の変更を元に戻す", + "command.datagrid.saveCellToFile": "セルをファイルに保存", + "command.datagrid.sendToDataDeployer": "データデプロイヤーに送信", + "command.datagrid.setAutoRefresh.1": "1秒ごとに更新", + "command.datagrid.setAutoRefresh.10": "10秒ごとに更新", + "command.datagrid.setAutoRefresh.15": "15秒ごとに更新", + "command.datagrid.setAutoRefresh.30": "30秒ごとに更新", + "command.datagrid.setAutoRefresh.5": "5秒ごとに更新", + "command.datagrid.setAutoRefresh.60": "60秒ごとに更新", + "command.datagrid.setNull": "NULLに設定", + "command.datagrid.startAutoRefresh": "自動更新を開始", + "command.datagrid.stopAutoRefresh": "自動更新を停止", + "command.datagrid.switchToJSON": "JSONに切り替え", + "command.datagrid.switchToform": "フォームに切り替え", + "command.datagrid.toggleLeftPanel": "左パネルの切り替え", + "command.datagrid.undo": "元に戻す", + "command.datagrid.viewJsonDocument": "行をJSONドキュメントとして表示", + "command.datagrid.viewJsonValue": "セルをJSONドキュメントとして表示", + "command.datagrid.witchToTable": "テーブルに切り替え", + "command.datgrid.hideColumn": "カラムを非表示", + "command.designer": "デザイナー", + "command.designer.arrange": "配置", + "command.designer.exportDiagram": "ダイアグラムをエクスポート", + "command.designer.remove": "削除", + "command.designer.removeSelectedTables": "選択したテーブルを削除", + "command.diagram": "ダイアグラム", + "command.edit": "編集", + "command.edit.copy": "コピー", + "command.edit.cut": "切り取り", + "command.edit.paste": "貼り付け", + "command.edit.redo": "やり直す", + "command.edit.selectAll": "すべて選択", + "command.edit.undo": "元に戻す", + "command.execute": "実行", + "command.favoriteJsonEditor": "お気に入りJSONエディター", + "command.favoriteJsonEditor.preview": "プレビュー", + "command.favoriteJsonEditor.save": "保存", + "command.file": "ファイル", + "command.file.exit": "終了", + "command.file.import": "データをインポート", + "command.file.open": "開く", + "command.file.openArchive": "DBモデル/アーカイブを開く", + "command.file.quit": "終了", + "command.file.resetLayout": "レイアウトデータと設定をリセット", + "command.file.resetLayoutConfirm": "レイアウトデータを本当にリセットしますか?開いているすべてのタブ、設定、レイアウトデータが失われます。接続と保存されたファイルは保持されます。その後、変更を適用するためにDbGateを再起動してください。", + "command.find": "検索", + "command.folder": "フォルダー", + "command.folder.openData": "データフォルダーを開く", + "command.folder.openLogs": "ログを開く", + "command.internal": "内部", + "command.internal.loadCampaigns": "キャンペーンリストを読み込み", + "command.internal.showCampaigns": "キャンペーンを表示", + "command.jsonl.closePreview": "プレビューを閉じる", + "command.jsonl.preview": "プレビュー", + "command.jsonl.previewNewTab": "新しいタブでプレビュー", + "command.jsonl.save": "保存", + "command.kill": "強制終了", + "command.markdown.preview": "プレビュー", + "command.new": "新規", + "command.new.JSShell": "新しいJavaScriptシェル", + "command.new.application": "アプリケーション", + "command.new.archiveFolder": "アーカイブフォルダー", + "command.new.collection": "コレクション", + "command.new.collectionToolbar": "新しいコレクション/コンテナー", + "command.new.connection": "接続を追加", + "command.new.connectionCloud": "クラウド上の接続", + "command.new.connectionFolder": "接続フォルダー", + "command.new.connectionFolderToolbar": "接続フォルダーを追加", + "command.new.diagram": "ERダイアグラム", + "command.new.duckdbDatabase": "新しいDuckDBデータベース", + "command.new.jsonl": "JSON Lines", + "command.new.markdown": "Markdownページ", + "command.new.modelCompare": "DBを比較", + "command.new.modelTransform": "モデル変換", + "command.new.newApplication": "新しいアプリケーション", + "command.new.newDiagram": "新しいERダイアグラム", + "command.new.newJsonl": "新しいJSON linesファイル", + "command.new.newModelTransform": "新しいモデル変換", + "command.new.newPerspective": "新しいパースペクティブ", + "command.new.newQueryDesign": "新しいクエリデザイン", + "command.new.perspective": "パースペクティブ", + "command.new.query": "クエリ", + "command.new.queryDesign": "クエリデザイン", + "command.new.queryToolbar": "新しいクエリ", + "command.new.shell": "JavaScriptシェル", + "command.new.sqliteDatabase": "新しいSQLiteデータベース", + "command.new.table": "テーブル", + "command.new.tableToolbar": "新しいテーブル", + "command.openQuery": "クエリを開く", + "command.paste": "貼り付け", + "command.query": "クエリ", + "command.query.AiAssistant": "AIアシスタント", + "command.query.autocommitOffSwitch": "自動コミット: OFF", + "command.query.autocommitOnSwitch": "自動コミット: ON", + "command.query.beginTransaction": "トランザクションを開始", + "command.query.commitTransaction": "トランザクションをコミット", + "command.query.commitTransactionToolbar": "コミット", + "command.query.executeCurrent": "現在のものを実行", + "command.query.formatCode": "コードをフォーマット", + "command.query.insertSqlJoin": "SQL JOINを挿入", + "command.query.rollbackTransaction": "トランザクションをロールバック", + "command.query.rollbackTransactionToolbar": "ロールバック", + "command.query.toggleAutoExecute": "自動実行の切り替え", + "command.query.toggleFixedConnection": "固定接続の切り替え", + "command.query.toggleVisibleResultTabs": "結果タブの表示切り替え", + "command.queryData": "データをクエリ", + "command.queryData.stopLoading": "読み込みを停止", + "command.redo": "やり直す", + "command.replace": "置換", + "command.save": "保存", + "command.saveAs": "名前を付けて保存", + "command.saveToDisk": "ディスクに保存", + "command.serverSummary": "サーバー概要", + "command.settings": "設定", + "command.settings.change": "変更", + "command.settings.exportConnections": "接続をエクスポート", + "command.settings.importConnections": "接続をインポート", + "command.settings.shortcuts": "キーボードショートカット", + "command.shell.copyNodeScript": "nodejsスクリプトをコピー", + "command.sidebar": "サイドバー", + "command.sidebar.show": "表示", + "command.sidebar.toggleToolbar": "サイドバーの切り替え", + "command.sql": "SQL", + "command.sql.generator": "SQLジェネレーター", + "command.sqlObject": "SQLオブジェクト", + "command.sqlObject.find": "検索", + "command.tableData": "テーブルデータ", + "command.tableData.save": "保存", + "command.tableEditor": "テーブルエディター", + "command.tableEditor.reset": "変更をリセット", + "command.tableEditor.save": "保存", + "command.tabs": "タブ", + "command.tabs.addToFavorites": "現在のタブをお気に入りに追加", + "command.tabs.changelog": "変更履歴", + "command.tabs.closeAll": "すべてのタブを閉じる", + "command.tabs.closeTab": "タブを閉じる", + "command.tabs.closeTabsButCurrentDb": "現在のDB以外のタブを閉じる", + "command.tabs.closeTabsWithCurrentDb": "現在のDBのタブを閉じる", + "command.tabs.nextTab": "次のタブ", + "command.tabs.previousTab": "前のタブ", + "command.tabs.reopenClosedTab": "閉じたタブを再度開く", + "command.theme": "テーマ", + "command.theme.change": "変更", + "command.theme.changeToolbar": "テーマを変更", + "command.toggleComment": "コメントの切り替え", + "command.toolbar": "ツールバー", + "command.toolbar.hide": "非表示", + "command.toolbar.show": "表示", + "command.undo": "元に戻す", + "command.view": "表示", + "command.view.reset": "表示をリセット", + "command.view.restart": "変更を適用するためにDbGateを再起動(またはWebで再読み込み)してください", + "commandModal.category": "カテゴリー", + "commandModal.configure": "コマンドを設定", + "commandModal.keyboard": "キーボード", + "commandModal.keyboardShortcut": "キーボードショートカット", + "commandModal.name": "名前", + "commandModal.showKeyCombination": "希望するキー組み合わせを表示してENTERを押してください", + "common.addNew": "新規追加", + "common.advanced": "詳細設定", + "common.archive": "アーカイブ (JSONL)", + "common.cancel": "キャンセル", + "common.close": "閉じる", + "common.column": "カラム ", + "common.compare": "データベースを比較", + "common.connection": "接続", + "common.connectionOnCloud": "クラウド上の接続", + "common.connections": "接続", + "common.createNew": "新規作成", + "common.data": "データ", + "common.database": "データベース", + "common.databaseChat": "データベースチャット", + "common.datagrid.deepRefresh": "構造とともに更新", + "common.delete": "削除", + "common.description": "説明", + "common.erDiagram": "ERダイアグラム", + "common.error": "エラー", + "common.execute": "実行", + "common.export": "エクスポート", + "common.exportDatabase": "データベースをエクスポート", + "common.featurePremium": "この機能はDbGate Premiumでのみ利用可能です", + "common.general": "一般", + "common.import": "インポート", + "common.kill": "強制終了", + "common.loadingData": "データを読み込み中", + "common.name": "名前", + "common.notSelectedOptional": "(未選択 - オプション)", + "common.parameters": "パラメーター", + "common.passwordEncrypted": "パスワードは暗号化されています", + "common.perspective": "パースペクティブ", + "common.query": "クエリ", + "common.queryDesigner": "クエリデザイナー", + "common.queryEditor": "SQLクエリエディター", + "common.refresh": "更新", + "common.remove": "削除", + "common.reset": "リセット", + "common.save": "保存", + "common.saveAndNext": "保存して次へ", + "common.saveToArchive": "アーカイブに保存", + "common.schema": "スキーマ", + "common.search": "検索", + "common.searchBy": "検索条件:", + "common.sqlGenerator": "SQLジェネレーター", + "common.table": "テーブル", + "common.testingConnection": "接続テスト中", + "connection.accessKeyId": "アクセスキーID", + "connection.allowedDatabases": "許可されたデータベース、1行に1つ", + "connection.allowedDatabasesRegex": "許可されたデータベースの正規表現", + "connection.askPassword": "保存せず、パスワードを問い合わせる", + "connection.askUser": "保存せず、ログインとパスワードを問い合わせる", + "connection.authentication": "認証", + "connection.autoDetectNatMap": "NATマップを自動検出(Dockerネットワーク内のRedisクラスターに使用)", + "connection.chooseType": "タイプを選択", + "connection.clientLibraryPath": "クライアントライブラリパス", + "connection.closeConfirm": "接続を閉じると {count} 個の開いているタブが閉じます。続けますか?", + "connection.clusterNodes": "クラスターノード", + "connection.color": "色", + "connection.connect": "接続", + "connection.connectionDefinition": "サービスアカウントキーJSON", + "connection.copyToCloudFolder": "クラウドフォルダーにコピー", + "connection.createDatabase": "データベースを作成", + "connection.createNewFolder": "接続フォルダーを作成", + "connection.createNewFolderName": "新しい接続フォルダー名", + "connection.database": "データベース名", + "connection.databaseFile": "データベースファイル", + "connection.databaseFilePath": "データベースファイル(サーバー上のパス)", + "connection.databaseUrl": "データベースURL", + "connection.defaultDatabase": "デフォルトデータベース", + "connection.delete": "削除", + "connection.deleteConfirm": "本当に接続 {name} を削除しますか?", + "connection.disconnect": "切断", + "connection.displayName": "表示名", + "connection.dockerWarning": "Docker内ではlocalhostと1270.0.1は機能しません。代わりにdockerhostを使用してください", + "connection.duplicate": "複製", + "connection.edit": "編集", + "connection.endpointKey": "キー", + "connection.engine": "データベースエンジン", + "connection.engineDriverNotFound": "エンジンドライバー {engine} が見つかりません。インストールされたプラグインを確認し、接続編集ダイアログでエンジンを変更してください", + "connection.fillDetails": "データベース接続詳細を入力", + "connection.isReadOnly": "読み取り専用", + "connection.keySeparator": "キーセパレーター", + "connection.localDataCenter": "ローカルデータセンター", + "connection.new.folder.title": "新しい接続フォルダーを追加", + "connection.new.title": "新しい接続を追加", + "connection.newQuery": "新しいクエリ(サーバー)", + "connection.password": "パスワード", + "connection.passwordMode": "パスワードモード", + "connection.recentUnsaved": "最近使用したものと未保存", + "connection.refresh": "更新", + "connection.refresh.title": "接続リストを更新", + "connection.saveEncrypted": "保存して暗号化", + "connection.saveRaw": "生のまま保存(危険!!)", + "connection.search.placeholder": "接続またはデータベースを検索", + "connection.secretAccessKey": "シークレットアクセスキー", + "connection.selectType": "(接続タイプを選択)", + "connection.server": "サーバー", + "connection.serverSummary": "サーバー概要", + "connection.serviceName": "サービス名", + "connection.singleDatabase": "データベース {defaultDatabase} のみを使用", + "connection.socketPath": "ソケットパス", + "connection.sshTunnel.agentFound": "SSHエージェントが見つかりました", + "connection.sshTunnel.agentNotFound": "SSHエージェントが見つかりません", + "connection.sshTunnel.authMethod.userPassword": "ユーザー名とパスワード", + "connection.sshTunnel.authentication": "SSH認証", + "connection.sshTunnel.keyFilePassphrase": "キーファイルのパスフレーズ", + "connection.sshTunnel.privateKeyFile": "秘密鍵ファイル", + "connection.sshTunnel.privateKeyFilePath": "秘密鍵ファイル(サーバー上のパス)", + "connection.sshTunnel.use": "SSHトンネルを使用", + "connection.ssl.caCert": "CA証明書(オプション)", + "connection.ssl.certificate": "証明書(オプション)", + "connection.ssl.certificateKeyFilePassword": "証明書キーファイルのパスワード(オプション)", + "connection.ssl.keyFile": "キーファイル(オプション)", + "connection.ssl.rejectUnauthorized": "未認証を拒否", + "connection.ssl.use": "SSLを使用", + "connection.trustServerCertificate": "サーバー証明書を信頼", + "connection.type": "接続タイプ", + "connection.useSeparateSchemas": "スキーマを個別に使用(多数の大きなスキーマがある場合に使用)", + "connection.useUrl": "データベースURLを使用", + "connection.user": "ユーザー", + "connection.viewDetails": "詳細を表示", + "connection.windowsDomain": "ドメイン(NTLM認証を使用する場合に指定)", + "dataForm.loadingRowCount": "行数を読み込み中...", + "dataForm.noData": "データがありません", + "dataForm.outOfBounds": "範囲外: {current} / {total}", + "dataForm.rowCount": "行: {current} / {total}", + "dataGrid.chooseValue": "{field} から値を選択", + "dataGrid.codeHighlighting": "コードハイライト:", + "dataGrid.codeHighlighting.none": "なし(生テキスト)", + "dataGrid.columns": "カラム", + "dataGrid.dependentTables": "依存テーブル", + "dataGrid.editCellValue": "セルの値を編集", + "dataGrid.filters": "フィルター", + "dataGrid.formatJson": "JSONをフォーマット", + "dataGrid.formatJson.invalid": "有効なJSONではありません", + "dataGrid.macros": "マクロ", + "dataGrid.multiColumnFilter": "複数カラムフィルター", + "dataGrid.references": "参照", + "dataGrid.referencesTables": "参照テーブル", + "dataGrid.searchReferences": "参照を検索", + "dataGrid.value": "値", + "database.backup": "バックアップ #", + "database.chooseArchiveFolderForDataDeployer": "データデプロイヤー用のアーカイブフォルダーを選択", + "database.closeConfirm": "接続を閉じると {count} 個の開いているタブが閉じます。続けますか?", + "database.compare": "比較", + "database.compareWithCurrentDb": "{name} と比較", + "database.copyDatabaseName": "データベース名をコピー", + "database.createDatabaseBackup": "データベースバックアップを作成", + "database.createNewApplication": "新しいアプリケーションを作成", + "database.dataDeployer": "データデプロイヤー", + "database.databaseChat": "データベースチャット", + "database.databaseProfiler": "データベースプロファイラー", + "database.designPerspectiveQuery": "パースペクティブクエリを設計", + "database.designQuery": "クエリを設計", + "database.diagram": "ダイアグラム #", + "database.disconnect": "切断", + "database.dropAllObjectsConfirm": "これによりスクリプトが生成され、実行後に {name} 内のすべてのオブジェクトが削除されます。続けますか?", + "database.dropConfirm": "本当にデータベース {name} を削除しますか?このデータベースで開いているすべてのセッションが強制的に閉じられます。", + "database.dropDatabase": "データベースを削除", + "database.editApplications": "アプリケーションを編集", + "database.export": "エクスポート", + "database.exportDbModel": "DBモデルをエクスポート", + "database.generateScript": "スクリプトを生成", + "database.import": "インポート", + "database.newCollection": "新しいコレクション/コンテナー", + "database.newQuery": "新しいクエリ", + "database.newTable": "新しいテーブル", + "database.perspective": "パースペクティブ #", + "database.profiler": "プロファイラー", + "database.queryDesigner": "クエリ #", + "database.refreshSchemas": "スキーマを更新", + "database.restore": "復元 #", + "database.restoreDatabaseBackup": "データベースバックアップを復元", + "database.shellDropAllObjects": "シェル: すべてのオブジェクトを削除", + "database.shellRunScript": "シェル: スクリプトを実行", + "database.shellTitle": "シェル #", + "database.showDiagram": "ダイアグラムを表示", + "database.sqlGenerator": "SQLジェネレーター", + "datagrid.closeTabs.close": "タブを閉じる", + "datagrid.closeTabs.header": "タブを閉じることを確認", + "datagrid.closeTabs.modifiedFiles": "次のファイルが変更されています。本当にタブを閉じますか?閉じた後、履歴から再度開くことができます", + "datagrid.columnNameFilter": "カラム名フィルター", + "datagrid.copyAdvanced": "高度なコピー", + "datagrid.macros.calculation": "Calculation", + "datagrid.macros.calculationDescription": "Custom expression. Use row.column_name for accessing column values, value for original value", + "datagrid.macros.changeTextCase": "Change text case", + "datagrid.macros.changeTextCaseDescription": "Uppercase, lowercase and other case functions", + "datagrid.macros.changeTextCaseType": "Type", + "datagrid.macros.currentDate": "Current date", + "datagrid.macros.currentDateDescription": "Gets current date", + "datagrid.macros.dayName": "Day name", + "datagrid.macros.delimiter": "Delimiter", + "datagrid.macros.detail": "Macro detail", + "datagrid.macros.duplicateColumns": "Duplicate columns", + "datagrid.macros.duplicateColumnsDescription": "Duplicate selected columns", + "datagrid.macros.expression": "Expression", + "datagrid.macros.extractDateFields": "Extract date fields", + "datagrid.macros.extractDateFieldsDescription": "Extract year, month, day and other date/time fields from selection and adds it as new columns", + "datagrid.macros.format": "Format", + "datagrid.macros.generateUUID": "Generate UUID", + "datagrid.macros.generateUUIDDescription": "Generate unique identifier", + "datagrid.macros.hourName": "Hour name", + "datagrid.macros.minuteName": "Minute name", + "datagrid.macros.monthName": "Month name", + "datagrid.macros.noParameters": "This macro has no parameters", + "datagrid.macros.padCharacter": "Character", + "datagrid.macros.padLeft": "Pad left", + "datagrid.macros.padLeftDescription": "Returns string of a specified length in which the beginning of the current string is padded with spaces or other character", + "datagrid.macros.padLength": "Length", + "datagrid.macros.padRight": "Pad right", + "datagrid.macros.padRightDescription": "Returns string of a specified length in which the end of the current string is padded with spaces or other character", + "datagrid.macros.postfix": "Postfix", + "datagrid.macros.prefix": "Prefix", + "datagrid.macros.removeDiacritics": "Remove diacritics", + "datagrid.macros.removeDiacriticsDescription": "Removes diacritics from selected cells", + "datagrid.macros.rowIndex": "Row index", + "datagrid.macros.rowIndexDescription": "Index of row from 1 (autoincrement)", + "datagrid.macros.searchReplaceText": "Search & replace text", + "datagrid.macros.searchReplaceTextCaseSensitive": "Case sensitive", + "datagrid.macros.searchReplaceTextDescription": "Search & replace text or regular expression", + "datagrid.macros.searchReplaceTextFind": "Find", + "datagrid.macros.searchReplaceTextIsRegex": "Regular expression", + "datagrid.macros.searchReplaceTextReplaceWith": "Replace with", + "datagrid.macros.secondName": "Second name", + "datagrid.macros.splitColumns": "Split columns", + "datagrid.macros.splitColumnsDescription": "Split selected columns", + "datagrid.macros.textGroup": "Text", + "datagrid.macros.toBoolean": "Convert to boolean", + "datagrid.macros.toBooleanDescription": "Converts to boolean", + "datagrid.macros.toInt": "Convert to integer", + "datagrid.macros.toIntDescription": "Converts to integral number", + "datagrid.macros.toNumber": "Convert to number", + "datagrid.macros.toNumberDescription": "Converts to number", + "datagrid.macros.toString": "Convert to string", + "datagrid.macros.toStringDescription": "Converts to string", + "datagrid.macros.toolsGroup": "Tools", + "datagrid.macros.trim": "Trim", + "datagrid.macros.trimDescription": "Removes leading and trailing whitespace", + "datagrid.macros.version": "Version", + "datagrid.macros.yearName": "Year name", + "datagrid.searchMacros": "Search macros", + "datagrid.setFormat": "Set format: ", + "datagrid.structure": "Structure", + "dbObject.collections": "コレクション/コンテナー", + "dbObject.confirmCloneCollection": "本当に {name} という名前のコレクション/コンテナーのコピーを作成しますか?", + "dbObject.confirmDropCollection": "本当にコレクション {name} を削除しますか?", + "dbObject.copyTableName": "テーブル名をコピー", + "dbObject.createCollection": "コレクション/コンテナーを作成", + "dbObject.createCollectionBackup": "コレクション/コンテナーバックアップを作成", + "dbObject.createTableBackup": "テーブルバックアップを作成", + "dbObject.designPerspectiveQuery": "パースペクティブクエリを設計", + "dbObject.designQuery": "クエリを設計", + "dbObject.diagram": "ダイアグラム #", + "dbObject.disable": "無効化", + "dbObject.dropCollection": "コレクション/コンテナーを削除", + "dbObject.dropEvent": "イベントを削除", + "dbObject.dropProcedure": "プロシージャを削除", + "dbObject.dropTable": "テーブルを削除", + "dbObject.dropTrigger": "トリガーを削除", + "dbObject.dropView": "ビューを削除", + "dbObject.enable": "有効化", + "dbObject.functions": "関数", + "dbObject.matviews": "マテリアライズドビュー", + "dbObject.newCollectionName": "新しいコレクション/コンテナー名", + "dbObject.openData": "データを開く", + "dbObject.openJson": "JSONを開く", + "dbObject.openRawData": "生データを開く", + "dbObject.openStructure": "構造を開く", + "dbObject.procedures": "プロシージャ", + "dbObject.query": "クエリ #", + "dbObject.queryDesigner": "クエリデザイナー", + "dbObject.renameCollection": "コレクション/コンテナー名を変更", + "dbObject.renameProcedure": "プロシージャ名を変更", + "dbObject.renameTable": "テーブル名を変更", + "dbObject.renameView": "ビュー名を変更", + "dbObject.schedulerEvents": "スケジューラーイベント", + "dbObject.showDiagram": "ダイアグラムを表示", + "dbObject.showQuery": "クエリを表示", + "dbObject.showSql": "SQLを表示", + "dbObject.sqlGenerator": "SQLジェネレーター", + "dbObject.sqlTemplate": "SQLテンプレート", + "dbObject.tables": "テーブル", + "dbObject.triggers": "トリガー", + "dbObject.truncateTable": "テーブルをトランケート", + "dbObject.views": "ビュー", + "error.driverNotFound": "無効なデータベース接続、ドライバーが見つかりません", + "error.selectedCloudConnection": "選択された接続はDbGateクラウドからのものです", + "error.selectedNotCloudConnection": "選択された接続はDbGateクラウドからのものではありません", + "export.currentArchive": "現在のアーカイブ", + "export.exportAdvanced": "高度なエクスポート...", + "export.result": "エクスポート結果", + "file.allSupported": "サポートされているすべてのファイル", + "file.diagramFiles": "ダイアグラムファイル", + "file.duckdb": "DuckDBデータベース", + "file.jsonFiles": "JSONファイル", + "file.perspectiveFiles": "パースペクティブファイル", + "file.queryDesignerFiles": "クエリデザイナーファイル", + "file.sqlFiles": "SQLファイル", + "file.sqliteDatabase": "SQLiteデータベース", + "filter.after": "以降...", + "filter.and": "かつ", + "filter.arrayIsEmpty": "配列が空", + "filter.arrayIsNotEmpty": "配列が空ではない", + "filter.before": "以前...", + "filter.beginsWith": "で始まる...", + "filter.between": "の間...", + "filter.clear": "フィルターをクリア", + "filter.contains": "を含む...", + "filter.doesNotBeginWith": "で始まらない...", + "filter.doesNotContain": "を含まない...", + "filter.doesNotEndWith": "で終わらない...", + "filter.doesNotEqual": "等しくない...", + "filter.endsWith": "で終わる...", + "filter.equals": "等しい...", + "filter.fieldDoesNotExist": "フィールドが存在しない", + "filter.fieldExists": "フィールドが存在する", + "filter.greaterThan": "より大きい...", + "filter.greaterThanOrEqualTo": "以上...", + "filter.hasNotEmptyValue": "空でない値を持つ", + "filter.isAfter": "以降", + "filter.isAfterOrEqual": "以降または等しい", + "filter.isBefore": "以前", + "filter.isBeforeOrEqual": "以前または等しい", + "filter.isEmptyOrNull": "空またはNULL", + "filter.isFalse": "偽", + "filter.isFalseOrNull": "偽またはNULL", + "filter.isGreater": "より大きい", + "filter.isGreaterOrEqual": "以上", + "filter.isNotNull": "NULLではない", + "filter.isNull": "NULL", + "filter.isSmaller": "より小さい", + "filter.isSmallerOrEqual": "以下", + "filter.isTrue": "真", + "filter.isTrueOrNull": "真またはNULL", + "filter.lastMonth": "先月", + "filter.lastWeek": "先週", + "filter.lastYear": "昨年", + "filter.lessThan": "より小さい...", + "filter.lessThanOrEqualTo": "以下...", + "filter.modal.beginsWith": "で始まる", + "filter.modal.contains": "を含む", + "filter.modal.doesNotBeginWith": "で始まらない", + "filter.modal.doesNotContain": "を含まない", + "filter.modal.doesNotEndWith": "で終わらない", + "filter.modal.doesNotEqual": "等しくない", + "filter.modal.endsWith": "で終わる", + "filter.modal.equals": "等しい", + "filter.modal.fieldDoesNotExist": "フィールドが存在しない", + "filter.modal.fieldExists": "フィールドが存在する", + "filter.modal.isNotNull": "NULLではない", + "filter.modal.isNull": "NULL", + "filter.modal.sqlCondition": "SQL条件", + "filter.modal.sqlConditionRight": "SQL条件 - 右側のみ", + "filter.multipleValues": "複数の値でフィルター", + "filter.nextMonth": "来月", + "filter.nextWeek": "来週", + "filter.nextYear": "来年", + "filter.or": "または", + "filter.setFilter": "フィルターを設定", + "filter.showRowsWhere": "次の条件の行を表示", + "filter.sqlCondition": "SQL条件 ...", + "filter.sqlConditionRight": "SQL条件 - 右側 ...", + "filter.thisMonth": "今月", + "filter.thisWeek": "今週", + "filter.thisYear": "今年", + "filter.today": "今日", + "filter.tomorrow": "明日", + "filter.yesterday": "昨日", + "foreignKey.baseColumns": "基本カラム", + "foreignKey.refColumns": "参照カラム", + "foreignKey.refTableName": "参照テーブル", + "foreignKeyEditor.addColumn": "カラムを追加", + "foreignKeyEditor.addForeignKey": "外部キーを追加", + "foreignKeyEditor.baseColumn": "基本カラム - ", + "foreignKeyEditor.editForeignKey": "外部キーを編集", + "foreignKeyEditor.onDeleteAction": "削除時の動作", + "foreignKeyEditor.onUpdateAction": "更新時の動作", + "foreignKeyEditor.refColumn": "参照カラム - ", + "foreignKeyEditor.referencedTable": "参照テーブル", + "foreignKeyEditor.tableNotSet": "(テーブルが未設定)", + "importExport.createZipFileInArchive": "アーカイブ内にZIPファイルを作成", + "importExport.exportToZipArchive": "ZIPアーカイブを出力", + "importExport.exportToZipFile": "ZIPファイルにエクスポート", + "importExport.importFromZipArchive": "ZIPアーカイブを入力", + "importExport.importFromZipFile": "ZIPファイルからインポート(アーカイブフォルダー内)", + "importExport.sourceFiles": "ソースファイル", + "importExport.tablesViewsCollections": "テーブル / ビュー / コレクション", + "indexEditor.filteredIndexCondition": "フィルター済みインデックス条件", + "indexEditor.indexName": "インデックス名", + "indexEditor.isUnique": "一意インデックス", + "menu.edit": "編集", + "menu.file": "ファイル", + "menu.help": "ヘルプ", + "menu.tools": "ツール", + "menu.view": "表示", + "newObject.compareDescription": "データベーススキーマを比較", + "newObject.compareDisabled": "現在のデータベースでは比較機能が利用できません", + "newObject.connectionLocal": "ローカルに保存されたデータベース接続", + "newObject.connectionLocalDisabled": "新しい接続を作成する権限がありません", + "newObject.connectionOnCloudDescription": "DbGateクラウドに保存されたデータベース接続", + "newObject.connectionOnCloudDisabled": "DbGateクラウドに接続を作成するにはログインが必要です", + "newObject.databaseChatDescription": "AIを使用してデータベースとチャット", + "newObject.databaseChatDisabled": "現在のデータベースではデータベースチャットが利用できません", + "newObject.erDiagramDescription": "データベース構造を可視化", + "newObject.erDiagramDisabled": "現在のデータベースではER図が利用できません", + "newObject.exportDescription": "CSV、JSON、Excel、または他のDBにエクスポート", + "newObject.exportDisabled": "現在のデータベースではエクスポートが利用できません", + "newObject.perspectiveDescription": "複数のデータベースから複雑なデータを結合", + "newObject.queryDesignerDescription": "SQLクエリをビジュアルに設計", + "newObject.queryDesignerDisabled": "現在のデータベースではクエリデザイナーが利用できません", + "newObject.sqlGeneratorDescription": "データベースオブジェクトのSQLスクリプトを生成", + "newObject.sqlGeneratorDisabled": "現在のデータベースではSQLジェネレーターが利用できません", + "newObject.tableDescription": "現在のデータベースにテーブルを作成", + "newObject.tableDisabled": "現在のデータベースではテーブル作成が利用できません", + "query.limitRows": "{queryRowsLimit}行に制限", + "query.named": ":variable", + "query.noParameters": "(パラメーターなし)", + "query.positional": "? (位置指定)", + "query.unlimitedRows": "無制限", + "query.variable": "#variable", + "schema.add": "新しいスキーマを追加", + "schema.allSchemas": "すべてのスキーマ ({count})", + "schema.createSchema": "スキーマを作成", + "schema.delete": "スキーマを削除", + "schema.resetToDefault": "デフォルトにリセット", + "schema.schemaName": "スキーマ名", + "serverSummaryTab.databases": "データベース", + "serverSummaryTab.errorTitle": "サーバー概要の読み込みエラー", + "serverSummaryTab.loadingMessage": "サーバー詳細を読み込み中", + "serverSummaryTab.processes": "プロセス", + "serverSummaryTab.variables": "変数", + "settings.appearance": "アプリケーションテーマ", + "settings.appearance.afterInstalling": "テーマプラグインをインストールすると(利用可能な拡張機能で\"theme\"を検索)、新しいテーマがここに表示されます。", + "settings.appearance.customSize": "カスタムサイズ", + "settings.appearance.editorTheme": "テーマ", + "settings.appearance.editorTheme.default": "(テーマのデフォルトを使用)", + "settings.appearance.fontFamily": "エディターのフォントファミリー", + "settings.appearance.fontSize": "フォントサイズ", + "settings.appearance.moreThemes": "さらに多くのテーマが次の形式で利用可能", + "settings.appearance.useSystemTheme": "システムテーマを使用", + "settings.behaviour": "動作", + "settings.behaviour.jsonPreviewWrap": "プレビューでJSONを折り返す", + "settings.behaviour.openDetailOnArrows": "キーボードナビゲーションで詳細を開く", + "settings.behaviour.singleClickPreview": "\"テーブル、ビュー、関数\"ビューでファイルをシングルクリックまたは選択すると、プレビューモードで表示され、既存のタブ(プレビュータブ)が再利用されます。これは、テーブルを素早く閲覧している際に、訪れたすべてのテーブルに独自のタブを持たせたくない場合に便利です。テーブルの編集を開始するか、\"テーブル\"ビューからダブルクリックでテーブルを開くと、そのテーブル専用の新しいタブが作成されます。", + "settings.behaviour.useTabPreviewMode": "タブプレビューモードを使用", + "settings.confirmations": "確認", + "settings.confirmations.skipConfirm.collectionDataSave": "コレクションデータ保存時の確認をスキップ (NoSQL)", + "settings.confirmations.skipConfirm.tableDataSave": "テーブルデータ保存時の確認をスキップ (SQL)", + "settings.connection": "接続", + "settings.connection.autoRefresh": "バックグラウンドでデータベースモデルを自動更新", + "settings.connection.autoRefreshInterval": "DB構造の自動再読み込み間隔(秒)", + "settings.connection.showOnlyTabsFromSelectedDatabase": "選択されたデータベースのタブのみ表示", + "settings.connection.sshBindHost": "SSH接続用のローカルホストアドレス", + "settings.dataGrid.alignNumbersRight": "数値を右揃え", + "settings.dataGrid.collectionPageSize": "コレクションページサイズ(MongoDB JSONビュー用、5から1000の間)", + "settings.dataGrid.coloringMode": "行の色分けモード", + "settings.dataGrid.coloringMode.2-primary": "2行ごと、プライマリカラー", + "settings.dataGrid.coloringMode.2-secondary": "2行ごと、セカンダリカラー", + "settings.dataGrid.coloringMode.36": "3行目と6行目ごと", + "settings.dataGrid.coloringMode.none": "なし", + "settings.dataGrid.defaultAutoRefreshInterval": "デフォルトグリッド自動更新間隔(秒)", + "settings.dataGrid.pageSize": "ページサイズ(漸進的読み込みの行数5から50000の間)", + "settings.dataGrid.showAllColumnsWhenSearch": "検索時にすべてのカラムを表示", + "settings.dataGrid.showHintColumns": "外部キーヒントを表示", + "settings.dataGrid.thousandsSeparator": "数値に桁区切りを使用", + "settings.dataGrid.title": "データグリッド", + "settings.defaultActions": "デフォルト動作", + "settings.defaultActions.collectionClick": "NoSQLコレクションクリック", + "settings.defaultActions.connectionClick": "接続クリック", + "settings.defaultActions.connectionClick.connect": "接続", + "settings.defaultActions.connectionClick.none": "何もしない", + "settings.defaultActions.connectionClick.openDetails": "編集 / 詳細を開く", + "settings.defaultActions.databaseClick": "データベースクリック", + "settings.defaultActions.databaseClick.none": "何もしない", + "settings.defaultActions.databaseClick.switch": "データベースを切り替え", + "settings.defaultActions.functionClick": "関数クリック", + "settings.defaultActions.materializedViewClick": "マテリアライズドビュークリック", + "settings.defaultActions.procedureClick": "プロシージャクリック", + "settings.defaultActions.tableClick": "テーブルクリック", + "settings.defaultActions.useLastUsedAction": "前回使用した動作を使用", + "settings.defaultActions.viewClick": "ビュークリック", + "settings.editor.keybinds": "エディターキーバインド", + "settings.editor.wordWrap": "ワードラップを有効化", + "settings.externalTools": "外部ツール", + "settings.general": "一般", + "settings.license": "ライセンス", + "settings.localization": "ローカライゼーション", + "settings.localization.language": "言語", + "settings.localization.reloadWarning": "新しい言語設定を適用するためにアプリケーションが再読み込みされます", + "settings.nativeMenuRestartWarning": "ネイティブメニュー設定はアプリ再起動後に適用されます", + "settings.other": "その他", + "settings.other.ai.allowSendModels": "DBモデルとクエリスニペットをAIサービスに送信することを許可", + "settings.other.autoUpdateApplication": "アプリケーションの自動更新", + "settings.other.autoUpdateApplication.check": "新しいバージョンを確認", + "settings.other.autoUpdateApplication.download": "新しいバージョンを確認してダウンロード", + "settings.other.autoUpdateApplication.skip": "新しいバージョンを確認しない", + "settings.other.externalTools.mysql": "mysql(MySQLデータベースの復元)", + "settings.other.externalTools.mysqlPlugins": "mysqlプラグインのフォルダー(例:認証用)。問題がある場合のみ設定", + "settings.other.externalTools.mysqldump": "mysqldump(MySQLデータベースのバックアップ)", + "settings.other.externalTools.pg_dump": "pg_dump(PostgreSQLデータベースのバックアップ)", + "settings.other.externalTools.psql": "psql(PostgreSQLデータベースの復元)", + "settings.other.gistCreateToken": "エラーgist作成用のAPIトークン", + "settings.other.license": "ライセンス", + "settings.other.licenseKey": "ライセンスキー", + "settings.other.licenseKey.checkForNew": "新しいライセンスキーを確認", + "settings.other.licenseKey.expiration": "ライセンスキーの有効期限:", + "settings.other.licenseKey.invalid": "ライセンスキーが無効です", + "settings.other.licenseKey.valid": "ライセンスキーは有効です", + "settings.other.licenseKey.validTo": "ライセンス有効期限:", + "settings.session": "クエリセッション", + "settings.session.autoClose": "活動がない期間後にクエリセッションを自動的に閉じる", + "settings.session.autoCloseTimeout": "活動がないクエリセッションを閉じるまでの間隔(分)", + "settings.sqlEditor": "SQLエディター", + "settings.sqlEditor.disableExecuteCurrentLine": "現在の行の実行を無効化(現在を実行)", + "settings.sqlEditor.disableSplitByEmptyLine": "空行での分割を無効化", + "settings.sqlEditor.limitRows": "クエリからN行のみ返す", + "settings.sqlEditor.limitRowsPlaceholder": "(行数制限なし)", + "settings.sqlEditor.showTableAliasesInCodeCompletion": "コード補完にテーブルエイリアスを表示", + "settings.sqlEditor.sqlCommandsCase": "SQLコマンドの大文字小文字", + "settings.tabGroup.showServerName": "タブグループのタイトルにデータベース名と並んでサーバー名を表示", + "settings.theme": "テーマ", + "settings.title": "設定", + "settings.useNativeWindowTitle": "ネイティブウィンドウタイトルを使用", + "settings.useSystemNativeMenu": "システムネイティブメニューを使用", + "sqlObject.collectionName": "コレクション名", + "sqlObject.columnComment": "カラムコメント", + "sqlObject.columnDataType": "カラムデータ型", + "sqlObject.columnName": "カラム名", + "sqlObject.databaseEmpty": "データベース {database} が空か、構造が読み込まれていません。更新ボタンを押して構造を再読み込みしてください", + "sqlObject.loadingStructure": "データベース構造を読み込み中", + "sqlObject.newCollection": "新しいコレクション/コンテナー", + "sqlObject.schemaName": "スキーマ", + "sqlObject.search.placeholder": "テーブル、ビュー、プロシージャを検索", + "sqlObject.searchBy": "検索条件:", + "sqlObject.tableComment": "テーブルコメント", + "sqlObject.tableEngine": "テーブルエンジン", + "sqlObject.tableViewProcedureName": "テーブル/ビュー/プロシージャ名", + "sqlObject.tablesWithRows": "行があるテーブルのみ", + "sqlObject.viewProcedureTriggerText": "ビュー/プロシージャ/トリガーテキスト", + "sqlObjectList.refreshDatabase": "データベース接続とオブジェクトリストを更新", + "summaryProcesses.actions": "アクション", + "summaryProcesses.client": "クライアント", + "summaryProcesses.connectionId": "接続ID", + "summaryProcesses.killConfirm": "本当にプロセス {processId} を中止しますか?", + "summaryProcesses.killError": "プロセス {processId} の中止中にエラー:{errorMessage}", + "summaryProcesses.killSuccess": "プロセス {processId} を正常に中止しました", + "summaryProcesses.namespace": "名前空間", + "summaryProcesses.operation": "操作", + "summaryProcesses.processId": "プロセスID", + "summaryProcesses.runningTime": "実行時間", + "summaryProcesses.state": "状態", + "summaryProcesses.waitingFor": "待機中", + "summaryVariables.value": "値", + "summaryVariables.variable": "変数", + "tab.administration": "管理", + "tableData.viewColumns": "カラムを表示", + "tableEdit.addConstraintLabel": "{constraintLabel}を追加", + "tableEdit.editConstraintLabel": "{constraintLabel}を編集", + "tableEdit.unique": "一意", + "tableEditor": "テーブルエディター", + "tableEditor.addColumn": "カラムを追加", + "tableEditor.addForeignKey": "外部キーを追加", + "tableEditor.addIndex": "インデックスを追加", + "tableEditor.addPrimaryKey": "主キーを追加", + "tableEditor.addUnique": "一意制約を追加", + "tableEditor.columnComment": "コメント", + "tableEditor.columns": "カラム", + "tableEditor.computedExpression": "計算式", + "tableEditor.constraintName": "制約名", + "tableEditor.copydefinitions": "定義をコピー", + "tableEditor.copynames": "名前をコピー", + "tableEditor.dataType": "データ型", + "tableEditor.defaultValue": "デフォルト値", + "tableEditor.dependencies": "依存関係", + "tableEditor.foreignKeys": "外部キー ({foreignKeyCount})", + "tableEditor.indexes": "インデックス ({indexCount})", + "tableEditor.isPersisted": "永続化", + "tableEditor.isSparse": "疎", + "tableEditor.isUnsigned": "符号なし", + "tableEditor.isZeroFill": "ゼロ埋め", + "tableEditor.no": "NO", + "tableEditor.noConstraintDefined": "{constraintLabel}が定義されていません", + "tableEditor.nocolumnsdefined": "カラムが定義されていません", + "tableEditor.noforeignkeydefined": "外部キーが定義されていません", + "tableEditor.noindexdefined": "インデックスが定義されていません", + "tableEditor.notnull": "NOT NULL", + "tableEditor.nouniquedefined": "一意制約が定義されていません", + "tableEditor.null": "NULL", + "tableEditor.nullability": "NULL許可", + "tableEditor.primaryKey": "主キー", + "tableEditor.remove": "削除", + "tableEditor.tablename": "テーブル名", + "tableEditor.tableproperties": "テーブルプロパティ", + "tableEditor.unique": "一意", + "tableEditor.uniqueConstraints": "一意制約 ({constraintCount})", + "tableEditor.yes": "YES", + "tableStructure.alter": "テーブルを変更", + "tableStructure.create": "テーブルを作成", + "tabsPanel.addToFavorites": "お気に入りに追加", + "tabsPanel.closeAll": "すべて閉じる", + "tabsPanel.closeOthers": "他を閉じる", + "tabsPanel.closeTabsWithDb": "DB {database} のタブを閉じる", + "tabsPanel.closeTabsWithOtherDb": "{database} 以外のDBのタブを閉じる", + "tabsPanel.closeToTheRight": "右側を閉じる", + "tabsPanel.duplicate": "複製", + "tabsPanel.pinTab": "タブを固定", + "tabsPanel.switchDatabase": "データベースを切り替え", + "widget.collectionsContainers": "コレクション/コンテナー", + "widget.databaseContent": "データベースの内容", + "widget.databases": "データベース", + "widget.keys": "キー", + "widget.pinned": "固定済み", + "widget.tablesViewsFunctions": "テーブル、ビュー、関数", + "widgets.managePlugins": "プラグインを管理", + "widgets.viewApplicationLogs": "アプリケーションログを表示" +} \ No newline at end of file From da224303fe276337601295b6445ebd5dfbcbe6e9 Mon Sep 17 00:00:00 2001 From: Stela Augustinova Date: Mon, 24 Nov 2025 16:29:29 +0100 Subject: [PATCH 15/76] Translation - added translation tags for widgets --- .../web/src/buttons/InlineUploadButton.svelte | 5 +++-- packages/web/src/buttons/UploadButton.svelte | 3 ++- .../web/src/designer/DesignerTable.svelte | 17 ++++++++-------- .../src/plugins/AvailablePluginsList.svelte | 3 ++- .../web/src/widgets/CellDataWidget.svelte | 11 +++++----- packages/web/src/widgets/FilesWidget.svelte | 4 ++-- packages/web/src/widgets/HistoryWidget.svelte | 5 +++-- packages/web/src/widgets/PluginsWidget.svelte | 6 ++++-- .../web/src/widgets/PublicCloudWidget.svelte | 8 ++++---- .../web/src/widgets/QueryHistoryList.svelte | 5 +++-- .../web/src/widgets/SavedFilesList.svelte | 11 +++++----- .../web/src/widgets/WidgetIconPanel.svelte | 20 +++++++++---------- 12 files changed, 54 insertions(+), 44 deletions(-) diff --git a/packages/web/src/buttons/InlineUploadButton.svelte b/packages/web/src/buttons/InlineUploadButton.svelte index 9c6d8bd92..7d1c6aa32 100644 --- a/packages/web/src/buttons/InlineUploadButton.svelte +++ b/packages/web/src/buttons/InlineUploadButton.svelte @@ -5,6 +5,7 @@ import getElectron from '../utility/getElectron'; import InlineButtonLabel from '../buttons/InlineButtonLabel.svelte'; import resolveApi, { resolveApiHeaders } from '../utility/resolveApi'; + import { _t } from '../translations'; import uuidv1 from 'uuid/v1'; @@ -49,11 +50,11 @@ {#if electron} - + {:else} - {}} title="Upload file" data-testid={$$props['data-testid']} htmlFor={inputId}> + {}} title={_t('files.uploadFile', { defaultMessage: "Upload file" })} data-testid={$$props['data-testid']} htmlFor={inputId}> {/if} diff --git a/packages/web/src/buttons/UploadButton.svelte b/packages/web/src/buttons/UploadButton.svelte index 0d9a18a22..33b9f6484 100644 --- a/packages/web/src/buttons/UploadButton.svelte +++ b/packages/web/src/buttons/UploadButton.svelte @@ -1,6 +1,7 @@
- Upload file + {_t('files.uploadFile', { defaultMessage: "Upload file" })}
diff --git a/packages/web/src/designer/DesignerTable.svelte b/packages/web/src/designer/DesignerTable.svelte index c94f12d51..c13099d48 100644 --- a/packages/web/src/designer/DesignerTable.svelte +++ b/packages/web/src/designer/DesignerTable.svelte @@ -17,6 +17,7 @@ import moveDrag from '../utility/moveDrag'; import ColumnLine from './ColumnLine.svelte'; import DomTableRef from './DomTableRef'; + import { _t } from '../translations'; export let conid; export let database; @@ -185,8 +186,8 @@ const handleSetTableAlias = () => { showModal(InputTextModal, { value: alias || '', - label: 'New alias', - header: 'Set table alias', + label: _t('designerTable.newAlias', { defaultMessage: 'New alias' }), + header: _t('designerTable.setTableAlias', { defaultMessage: 'Set table alias' }), onConfirm: newAlias => { onChangeTable({ ...table, @@ -210,13 +211,13 @@ return settings?.tableMenu({ designer, designerId, onRemoveTable }); } return [ - { text: 'Remove', onClick: () => onRemoveTable({ designerId }) }, + { text: _t('common.remove', { defaultMessage: 'Remove' }), onClick: () => onRemoveTable({ designerId }) }, { divider: true }, settings?.allowTableAlias && !isMultipleTableSelection && [ - { text: 'Set table alias', onClick: handleSetTableAlias }, + { text: _t('designerTable.setTableAlias', { defaultMessage: 'Set table alias' }), onClick: handleSetTableAlias }, alias && { - text: 'Remove table alias', + text: _t('designerTable.removeTableAlias', { defaultMessage: 'Remove table alias' }), onClick: () => onChangeTable({ ...table, @@ -225,11 +226,11 @@ }, ], settings?.allowAddAllReferences && - !isMultipleTableSelection && { text: 'Add references', onClick: () => onAddAllReferences(table) }, - settings?.allowChangeColor && { text: 'Change color', onClick: () => onChangeTableColor(table) }, + !isMultipleTableSelection && { text: _t('designerTable.addReferences', { defaultMessage: 'Add references' }), onClick: () => onAddAllReferences(table) }, + settings?.allowChangeColor && { text: _t('designerTable.changeColor', { defaultMessage: 'Change color' }), onClick: () => onChangeTableColor(table) }, settings?.allowDefineVirtualReferences && !isMultipleTableSelection && { - text: 'Define virtual foreign key', + text: _t('designerTable.defineVirtualForeignKey', { defaultMessage: 'Define virtual foreign key' }), onClick: () => handleDefineVirtualForeignKey(table), }, settings?.appendTableSystemMenu && diff --git a/packages/web/src/plugins/AvailablePluginsList.svelte b/packages/web/src/plugins/AvailablePluginsList.svelte index 650e536ba..0036c3e33 100644 --- a/packages/web/src/plugins/AvailablePluginsList.svelte +++ b/packages/web/src/plugins/AvailablePluginsList.svelte @@ -8,6 +8,7 @@ import WidgetsInnerContainer from '../widgets/WidgetsInnerContainer.svelte'; import PluginsList from './PluginsList.svelte'; import { filterName } from 'dbgate-tools'; + import { _t } from '../translations'; let filter = ''; // let search = ''; @@ -20,7 +21,7 @@ - + {#if $plugins?.errorMessage} diff --git a/packages/web/src/widgets/CellDataWidget.svelte b/packages/web/src/widgets/CellDataWidget.svelte index 783b8084c..8175b86e8 100644 --- a/packages/web/src/widgets/CellDataWidget.svelte +++ b/packages/web/src/widgets/CellDataWidget.svelte @@ -101,6 +101,7 @@ import WidgetTitle from './WidgetTitle.svelte'; import JsonExpandedCellView from '../celldata/JsonExpandedCellView.svelte'; import XmlCellView from '../celldata/XmlCellView.svelte'; + import { _t } from '../translations'; let selectedFormatType = 'autodetect'; @@ -116,7 +117,7 @@
- Cell data view + {_t('cellDataWidget.title', { defaultMessage: "Cell data view" })}
Format:  @@ -126,18 +127,18 @@ on:change={e => (selectedFormatType = e.detail)} data-testid="CellDataWidget_selectFormat" options={[ - { value: 'autodetect', label: `Autodetect - ${autodetectFormat.title}` }, + { value: 'autodetect', label: _t('cellDataWidget.autodetect', { defaultMessage: "Autodetect - {autoDetectTitle}", values : { autoDetectTitle: autodetectFormat.title } }) }, ...formats.map(fmt => ({ label: fmt.title, value: fmt.type })), ]} />
{#if usedFormat.single && selection?.length != 1} - + {:else if usedFormat == null} - + {:else if !selection || selection.length == 0} - + {:else} {/if} diff --git a/packages/web/src/widgets/FilesWidget.svelte b/packages/web/src/widgets/FilesWidget.svelte index 657b793e8..51a0ea96d 100644 --- a/packages/web/src/widgets/FilesWidget.svelte +++ b/packages/web/src/widgets/FilesWidget.svelte @@ -19,12 +19,12 @@ - + {#if hasPermission('files/favorites/read')} - + diff --git a/packages/web/src/widgets/HistoryWidget.svelte b/packages/web/src/widgets/HistoryWidget.svelte index a5210f26f..a9988f2de 100644 --- a/packages/web/src/widgets/HistoryWidget.svelte +++ b/packages/web/src/widgets/HistoryWidget.svelte @@ -13,13 +13,14 @@ import WidgetColumnBar from './WidgetColumnBar.svelte'; import WidgetColumnBarItem from './WidgetColumnBarItem.svelte'; import WidgetsInnerContainer from './WidgetsInnerContainer.svelte'; + import { _t } from '../translations'; $: favorites = useFavorites(); - + - + diff --git a/packages/web/src/widgets/PluginsWidget.svelte b/packages/web/src/widgets/PluginsWidget.svelte index a44880f1f..8502e0eea 100644 --- a/packages/web/src/widgets/PluginsWidget.svelte +++ b/packages/web/src/widgets/PluginsWidget.svelte @@ -4,13 +4,15 @@ import WidgetColumnBar from './WidgetColumnBar.svelte'; import WidgetColumnBarItem from './WidgetColumnBarItem.svelte'; + + import { _t } from '../translations'; - + - + diff --git a/packages/web/src/widgets/PublicCloudWidget.svelte b/packages/web/src/widgets/PublicCloudWidget.svelte index a14c49d9f..cb6b39270 100644 --- a/packages/web/src/widgets/PublicCloudWidget.svelte +++ b/packages/web/src/widgets/PublicCloudWidget.svelte @@ -30,11 +30,11 @@ - + @@ -52,9 +52,9 @@
- Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first. + {_t('publicCloudWidget.onlyRelevantFilesListed', { defaultMessage: "Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first." })}
- +
{/if}
diff --git a/packages/web/src/widgets/QueryHistoryList.svelte b/packages/web/src/widgets/QueryHistoryList.svelte index f6436df20..77767abd5 100644 --- a/packages/web/src/widgets/QueryHistoryList.svelte +++ b/packages/web/src/widgets/QueryHistoryList.svelte @@ -9,6 +9,7 @@ import openNewTab from '../utility/openNewTab'; import CloseSearchButton from '../buttons/CloseSearchButton.svelte'; import { apiCall, apiOff, apiOn } from '../utility/api'; + import { _t } from '../translations'; let filter = ''; let search = ''; @@ -38,7 +39,7 @@ - + { @@ -54,7 +55,7 @@ on:click={() => { openNewTab( { - title: 'Query #', + title: _t('database.queryDesigner', { defaultMessage: "Query #" }), icon: 'icon sql-file', tabComponent: 'QueryTab', focused: true, diff --git a/packages/web/src/widgets/SavedFilesList.svelte b/packages/web/src/widgets/SavedFilesList.svelte index 095794588..ea24ceeb0 100644 --- a/packages/web/src/widgets/SavedFilesList.svelte +++ b/packages/web/src/widgets/SavedFilesList.svelte @@ -13,6 +13,7 @@ import { isProApp } from '../utility/proTools'; import InlineUploadButton from '../buttons/InlineUploadButton.svelte'; import { DATA_FOLDER_NAMES } from 'dbgate-tools'; + import { _t } from '../translations'; let filter = ''; @@ -65,19 +66,19 @@ - + - + @@ -86,7 +87,7 @@ (data.teamFileId ? 'Team files' : dataFolderTitle(data.folder))} + groupFunc={data => (data.teamFileId ? _t('files.teamFiles', { defaultMessage: "Team files" }) : dataFolderTitle(data.folder))} {filter} /> diff --git a/packages/web/src/widgets/WidgetIconPanel.svelte b/packages/web/src/widgets/WidgetIconPanel.svelte index 4dfef5ab5..fa812c188 100644 --- a/packages/web/src/widgets/WidgetIconPanel.svelte +++ b/packages/web/src/widgets/WidgetIconPanel.svelte @@ -35,16 +35,16 @@ getCurrentConfig().storageDatabase && { icon: 'icon admin', name: 'admin', - title: 'Administration', + title: _t('widgets.administration', { defaultMessage: 'Administration' }), }, { icon: 'icon database', name: 'database', - title: 'Database connections', + title: _t('widgets.databaseConnections', { defaultMessage: 'Database connections' }), }, getCurrentConfig().allowPrivateCloud && { name: 'cloud-private', - title: 'DbGate Cloud', + title: _t('widgets.dbgateCloud', { defaultMessage: 'DbGate Cloud' }), icon: 'icon cloud-private', }, @@ -55,17 +55,17 @@ { icon: 'icon file', name: 'file', - title: 'Favorites & Saved files', + title: _t('widgets.favoritesAndSavedFiles', { defaultMessage: 'Favorites & Saved files' }), }, { icon: 'icon history', name: 'history', - title: 'Query history & Closed tabs', + title: _t('widgets.queryHistoryAndClosedTabs', { defaultMessage: 'Query history & Closed tabs' }), }, isProApp() && { icon: 'icon archive', name: 'archive', - title: 'Archive (saved tabular data)', + title: _t('widgets.archive', { defaultMessage: 'Archive (saved tabular data)' }), }, // { // icon: 'icon plugin', @@ -75,17 +75,17 @@ { icon: 'icon cell-data', name: 'cell-data', - title: 'Selected cell data detail view', + title: _t('widgets.selectedCellDataDetailView', { defaultMessage: 'Selected cell data detail view' }), }, { name: 'cloud-public', - title: 'DbGate Cloud', + title: _t('widgets.dbgateCloud', { defaultMessage: 'DbGate Cloud' }), icon: 'icon cloud-public', }, { icon: 'icon premium', name: 'premium', - title: 'Premium promo', + title: _t('widgets.premiumPromo', { defaultMessage: 'Premium promo' }), isPremiumPromo: true, }, // { @@ -213,7 +213,7 @@ class="wrapper" on:click={() => showModal(NewObjectModal)} data-testid="WidgetIconPanel_addButton" - title="Add New" + title={_t('widgets.addNew', { defaultMessage: 'Add New' })} >
From b6f0e15951c9aae9ee1b9dde6e15ad312a108518 Mon Sep 17 00:00:00 2001 From: Stela Augustinova Date: Mon, 24 Nov 2025 16:48:29 +0100 Subject: [PATCH 16/76] Translation - add translation tags for logs --- packages/web/src/tabs/AppLogTab.svelte | 63 +++++++++++++------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/packages/web/src/tabs/AppLogTab.svelte b/packages/web/src/tabs/AppLogTab.svelte index 5635dc50d..90b92585d 100644 --- a/packages/web/src/tabs/AppLogTab.svelte +++ b/packages/web/src/tabs/AppLogTab.svelte @@ -24,6 +24,7 @@ createQuickExportHandlerRef, registerQuickExportHandler, } from '../buttons/ToolStripExportButton.svelte'; + import { _t } from '../translations'; let loadedRows = []; let loadedAll = false; @@ -191,8 +192,8 @@ { @@ -202,7 +203,7 @@ /> {#if mode === 'recent'} -
Auto-scroll
+
{_t('logs.autoScroll', { defaultMessage: 'Auto-scroll' })}
Date:
+
{_t('logs.date', { defaultMessage: 'Date:' })}
{ dateFilter = value; @@ -225,12 +226,12 @@ data-testid="AdminAuditLogTab_addFilter" icon="icon filter" menu={[ - { text: 'Connection ID', onClick: () => filterBy('conid') }, - { text: 'Database', onClick: () => filterBy('database') }, - { text: 'Engine', onClick: () => filterBy('engine') }, - { text: 'Message code', onClick: () => filterBy('msgcode') }, - { text: 'Caller', onClick: () => filterBy('caller') }, - { text: 'Name', onClick: () => filterBy('name') }, + { text: _t('logs.connectionId', { defaultMessage: 'Connection ID' }), onClick: () => filterBy('conid') }, + { text: _t('logs.database', { defaultMessage: 'Database' }), onClick: () => filterBy('database') }, + { text: _t('logs.engine', { defaultMessage: 'Engine' }), onClick: () => filterBy('engine') }, + { text: _t('logs.messageCode', { defaultMessage: 'Message code' }), onClick: () => filterBy('msgcode') }, + { text: _t('logs.caller', { defaultMessage: 'Caller' }), onClick: () => filterBy('caller') }, + { text: _t('logs.name', { defaultMessage: 'Name' }), onClick: () => filterBy('name') }, ]} />
@@ -259,15 +260,15 @@ - - - - - - - - - + + + + + + + + + @@ -299,14 +300,14 @@
-
Message code:
+
{_t('logs.messageCode', { defaultMessage: 'Message code:' })}
{#if mode == 'date'} doSetFilter('msgcode', [row.msgcode])}>{row.msgcode || 'N/A'} {:else} @@ -314,15 +315,15 @@ {/if}
-
Message:
+
{_t('logs.message', { defaultMessage: 'Message:' })}
{row.msg}
-
Time:
+
{_t('logs.time', { defaultMessage: 'Time:' })}
{row.time ? format(new Date(parseInt(row.time)), 'yyyy-MM-dd HH:mm:ss') : ''}
-
Caller:
+
{_t('logs.caller', { defaultMessage: 'Caller:' })}
{#if mode == 'date'} doSetFilter('caller', [row.caller])}>{row.caller || 'N/A'} {:else} @@ -330,7 +331,7 @@ {/if}
-
Name:
+
{_t('logs.name', { defaultMessage: 'Name:' })}
{#if mode == 'date'} doSetFilter('name', [row.name])}>{row.name || 'N/A'} {:else} @@ -339,7 +340,7 @@
{#if row.conid}
-
Connection ID:
+
{_t('logs.connectionId', { defaultMessage: 'Connection ID:' })}
{#if mode == 'date'} doSetFilter('conid', [row.conid])} >{formatPossibleUuid(row.conid)} -
Database:
+
{_t('logs.database', { defaultMessage: 'Database:' })}
{#if mode == 'date'} doSetFilter('database', [row.database])}>{row.database} {:else} @@ -361,7 +362,7 @@ {/if} {#if row.engine}
-
Engine:
+
{_t('logs.engine', { defaultMessage: 'Engine:' })}
{#if mode == 'date'} doSetFilter('engine', [row.engine])}>{row.engine} {:else} @@ -381,13 +382,13 @@ {/each} {#if !loadedRows?.length && mode === 'date'}
- + {/if} {#if !loadedAll && mode === 'date'} {#key loadedRows} - + {/key} {/if} @@ -402,7 +403,7 @@ data-testid="AdminAuditLogTab_refreshButton" on:click={() => { reloadData(); - }}>Refresh{_t('logs.refresh', { defaultMessage: 'Refresh' })} From 1e195e07e0d89b8dfd736b57ebd535328e41d961 Mon Sep 17 00:00:00 2001 From: Stela Augustinova Date: Mon, 24 Nov 2025 17:02:34 +0100 Subject: [PATCH 17/76] Translation - added translation tags for import/export --- packages/web/src/impexp/SourceTargetConfig.svelte | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/web/src/impexp/SourceTargetConfig.svelte b/packages/web/src/impexp/SourceTargetConfig.svelte index 38a8a19cd..2c07987c0 100644 --- a/packages/web/src/impexp/SourceTargetConfig.svelte +++ b/packages/web/src/impexp/SourceTargetConfig.svelte @@ -73,19 +73,19 @@
{#if direction == 'source'}
- Source configuration + {_t('importExport.sourceConfiguration', { defaultMessage: 'Source configuration' })}
{/if} {#if direction == 'target'}
- Target configuration + {_t('importExport.targetConfiguration', { defaultMessage: 'Target configuration' })}
{/if}
{#if $currentDatabase} { values.update(x => ({ ...x, @@ -97,7 +97,7 @@ /> {/if} {#if direction == 'target'} { showModal(InputTextModal, { header: 'Archive', @@ -172,9 +172,9 @@ {/if} {#if storageType == 'database' || storageType == 'query'} - + {#if !$connectionInfo?.singleDatabase} - + {/if} {/if} {#if storageType == 'database'} From 5553e3cd8d61f4ea3a84fbbb8ee2b90f2a9b27d9 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 24 Nov 2025 17:34:40 +0100 Subject: [PATCH 18/76] SYNC: Handle error when saving to team files --- packages/web/src/commands/stdCommands.ts | 22 +++++++---- packages/web/src/modals/SaveFileModal.svelte | 39 +++++++++++++------- packages/web/src/tabs/DiagramTab.svelte | 1 + packages/web/src/utility/saveTabFile.ts | 3 +- 4 files changed, 44 insertions(+), 21 deletions(-) diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index 073fa7683..1b6db8bdc 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -115,7 +115,7 @@ registerCommand({ toolbar: true, icon: 'icon new-connection', toolbarName: __t('command.new.connection', { defaultMessage: 'Add connection' }), - category: __t('command.new', { defaultMessage: 'New'}), + category: __t('command.new', { defaultMessage: 'New' }), toolbarOrder: 1, name: __t('command.new.connection', { defaultMessage: 'Connection' }), testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase, @@ -561,7 +561,10 @@ registerCommand({ testEnabled: () => true, onClick: () => { showModal(ConfirmModal, { - message: _t('command.file.resetLayoutConfirm', { defaultMessage: 'Really reset layout data? All opened tabs, settings and layout data will be lost. Connections and saved files will be preserved. After this, restart DbGate for applying changes.' }), + message: _t('command.file.resetLayoutConfirm', { + defaultMessage: + 'Really reset layout data? All opened tabs, settings and layout data will be lost. Connections and saved files will be preserved. After this, restart DbGate for applying changes.', + }), onConfirm: async () => { await apiCall('config/delete-settings'); localStorage.clear(); @@ -665,7 +668,9 @@ registerCommand({ 'currentArchive', ]; for (const key of keys) removeLocalStorage(key); - showSnackbarSuccess(_t('command.view.restart', { defaultMessage: 'Restart DbGate (or reload on web) for applying changes' })); + showSnackbarSuccess( + _t('command.view.restart', { defaultMessage: 'Restart DbGate (or reload on web) for applying changes' }) + ); }, }); @@ -799,7 +804,9 @@ registerCommand({ registerCommand({ id: 'file.exit', category: __t('command.file', { defaultMessage: 'File' }), - name: isMac() ? __t('command.file.quit', { defaultMessage: 'Quit' }) : __t('command.file.exit', { defaultMessage: 'Exit' }), + name: isMac() + ? __t('command.file.quit', { defaultMessage: 'Quit' }) + : __t('command.file.exit', { defaultMessage: 'Exit' }), // keyText: isMac() ? 'Command+Q' : null, testEnabled: () => getElectron() != null, onClick: () => getElectron().send('quit-app'), @@ -862,6 +869,7 @@ export function registerFileCommands({ undoRedo = false, executeAdditionalCondition = null, copyPaste = false, + defaultTeamFolder = false, }) { if (save) { registerCommand({ @@ -874,7 +882,7 @@ export function registerFileCommands({ toolbar: true, isRelatedToTab: true, testEnabled: () => getCurrentEditor() != null, - onClick: () => saveTabFile(getCurrentEditor(), 'save', folder, format, fileExtension), + onClick: () => saveTabFile(getCurrentEditor(), 'save', folder, format, fileExtension, defaultTeamFolder), }); registerCommand({ id: idPrefix + '.saveAs', @@ -882,14 +890,14 @@ export function registerFileCommands({ category, name: __t('command.saveAs', { defaultMessage: 'Save As' }), testEnabled: () => getCurrentEditor() != null, - onClick: () => saveTabFile(getCurrentEditor(), 'save-as', folder, format, fileExtension), + onClick: () => saveTabFile(getCurrentEditor(), 'save-as', folder, format, fileExtension, defaultTeamFolder), }); registerCommand({ id: idPrefix + '.saveToDisk', category, name: __t('command.saveToDisk', { defaultMessage: 'Save to disk' }), testEnabled: () => getCurrentEditor() != null && getElectron() != null, - onClick: () => saveTabFile(getCurrentEditor(), 'save-to-disk', folder, format, fileExtension), + onClick: () => saveTabFile(getCurrentEditor(), 'save-to-disk', folder, format, fileExtension, defaultTeamFolder), }); } diff --git a/packages/web/src/modals/SaveFileModal.svelte b/packages/web/src/modals/SaveFileModal.svelte index 062f63298..a069d57f9 100644 --- a/packages/web/src/modals/SaveFileModal.svelte +++ b/packages/web/src/modals/SaveFileModal.svelte @@ -14,6 +14,8 @@ import { closeCurrentModal, showModal } from './modalTools'; import FormCloudFolderSelect from '../forms/FormCloudFolderSelect.svelte'; import FormCheckboxField from '../forms/FormCheckboxField.svelte'; + import { useConfig } from '../utility/metadataLoaders'; + import { showSnackbarError } from '../utility/snackbar'; export let data; export let name; @@ -24,26 +26,37 @@ export let onSave = undefined; export let folid; export let skipLocal = false; + export let defaultTeamFolder = false; // export let cntid; - const values = writable({ name, cloudFolder: folid ?? '__local' }); + const configValue = useConfig(); + + const values = writable({ + name, + cloudFolder: folid ?? '__local', + saveToTeamFolder: !!(getCurrentConfig()?.storageDatabase && defaultTeamFolder), + }); const electron = getElectron(); const handleSubmit = async e => { const { name, cloudFolder } = e.detail; if ($values['saveToTeamFolder']) { - const { teamFileId } = await apiCall('team-files/create-new', { fileType: folder, file: name, data }); - closeCurrentModal(); - if (onSave) { - onSave(name, { - savedFile: name, - savedFolder: folder, - savedFilePath: null, - savedCloudFolderId: null, - savedCloudContentId: null, - savedTeamFileId: teamFileId, - }); + const resp = await apiCall('team-files/create-new', { fileType: folder, file: name, data }); + if (resp.apiErrorMessage) { + showSnackbarError(resp.apiErrorMessage); + } else if (resp.teamFileId) { + closeCurrentModal(); + if (onSave) { + onSave(name, { + savedFile: name, + savedFolder: folder, + savedFilePath: null, + savedCloudFolderId: null, + savedCloudContentId: null, + savedTeamFileId: resp.teamFileId, + }); + } } } else if (cloudFolder === '__local') { await apiCall('files/save', { folder, file: name, data, format }); @@ -124,7 +137,7 @@ ]} /> {/if} - {#if getCurrentConfig().storageDatabase} + {#if $configValue?.storageDatabase} {/if} diff --git a/packages/web/src/tabs/DiagramTab.svelte b/packages/web/src/tabs/DiagramTab.svelte index 73657781a..734fa81a2 100644 --- a/packages/web/src/tabs/DiagramTab.svelte +++ b/packages/web/src/tabs/DiagramTab.svelte @@ -8,6 +8,7 @@ folder: 'diagrams', format: 'json', fileExtension: 'diagram', + defaultTeamFolder: true, undoRedo: true, }); diff --git a/packages/web/src/utility/saveTabFile.ts b/packages/web/src/utility/saveTabFile.ts index c47c66173..66946ec6b 100644 --- a/packages/web/src/utility/saveTabFile.ts +++ b/packages/web/src/utility/saveTabFile.ts @@ -11,7 +11,7 @@ import getElectron from './getElectron'; // return derived(editorStore, editor => editor != null); // } -export default async function saveTabFile(editor, saveMode, folder, format, fileExtension) { +export default async function saveTabFile(editor, saveMode, folder, format, fileExtension, defaultTeamFolder) { const tabs = get(openedTabs); const tabid = editor.activator.tabid; const data = editor.getData(); @@ -94,6 +94,7 @@ export default async function saveTabFile(editor, saveMode, folder, format, file filePath: savedFilePath, onSave, folid: savedCloudFolderId, + defaultTeamFolder, // cntid: savedCloudContentId, }); } From 53c63f0f4baf405fbb69d2618204dd2453b91590 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Tue, 25 Nov 2025 09:20:09 +0100 Subject: [PATCH 19/76] SYNC: diagrams supported in team files --- packages/api/src/storageModel.js | 14 +++++++++++++- packages/web/src/modals/SaveFileModal.svelte | 6 ++++-- packages/web/src/tabs/QueryTab.svelte | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/api/src/storageModel.js b/packages/api/src/storageModel.js index 0202f1641..7fb993670 100644 --- a/packages/api/src/storageModel.js +++ b/packages/api/src/storageModel.js @@ -1533,6 +1533,12 @@ module.exports = { "columnName": "name", "dataType": "varchar(250)", "notNull": true + }, + { + "pureName": "team_file_types", + "columnName": "format", + "dataType": "varchar(50)", + "notNull": false } ], "foreignKeys": [], @@ -1549,7 +1555,13 @@ module.exports = { "preloadedRows": [ { "id": -1, - "name": "sql" + "name": "sql", + "format": "text" + }, + { + "id": -2, + "name": "diagrams", + "format": "json" } ] }, diff --git a/packages/web/src/modals/SaveFileModal.svelte b/packages/web/src/modals/SaveFileModal.svelte index a069d57f9..6dcf13c4b 100644 --- a/packages/web/src/modals/SaveFileModal.svelte +++ b/packages/web/src/modals/SaveFileModal.svelte @@ -43,9 +43,9 @@ const { name, cloudFolder } = e.detail; if ($values['saveToTeamFolder']) { const resp = await apiCall('team-files/create-new', { fileType: folder, file: name, data }); - if (resp.apiErrorMessage) { + if (resp?.apiErrorMessage) { showSnackbarError(resp.apiErrorMessage); - } else if (resp.teamFileId) { + } else if (resp?.teamFileId) { closeCurrentModal(); if (onSave) { onSave(name, { @@ -57,6 +57,8 @@ savedTeamFileId: resp.teamFileId, }); } + } else { + showSnackbarError('Failed to save to team folder.'); } } else if (cloudFolder === '__local') { await apiCall('files/save', { folder, file: name, data, format }); diff --git a/packages/web/src/tabs/QueryTab.svelte b/packages/web/src/tabs/QueryTab.svelte index facb19f1a..7f1963bc8 100644 --- a/packages/web/src/tabs/QueryTab.svelte +++ b/packages/web/src/tabs/QueryTab.svelte @@ -52,6 +52,7 @@ findReplace: true, executeAdditionalCondition: () => getCurrentEditor()?.hasConnection() && hasPermission('dbops/query'), copyPaste: true, + defaultTeamFolder: true, }); registerCommand({ id: 'query.executeCurrent', From 3b4d90548591b5d495b23e0cd6f184bee5856d32 Mon Sep 17 00:00:00 2001 From: CI workflows Date: Tue, 25 Nov 2025 08:20:50 +0000 Subject: [PATCH 20/76] Update pro ref --- workflow-templates/includes.tpl.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflow-templates/includes.tpl.yaml b/workflow-templates/includes.tpl.yaml index a73f87b0b..bc4a792eb 100644 --- a/workflow-templates/includes.tpl.yaml +++ b/workflow-templates/includes.tpl.yaml @@ -7,7 +7,7 @@ checkout-and-merge-pro: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 + ref: 626a30d67f40e910e8c3ed89ec34d5aa58c1f7e2 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From 0d82fd51c72c2e2bb688571a7f34476611f8a3ba Mon Sep 17 00:00:00 2001 From: CI workflows Date: Tue, 25 Nov 2025 08:21:06 +0000 Subject: [PATCH 21/76] chore: auto-update github workflows --- .github/workflows/build-app-pro-beta.yaml | 2 +- .github/workflows/build-app-pro.yaml | 2 +- .github/workflows/build-cloud-pro.yaml | 2 +- .github/workflows/build-docker-pro.yaml | 2 +- .github/workflows/build-npm-pro.yaml | 2 +- .github/workflows/e2e-pro.yaml | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build-app-pro-beta.yaml b/.github/workflows/build-app-pro-beta.yaml index d406ee593..5b94db383 100644 --- a/.github/workflows/build-app-pro-beta.yaml +++ b/.github/workflows/build-app-pro-beta.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 + ref: 626a30d67f40e910e8c3ed89ec34d5aa58c1f7e2 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-app-pro.yaml b/.github/workflows/build-app-pro.yaml index c2db2e1f7..ab7a9b70b 100644 --- a/.github/workflows/build-app-pro.yaml +++ b/.github/workflows/build-app-pro.yaml @@ -43,7 +43,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 + ref: 626a30d67f40e910e8c3ed89ec34d5aa58c1f7e2 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-cloud-pro.yaml b/.github/workflows/build-cloud-pro.yaml index 4a71928df..0f5ec27fa 100644 --- a/.github/workflows/build-cloud-pro.yaml +++ b/.github/workflows/build-cloud-pro.yaml @@ -39,7 +39,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 + ref: 626a30d67f40e910e8c3ed89ec34d5aa58c1f7e2 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-docker-pro.yaml b/.github/workflows/build-docker-pro.yaml index 293195337..9cb2d4f26 100644 --- a/.github/workflows/build-docker-pro.yaml +++ b/.github/workflows/build-docker-pro.yaml @@ -44,7 +44,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 + ref: 626a30d67f40e910e8c3ed89ec34d5aa58c1f7e2 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/build-npm-pro.yaml b/.github/workflows/build-npm-pro.yaml index 9c5acbed8..0a2c64627 100644 --- a/.github/workflows/build-npm-pro.yaml +++ b/.github/workflows/build-npm-pro.yaml @@ -35,7 +35,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 + ref: 626a30d67f40e910e8c3ed89ec34d5aa58c1f7e2 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro diff --git a/.github/workflows/e2e-pro.yaml b/.github/workflows/e2e-pro.yaml index c720859ae..9d7237e39 100644 --- a/.github/workflows/e2e-pro.yaml +++ b/.github/workflows/e2e-pro.yaml @@ -26,7 +26,7 @@ jobs: repository: dbgate/dbgate-pro token: ${{ secrets.GH_TOKEN }} path: dbgate-pro - ref: 4899336f1f6f51b352b4c8809a0ab635b8127488 + ref: 626a30d67f40e910e8c3ed89ec34d5aa58c1f7e2 - name: Merge dbgate/dbgate-pro run: | mkdir ../dbgate-pro From b784e342c96f5f433979e4287d98b7ae84b46280 Mon Sep 17 00:00:00 2001 From: Stela Augustinova Date: Tue, 25 Nov 2025 10:07:41 +0100 Subject: [PATCH 22/76] Translation - added translation tags for import/export, connection tab --- packages/web/src/commands/stdCommands.ts | 4 ++-- .../src/forms/FormArchiveFilesSelect.svelte | 5 +++-- packages/web/src/impexp/FilesInput.svelte | 5 +++-- .../web/src/impexp/FormTablesSelect.svelte | 5 +++-- .../impexp/ImportExportConfigurator.svelte | 15 ++++++------- .../web/src/impexp/SourceTargetConfig.svelte | 4 ++-- packages/web/src/tabs/ImportExportTab.svelte | 21 ++++++++++--------- 7 files changed, 32 insertions(+), 27 deletions(-) diff --git a/packages/web/src/commands/stdCommands.ts b/packages/web/src/commands/stdCommands.ts index 073fa7683..4b488cd33 100644 --- a/packages/web/src/commands/stdCommands.ts +++ b/packages/web/src/commands/stdCommands.ts @@ -121,7 +121,7 @@ registerCommand({ testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase, onClick: () => { openNewTab({ - title: 'New Connection', + title: _t('common.newConnection', { defaultMessage: 'New Connection' }), icon: 'img connection', tabComponent: 'ConnectionTab', }); @@ -140,7 +140,7 @@ registerCommand({ !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase && !!getCloudSigninTokenHolder(), onClick: () => { openNewTab({ - title: 'New Connection on Cloud', + title: _t('common.newConnectionCloud', { defaultMessage: 'New Connection on Cloud' }), icon: 'img cloud-connection', tabComponent: 'ConnectionTab', props: { diff --git a/packages/web/src/forms/FormArchiveFilesSelect.svelte b/packages/web/src/forms/FormArchiveFilesSelect.svelte index c2dee45bd..53c6ee70c 100644 --- a/packages/web/src/forms/FormArchiveFilesSelect.svelte +++ b/packages/web/src/forms/FormArchiveFilesSelect.svelte @@ -7,6 +7,7 @@ import { getFormContext } from './FormProviderCore.svelte'; import FormSelectField from './FormSelectField.svelte'; + import { _t } from '../translations'; export let folderName; export let name; @@ -28,10 +29,10 @@
setFieldValue(name, _.uniq([...($values[name] || []), ...($files && $files.map(x => x.name))]))} /> - setFieldValue(name, [])} /> + setFieldValue(name, [])} />
diff --git a/packages/web/src/impexp/FilesInput.svelte b/packages/web/src/impexp/FilesInput.svelte index 37e4d719b..3afdd30e4 100644 --- a/packages/web/src/impexp/FilesInput.svelte +++ b/packages/web/src/impexp/FilesInput.svelte @@ -23,6 +23,7 @@ import ElectronFilesInput from './ElectronFilesInput.svelte'; import { addFilesToSourceList } from './ImportExportConfigurator.svelte'; import UploadButton from '../buttons/UploadButton.svelte'; + import { _t } from '../translations'; export let setPreviewSource = undefined; @@ -55,10 +56,10 @@ {:else} {/if} - +
-
Drag & drop imported files here
+
{_t('importExport.dragDropImportedFilesHere', { defaultMessage: "Drag & drop imported files here" })}
diff --git a/packages/web/src/settings/BehaviourSettings.svelte b/packages/web/src/settings/BehaviourSettings.svelte new file mode 100644 index 000000000..95d32d5f0 --- /dev/null +++ b/packages/web/src/settings/BehaviourSettings.svelte @@ -0,0 +1,68 @@ + + + +
{_t('settings.behaviour', { defaultMessage: 'Behaviour' })}
+ + + + + +
+ + {_t('settings.behaviour.singleClickPreview', { + defaultMessage: + 'When you single-click or select a file in the "Tables, Views, Functions" view, it is shown in a preview mode and reuses an existing tab (preview tab). This is useful if you are quickly browsing tables and don\'t want every visited table to have its own tab. When you start editing the table or use double-click to open the table from the "Tables" view, a new tab is dedicated to that table.', + })} +
+ + + +
{_t('settings.confirmations', { defaultMessage: 'Confirmations' })}
+ + + +
+ + \ No newline at end of file diff --git a/packages/web/src/settings/ConnectionSettings.svelte b/packages/web/src/settings/ConnectionSettings.svelte new file mode 100644 index 000000000..b57df5786 --- /dev/null +++ b/packages/web/src/settings/ConnectionSettings.svelte @@ -0,0 +1,89 @@ + + + +
{_t('settings.connection', { defaultMessage: 'Connection' })}
+ + { + $lockedDatabaseMode = !$lockedDatabaseMode; + }, + }} + > + ($lockedDatabaseMode = e.target.checked)} /> + + + + + + +
{_t('settings.session', { defaultMessage: 'Query sessions' })}
+ + +
+ + \ No newline at end of file diff --git a/packages/web/src/settings/DefaultActionsSettings.svelte b/packages/web/src/settings/DefaultActionsSettings.svelte new file mode 100644 index 000000000..ab360f830 --- /dev/null +++ b/packages/web/src/settings/DefaultActionsSettings.svelte @@ -0,0 +1,105 @@ + + + +
{_t('settings.defaultActions', { defaultMessage: 'Default actions' })}
+ + + + + + + + + + + + + +
+ + \ No newline at end of file diff --git a/packages/web/src/settings/ExternalToolsSettings.svelte b/packages/web/src/settings/ExternalToolsSettings.svelte new file mode 100644 index 000000000..0547094ac --- /dev/null +++ b/packages/web/src/settings/ExternalToolsSettings.svelte @@ -0,0 +1,52 @@ + + +
{_t('settings.externalTools', { defaultMessage: 'External tools' })}
+ + + + + + + \ No newline at end of file diff --git a/packages/web/src/settings/GeneralSettings.svelte b/packages/web/src/settings/GeneralSettings.svelte new file mode 100644 index 000000000..d8375fd5c --- /dev/null +++ b/packages/web/src/settings/GeneralSettings.svelte @@ -0,0 +1,259 @@ + + +{#if electron} +
{_t('settings.appearance', { defaultMessage: 'Appearance' })}
+ { + restartWarning = true; + }} + /> + {#if restartWarning} +
+ + {_t('settings.nativeMenuRestartWarning', { + defaultMessage: 'Native menu settings will be applied after app restart', + })} +
+ {/if} +{/if} + + +
{_t('settings.localization', { defaultMessage: 'Localization' })}
+ + + { + setSelectedLanguage(e.detail); + showModal(ConfirmModal, { + message: _t('settings.localization.reloadWarning', { + defaultMessage: 'Application will be reloaded to apply new language settings', + }), + onConfirm: () => { + setTimeout(() => { + internalRedirectTo(electron ? '/index.html' : '/'); + }, 100); + }, + }); + }} +/> + + +
{_t('settings.dataGrid.title', { defaultMessage: 'Data grid' })}
+ +{#if isProApp()} + +{/if} + + + + + + + + + + + + + + +
{_t('settings.sqlEditor', { defaultMessage: 'SQL editor' })}
+ +
+
+ +
+
+ + ({ label: mode.label, value: mode.value }))} + value={$currentEditorKeybindigMode} + on:change={e => ($currentEditorKeybindigMode = e.detail)} + /> + +
+
+ + ($currentEditorWrapEnabled = e.target.checked)} + /> + +
+
+ + + + + + + + + + + + \ No newline at end of file diff --git a/packages/web/src/settings/LicenseSettings.svelte b/packages/web/src/settings/LicenseSettings.svelte new file mode 100644 index 000000000..d25f6c51c --- /dev/null +++ b/packages/web/src/settings/LicenseSettings.svelte @@ -0,0 +1,96 @@ + + +
{_t('settings.other.license', { defaultMessage: 'License' })}
+ { + licenseKeyCheckResult = await apiCall('config/check-license', { licenseKey: value }); +}} +/> +{#if licenseKeyCheckResult} +
+ {#if licenseKeyCheckResult.status == 'ok'} +
+ + {_t('settings.other.licenseKey.valid', { defaultMessage: 'License key is valid' })} +
+ {#if licenseKeyCheckResult.validTo} +
+ {_t('settings.other.licenseKey.validTo', { defaultMessage: 'License valid to:' })} + {licenseKeyCheckResult.validTo} +
+ {/if} + {#if licenseKeyCheckResult.expiration} +
+ {_t('settings.other.licenseKey.expiration', { defaultMessage: 'License key expiration:' })} + {safeFormatDate(licenseKeyCheckResult.expiration)} +
+ {/if} + {:else if licenseKeyCheckResult.status == 'error'} +
+ + {licenseKeyCheckResult.errorMessage ?? + _t('settings.other.licenseKey.invalid', { defaultMessage: 'License key is invalid' })} + {#if licenseKeyCheckResult.expiration} +
+ {_t('settings.other.licenseKey.expiration', { defaultMessage: 'License key expiration:' })} + {safeFormatDate(licenseKeyCheckResult.expiration)} +
+ {/if} +
+ {#if licenseKeyCheckResult.isExpired} +
+ { + licenseKeyCheckResult = await apiCall('config/get-new-license', { oldLicenseKey: licenseKey }); + if (licenseKeyCheckResult.licenseKey) { + apiCall('config/update-settings', { 'other.licenseKey': licenseKeyCheckResult.licenseKey }); + } + }} + /> +
+ {/if} + {/if} +
+{/if} + + \ No newline at end of file diff --git a/packages/web/src/settings/OtherSettings.svelte b/packages/web/src/settings/OtherSettings.svelte new file mode 100644 index 000000000..80d94d067 --- /dev/null +++ b/packages/web/src/settings/OtherSettings.svelte @@ -0,0 +1,66 @@ + + +
{_t('settings.other', { defaultMessage: 'Other' })}
+ + + + + +{#if isProApp()} + +{/if} + + \ No newline at end of file diff --git a/packages/web/src/settings/ThemeSettings.svelte b/packages/web/src/settings/ThemeSettings.svelte new file mode 100644 index 000000000..80590f25d --- /dev/null +++ b/packages/web/src/settings/ThemeSettings.svelte @@ -0,0 +1,169 @@ + + +
{_t('settings.appearance', { defaultMessage: 'Application theme' })}
+ + { + if ($currentTheme) { + $currentTheme = null; + } else { + $currentTheme = getSystemTheme(); + } + }, +}} +> + { + if (e.target['checked']) { + $currentTheme = null; + } else { + $currentTheme = getSystemTheme(); + } + }} +/> + + +
+{#each $extensions.themes as theme} + +{/each} +
+ +
+{_t('settings.appearance.moreThemes', { defaultMessage: 'More themes are available as' })} +plugins +
+{_t('settings.appearance.afterInstalling', { + defaultMessage: + 'After installing theme plugin (try search "theme" in available extensions) new themes will be available here.', +})} +
+ +
{_t('settings.appearance.editorTheme', { defaultMessage: 'Editor theme' })}
+ +
+
+ + ({ label: theme, value: theme }))} + value={$currentEditorTheme} + on:change={e => ($currentEditorTheme = e.detail)} + /> + +
+ +
+ + x.value == $currentEditorFontSize) ? $currentEditorFontSize : 'custom'} + on:change={e => ($currentEditorFontSize = e.detail)} + /> + +
+ +
+ + ($currentEditorFontSize = e.target['value'])} + disabled={!!FONT_SIZES.find(x => x.value == $currentEditorFontSize) && + $currentEditorFontSize != 'custom'} + /> + +
+ +
+ +
+
+ +
+ +
+ + + \ No newline at end of file diff --git a/packages/web/src/tabs/SettingsTab.svelte b/packages/web/src/tabs/SettingsTab.svelte new file mode 100644 index 000000000..4598926c7 --- /dev/null +++ b/packages/web/src/tabs/SettingsTab.svelte @@ -0,0 +1,85 @@ + + + + + \ No newline at end of file diff --git a/packages/web/src/tabs/index.js b/packages/web/src/tabs/index.js index f8c0cdd8b..1e34e5102 100644 --- a/packages/web/src/tabs/index.js +++ b/packages/web/src/tabs/index.js @@ -25,6 +25,7 @@ import * as ServerSummaryTab from './ServerSummaryTab.svelte'; import * as ImportExportTab from './ImportExportTab.svelte'; import * as SqlObjectTab from './SqlObjectTab.svelte'; import * as AppLogTab from './AppLogTab.svelte'; +import * as SettingsTab from './SettingsTab.svelte'; import protabs from './index-pro'; @@ -56,5 +57,6 @@ export default { ImportExportTab, SqlObjectTab, AppLogTab, + SettingsTab, ...protabs, }; diff --git a/packages/web/src/widgets/WidgetIconPanel.svelte b/packages/web/src/widgets/WidgetIconPanel.svelte index 4dfef5ab5..9d9a4360f 100644 --- a/packages/web/src/widgets/WidgetIconPanel.svelte +++ b/packages/web/src/widgets/WidgetIconPanel.svelte @@ -118,6 +118,7 @@ const top = rect.bottom; const items = [ hasPermission('settings/change') && { command: 'settings.show' }, + hasPermission('settings/change') && { command: 'settings.settingsTab' }, { command: 'theme.changeTheme' }, hasPermission('settings/change') && { command: 'settings.commands' }, hasPermission('widgets/plugins') && { From c92a0e1d4310c9ea69a066657015b683593eb6a9 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Thu, 27 Nov 2025 08:58:11 +0100 Subject: [PATCH 40/76] fixed search in keyboard shortcuts #1273 --- packages/web/src/tabs/CommandListTab.svelte | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/web/src/tabs/CommandListTab.svelte b/packages/web/src/tabs/CommandListTab.svelte index cf2f6c850..4cc9a9691 100644 --- a/packages/web/src/tabs/CommandListTab.svelte +++ b/packages/web/src/tabs/CommandListTab.svelte @@ -13,6 +13,7 @@ import CommandModal from '../modals/CommandModal.svelte'; import { showModal } from '../modals/modalTools'; import { commandsCustomized } from '../stores'; + import { _tval } from '../translations'; $: commandList = _.sortBy(_.values($commandsCustomized), ['category', 'name']); let filter; @@ -27,7 +28,9 @@
filterName(filter, cmd['category'], cmd['name'], cmd['keyText'], cmd['id']))} + rows={commandList.filter(cmd => + filterName(filter, _tval(cmd['category']), _tval(cmd['name']), _tval(cmd['keyText']), cmd['id']) + )} columns={[ { header: 'Category', fieldName: 'category' }, { header: 'Name', fieldName: 'name' }, From 06a9a93d1c90eb29fd9bd59d0812e1ea39dfdfa7 Mon Sep 17 00:00:00 2001 From: Stela Augustinova Date: Thu, 27 Nov 2025 09:11:33 +0100 Subject: [PATCH 41/76] Added translation tag for settings --- .../web/src/settings/GeneralSettings.svelte | 2 +- packages/web/src/tabs/SettingsTab.svelte | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/packages/web/src/settings/GeneralSettings.svelte b/packages/web/src/settings/GeneralSettings.svelte index d8375fd5c..6ece49d79 100644 --- a/packages/web/src/settings/GeneralSettings.svelte +++ b/packages/web/src/settings/GeneralSettings.svelte @@ -19,7 +19,7 @@ const electron = getElectron(); let restartWarning = false; - +
{_t('settings.general', { defaultMessage: 'General' })}
{#if electron}
{_t('settings.appearance', { defaultMessage: 'Appearance' })}
Date: Thu, 27 Nov 2025 09:23:36 +0100 Subject: [PATCH 42/76] Added keyboard shortcuts to settings tab --- packages/web/src/tabs/SettingsTab.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/web/src/tabs/SettingsTab.svelte b/packages/web/src/tabs/SettingsTab.svelte index ecc4e6b9b..f86f73be2 100644 --- a/packages/web/src/tabs/SettingsTab.svelte +++ b/packages/web/src/tabs/SettingsTab.svelte @@ -12,6 +12,7 @@ import LicenseSettings from "../settings/LicenseSettings.svelte"; import { isProApp } from "../utility/proTools"; import { _t } from "../translations"; + import CommandListTab from "./CommandListTab.svelte"; const menuItems = [ { @@ -56,6 +57,13 @@ props: {}, testid: 'settings-external-tools', }, + { + label: _t('command.settings.shortcuts', { defaultMessage: 'Keyboard shortcuts' }), + identifier: 'shortcuts', + component: CommandListTab, + props: {}, + testid: 'settings-shortcuts', + }, isProApp() && { label: _t('settings.license', { defaultMessage: 'License' }), identifier: 'license', From 48f4924932ac0b82a9943487b09ec96285879cd4 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Thu, 27 Nov 2025 09:29:39 +0100 Subject: [PATCH 43/76] prettier format --- .../src/tableeditor/ForeignKeyEditorModal.svelte | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte b/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte index e6a6eac54..6ca5f8d81 100644 --- a/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte +++ b/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte @@ -60,7 +60,11 @@ - {constraintInfo ? _t('foreignKeyEditor.editForeignKey', { defaultMessage: 'Edit foreign key' }) : _t('foreignKeyEditor.addForeignKey', { defaultMessage: 'Add foreign key' })} + {constraintInfo + ? _t('foreignKeyEditor.editForeignKey', { defaultMessage: 'Edit foreign key' }) + : _t('foreignKeyEditor.addForeignKey', { defaultMessage: 'Add foreign key' })}
@@ -135,7 +139,8 @@ {_t('foreignKeyEditor.baseColumn', { defaultMessage: 'Base column - ' })}{tableInfo.pureName}
- {_t('foreignKeyEditor.refColumn', { defaultMessage: 'Ref column - ' })}{refTableName || _t('foreignKeyEditor.tableNotSet', { defaultMessage: '(table not set)' })} + {_t('foreignKeyEditor.refColumn', { defaultMessage: 'Ref column - ' })}{refTableName || + _t('foreignKeyEditor.tableNotSet', { defaultMessage: '(table not set)' })}
@@ -217,7 +222,11 @@ }} /> - + {#if constraintInfo} Date: Thu, 27 Nov 2025 10:29:33 +0100 Subject: [PATCH 44/76] foreign key editor UX --- .../src/tableeditor/ForeignKeyEditorModal.svelte | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte b/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte index 6ca5f8d81..500a21751 100644 --- a/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte +++ b/packages/web/src/tableeditor/ForeignKeyEditorModal.svelte @@ -96,6 +96,19 @@ const name = fullNameFromString(e.detail); refTableName = name.pureName; refSchemaName = name.schemaName; + + if (!columns?.find(x => x.columnName)) { + const refTable = dbInfo?.tables?.find( + x => x.pureName == refTableName && x.schemaName == refSchemaName + ); + if (refTable?.primaryKey) { + columns = refTable.primaryKey.columns.map(col => ({ + refColumnName: col.columnName, + })); + } else { + columns = []; + } + } } }} /> From c2703edfde2e361da16330a76625d1d55f8835e4 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Thu, 27 Nov 2025 11:03:12 +0100 Subject: [PATCH 45/76] prettier --- .../web/src/tableeditor/TableEditor.svelte | 89 +++++++++++++------ 1 file changed, 64 insertions(+), 25 deletions(-) diff --git a/packages/web/src/tableeditor/TableEditor.svelte b/packages/web/src/tableeditor/TableEditor.svelte index 95da33274..9ef70ebc4 100644 --- a/packages/web/src/tableeditor/TableEditor.svelte +++ b/packages/web/src/tableeditor/TableEditor.svelte @@ -3,8 +3,8 @@ registerCommand({ id: 'tableEditor.addColumn', - category: __t('tableEditor', { defaultMessage: 'Table editor'}), - name: __t('tableEditor.addColumn', { defaultMessage: 'Add column'}), + category: __t('tableEditor', { defaultMessage: 'Table editor' }), + name: __t('tableEditor.addColumn', { defaultMessage: 'Add column' }), icon: 'icon add-column', toolbar: true, isRelatedToTab: true, @@ -14,8 +14,8 @@ registerCommand({ id: 'tableEditor.addPrimaryKey', - category: __t('tableEditor', { defaultMessage: 'Table editor'}), - name: __t('tableEditor.addPrimaryKey', { defaultMessage: 'Add primary key'}), + category: __t('tableEditor', { defaultMessage: 'Table editor' }), + name: __t('tableEditor.addPrimaryKey', { defaultMessage: 'Add primary key' }), icon: 'icon add-key', toolbar: true, isRelatedToTab: true, @@ -25,8 +25,8 @@ registerCommand({ id: 'tableEditor.addForeignKey', - category: __t('tableEditor', { defaultMessage: 'Table editor'}), - name: __t('tableEditor.addForeignKey', { defaultMessage: 'Add foreign key'}), + category: __t('tableEditor', { defaultMessage: 'Table editor' }), + name: __t('tableEditor.addForeignKey', { defaultMessage: 'Add foreign key' }), icon: 'icon add-key', toolbar: true, isRelatedToTab: true, @@ -36,8 +36,8 @@ registerCommand({ id: 'tableEditor.addIndex', - category: __t('tableEditor', { defaultMessage: 'Table editor'}), - name: __t('tableEditor.addIndex', { defaultMessage: 'Add index'}), + category: __t('tableEditor', { defaultMessage: 'Table editor' }), + name: __t('tableEditor.addIndex', { defaultMessage: 'Add index' }), icon: 'icon add-key', toolbar: true, isRelatedToTab: true, @@ -47,8 +47,8 @@ registerCommand({ id: 'tableEditor.addUnique', - category: __t('tableEditor', { defaultMessage: 'Table editor'}), - name: __t('tableEditor.addUnique', { defaultMessage: 'Add unique'}), + category: __t('tableEditor', { defaultMessage: 'Table editor' }), + name: __t('tableEditor.addUnique', { defaultMessage: 'Add unique' }), icon: 'icon add-key', toolbar: true, isRelatedToTab: true, @@ -188,7 +188,10 @@ ({ ...x, ordinal: index + 1 }))} - title={_t('tableEditor.columns', { defaultMessage: 'Columns ({columnCount})', values: { columnCount: columns?.length || 0 } })} + title={_t('tableEditor.columns', { + defaultMessage: 'Columns ({columnCount})', + values: { columnCount: columns?.length || 0 }, + })} emptyMessage={_t('tableEditor.nocolumnsdefined', { defaultMessage: 'No columns defined' })} clickable on:clickrow={e => showModal(ColumnEditorModal, { columnInfo: e.detail, tableInfo, setTableInfo, driver })} @@ -217,9 +220,7 @@ text: _t('tableEditor.copydefinitions', { defaultMessage: 'Copy definitions' }), icon: 'icon copy', onClick: selected => { - const names = selected - .map(x => `${x.columnName} ${x.dataType}${x.notNull ? ' NOT NULL' : ''}`) - .join(',\n'); + const names = selected.map(x => `${x.columnName} ${x.dataType}${x.notNull ? ' NOT NULL' : ''}`).join(',\n'); navigator.clipboard.writeText(names); }, }, @@ -288,9 +289,21 @@ : null, ]} > - {row?.notNull ? _t('tableEditor.notnull', { defaultMessage: 'NOT NULL' }) : _t('tableEditor.null', { defaultMessage: 'NULL' })} - {row?.isSparse ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })} - {row?.isPersisted ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })} + {row?.notNull + ? _t('tableEditor.notnull', { defaultMessage: 'NOT NULL' }) + : _t('tableEditor.null', { defaultMessage: 'NULL' })} + {row?.isSparse + ? _t('tableEditor.yes', { defaultMessage: 'YES' }) + : _t('tableEditor.no', { defaultMessage: 'NO' })} + {row?.isPersisted + ? _t('tableEditor.yes', { defaultMessage: 'YES' }) + : _t('tableEditor.no', { defaultMessage: 'NO' })} { @@ -299,8 +312,16 @@ }}>{_t('tableEditor.remove', { defaultMessage: 'Remove' })} - {row?.isUnsigned ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })} - {row?.isZerofill ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })} + {row?.isUnsigned + ? _t('tableEditor.yes', { defaultMessage: 'YES' }) + : _t('tableEditor.no', { defaultMessage: 'NO' })} + {row?.isZerofill + ? _t('tableEditor.yes', { defaultMessage: 'YES' }) + : _t('tableEditor.no', { defaultMessage: 'NO' })} @@ -321,7 +342,10 @@ 0 ? addIndex : null} - title={_t('tableEditor.indexes', { defaultMessage: 'Indexes ({indexCount})', values: { indexCount: indexes?.length || 0 } })} + title={_t('tableEditor.indexes', { + defaultMessage: 'Indexes ({indexCount})', + values: { indexCount: indexes?.length || 0 }, + })} emptyMessage={isWritable ? _t('tableEditor.noindexdefined', { defaultMessage: 'No index defined' }) : null} clickable on:clickrow={e => showModal(IndexEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo, driver })} @@ -348,7 +372,11 @@ > {row?.columns.map(x => x.columnName).join(', ')} - {row?.isUnique ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })} + {row?.isUnique + ? _t('tableEditor.yes', { defaultMessage: 'YES' }) + : _t('tableEditor.no', { defaultMessage: 'NO' })} { @@ -364,7 +392,10 @@ 0 ? addUnique : null} - title={_t('tableEditor.uniqueConstraints', { defaultMessage: 'Unique constraints ({constraintCount})', values: { constraintCount: uniques?.length || 0 } })} + title={_t('tableEditor.uniqueConstraints', { + defaultMessage: 'Unique constraints ({constraintCount})', + values: { constraintCount: uniques?.length || 0 }, + })} emptyMessage={isWritable ? _t('tableEditor.nouniquedefined', { defaultMessage: 'No unique defined' }) : null} clickable on:clickrow={e => showModal(UniqueEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo })} @@ -401,13 +432,21 @@ 0 ? addForeignKey : null} - title={_t('tableEditor.foreignKeys', { defaultMessage: 'Foreign keys ({foreignKeyCount})', values: { foreignKeyCount: foreignKeys?.length || 0 } })} - emptyMessage={isWritable ? _t('tableEditor.noforeignkeydefined', { defaultMessage: 'No foreign key defined' }) : null} + title={_t('tableEditor.foreignKeys', { + defaultMessage: 'Foreign keys ({foreignKeyCount})', + values: { foreignKeyCount: foreignKeys?.length || 0 }, + })} + emptyMessage={isWritable + ? _t('tableEditor.noforeignkeydefined', { defaultMessage: 'No foreign key defined' }) + : null} clickable onRemove={row => setTableInfo(tbl => editorDeleteConstraint(tbl, row))} on:clickrow={e => showModal(ForeignKeyEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo, dbInfo })} /> - + {/if}
From abf0fc7942eac27be90d0bd94db9321e420e56dc Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 27 Nov 2025 14:06:48 +0100 Subject: [PATCH 46/76] incremental analysis in alter table tests --- .../__tests__/alter-table.spec.js | 72 ++++++++++++++++++- integration-tests/engines.js | 4 +- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/integration-tests/__tests__/alter-table.spec.js b/integration-tests/__tests__/alter-table.spec.js index 65e1b2d3f..21e0e4310 100644 --- a/integration-tests/__tests__/alter-table.spec.js +++ b/integration-tests/__tests__/alter-table.spec.js @@ -25,6 +25,13 @@ function pickImportantTableInfo(engine, table) { .map(props => _.omitBy(props, (v, k) => k == 'defaultValue' && v == 'NULL' && engine.setNullDefaultInsteadOfDrop) ), + foreignKeys: table.foreignKeys + .sort((a, b) => a.refTableName.localeCompare(b.refTableName)) + .map(fk => ({ + constraintType: fk.constraintType, + refTableName: fk.refTableName, + columns: fk.columns.map(col => ({ columnName: col.columnName, refColumnName: col.refColumnName })), + })), }; } @@ -33,7 +40,7 @@ function checkTableStructure(engine, t1, t2) { expect(pickImportantTableInfo(engine, t1)).toEqual(pickImportantTableInfo(engine, t2)); } -async function testTableDiff(engine, conn, driver, mangle) { +async function testTableDiff(engine, conn, driver, mangle, changedTable = 't1') { const initQuery = formatQueryWithoutParams(driver, `create table ~t0 (~id int not null primary key)`); await driver.query(conn, transformSqlForEngine(engine, initQuery)); @@ -68,8 +75,20 @@ async function testTableDiff(engine, conn, driver, mangle) { await driver.query(conn, transformSqlForEngine(engine, query)); } - const tget = x => x.tables.find(y => y.pureName == 't1'); - const structure1 = generateDbPairingId(extendDatabaseInfo(await driver.analyseFull(conn))); + if (!engine.skipReferences) { + const query = formatQueryWithoutParams( + driver, + `create table ~t3 (~id int not null primary key, ~fkval int ${ + driver.dialect.implicitNullDeclaration ? '' : 'null' + })` + ); + + await driver.query(conn, transformSqlForEngine(engine, query)); + } + + const tget = x => x.tables.find(y => y.pureName == changedTable); + const structure1Source = await driver.analyseFull(conn); + const structure1 = generateDbPairingId(extendDatabaseInfo(structure1Source)); let structure2 = _.cloneDeep(structure1); mangle(tget(structure2)); structure2 = extendDatabaseInfo(structure2); @@ -79,6 +98,11 @@ async function testTableDiff(engine, conn, driver, mangle) { await driver.script(conn, sql); + if (!engine.skipIncrementalAnalysis) { + const structure2RealIncremental = await driver.analyseIncremental(conn, structure1Source); + checkTableStructure(engine, tget(structure2RealIncremental), tget(structure2)); + } + const structure2Real = extendDatabaseInfo(await driver.analyseFull(conn)); checkTableStructure(engine, tget(structure2Real), tget(structure2)); @@ -214,6 +238,48 @@ describe('Alter table', () => { }) ); + test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))( + 'Drop FK - %s', + testWrapper(async (conn, driver, engine) => { + await testTableDiff( + engine, + conn, + driver, + tbl => { + tbl.foreignKeys = []; + }, + 't2' + ); + }) + ); + + test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))( + 'Create FK - %s', + testWrapper(async (conn, driver, engine) => { + await testTableDiff( + engine, + conn, + driver, + tbl => { + tbl.foreignKeys = [ + { + constraintType: 'foreignKey', + pureName: 't2', + refTableName: 't1', + columns: [ + { + columnName: 'fkval', + refColumnName: 'col_ref', + }, + ], + }, + ]; + }, + 't3' + ); + }) + ); + // test.each(engines.map(engine => [engine.label, engine]))( // 'Change autoincrement - %s', // testWrapper(async (conn, driver, engine) => { diff --git a/integration-tests/engines.js b/integration-tests/engines.js index 99b1308ea..94700af94 100644 --- a/integration-tests/engines.js +++ b/integration-tests/engines.js @@ -759,9 +759,9 @@ const enginesOnLocal = [ // cassandraEngine, //mysqlEngine, // mariaDbEngine, - //postgreSqlEngine, + postgreSqlEngine, //sqlServerEngine, - sqliteEngine, + // sqliteEngine, // cockroachDbEngine, // clickhouseEngine, // libsqlFileEngine, From 21eb27f6e383368716abc058054d24899c44a1b2 Mon Sep 17 00:00:00 2001 From: Stela Augustinova Date: Thu, 27 Nov 2025 14:42:24 +0100 Subject: [PATCH 47/76] Added new settings components, added wrapper to all setting components --- .../src/elements/SettingsMenuControl.svelte | 3 +- .../web/src/settings/BehaviourSettings.svelte | 2 + .../src/settings/ConnectionSettings.svelte | 3 + .../web/src/settings/DataGridSettings.svelte | 100 +++++++++ .../settings/DefaultActionsSettings.svelte | 3 + .../src/settings/ExternalToolsSettings.svelte | 2 + .../web/src/settings/GeneralSettings.svelte | 158 +------------- .../web/src/settings/OtherSettings.svelte | 3 + .../web/src/settings/SQLEditorSettings.svelte | 100 +++++++++ .../web/src/settings/ThemeSettings.svelte | 202 +++++++++--------- packages/web/src/tabs/SettingsTab.svelte | 16 ++ 11 files changed, 333 insertions(+), 259 deletions(-) create mode 100644 packages/web/src/settings/DataGridSettings.svelte create mode 100644 packages/web/src/settings/SQLEditorSettings.svelte diff --git a/packages/web/src/elements/SettingsMenuControl.svelte b/packages/web/src/elements/SettingsMenuControl.svelte index 8fc1bd875..7669682be 100644 --- a/packages/web/src/elements/SettingsMenuControl.svelte +++ b/packages/web/src/elements/SettingsMenuControl.svelte @@ -101,7 +101,7 @@ height: 100%; width: 100%; background-color: var(--theme-bg-2); - overflow-y: auto; + overflow-x: auto; } .menu::-webkit-scrollbar { @@ -111,7 +111,6 @@ .menu-item { white-space: nowrap; padding: 12px 20px; - width: 100%; display: flex; align-items: center; cursor: pointer; diff --git a/packages/web/src/settings/BehaviourSettings.svelte b/packages/web/src/settings/BehaviourSettings.svelte index 95d32d5f0..c4cb45704 100644 --- a/packages/web/src/settings/BehaviourSettings.svelte +++ b/packages/web/src/settings/BehaviourSettings.svelte @@ -5,6 +5,7 @@ import FormValues from "../forms/FormValues.svelte"; +
{_t('settings.behaviour', { defaultMessage: 'Behaviour' })}
@@ -52,6 +53,7 @@ })} />
+
\ No newline at end of file diff --git a/packages/web/src/settings/DefaultActionsSettings.svelte b/packages/web/src/settings/DefaultActionsSettings.svelte index ab360f830..a19d00ec0 100644 --- a/packages/web/src/settings/DefaultActionsSettings.svelte +++ b/packages/web/src/settings/DefaultActionsSettings.svelte @@ -8,6 +8,7 @@ +
{_t('settings.defaultActions', { defaultMessage: 'Default actions' })}
@@ -88,6 +89,8 @@ disabled={values['defaultAction.useLastUsedAction'] !== false} />
+
+ \ No newline at end of file diff --git a/packages/web/src/settings/ThemeSettings.svelte b/packages/web/src/settings/ThemeSettings.svelte index 80590f25d..4af6ad926 100644 --- a/packages/web/src/settings/ThemeSettings.svelte +++ b/packages/web/src/settings/ThemeSettings.svelte @@ -35,109 +35,110 @@ ORDER BY `; -
{_t('settings.appearance', { defaultMessage: 'Application theme' })}
+
+
{_t('settings.appearance', { defaultMessage: 'Application theme' })}
- { - if ($currentTheme) { - $currentTheme = null; - } else { - $currentTheme = getSystemTheme(); - } - }, -}} -> - { - if (e.target['checked']) { - $currentTheme = null; - } else { - $currentTheme = getSystemTheme(); - } - }} -/> - + { + if ($currentTheme) { + $currentTheme = null; + } else { + $currentTheme = getSystemTheme(); + } + }, + }} + > + { + if (e.target['checked']) { + $currentTheme = null; + } else { + $currentTheme = getSystemTheme(); + } + }} + /> + -
-{#each $extensions.themes as theme} - -{/each} +
+ {#each $extensions.themes as theme} + + {/each} +
+ +
+ {_t('settings.appearance.moreThemes', { defaultMessage: 'More themes are available as' })} + plugins +
+ {_t('settings.appearance.afterInstalling', { + defaultMessage: + 'After installing theme plugin (try search "theme" in available extensions) new themes will be available here.', + })} +
+ +
{_t('settings.appearance.editorTheme', { defaultMessage: 'Editor theme' })}
+ +
+
+ + ({ label: theme, value: theme }))} + value={$currentEditorTheme} + on:change={e => ($currentEditorTheme = e.detail)} + /> + +
+ +
+ + x.value == $currentEditorFontSize) ? $currentEditorFontSize : 'custom'} + on:change={e => ($currentEditorFontSize = e.detail)} + /> + +
+ +
+ + ($currentEditorFontSize = e.target['value'])} + disabled={!!FONT_SIZES.find(x => x.value == $currentEditorFontSize) && + $currentEditorFontSize != 'custom'} + /> + +
+ +
+ +
+
+ +
+ +
-
-{_t('settings.appearance.moreThemes', { defaultMessage: 'More themes are available as' })} -plugins -
-{_t('settings.appearance.afterInstalling', { - defaultMessage: - 'After installing theme plugin (try search "theme" in available extensions) new themes will be available here.', -})} -
- -
{_t('settings.appearance.editorTheme', { defaultMessage: 'Editor theme' })}
- -
-
- - ({ label: theme, value: theme }))} - value={$currentEditorTheme} - on:change={e => ($currentEditorTheme = e.detail)} - /> - -
- -
- - x.value == $currentEditorFontSize) ? $currentEditorFontSize : 'custom'} - on:change={e => ($currentEditorFontSize = e.detail)} - /> - -
- -
- - ($currentEditorFontSize = e.target['value'])} - disabled={!!FONT_SIZES.find(x => x.value == $currentEditorFontSize) && - $currentEditorFontSize != 'custom'} - /> - -
- -
- -
-
- -
- -
- - \ No newline at end of file diff --git a/packages/web/src/settings/DefaultActionsSettings.svelte b/packages/web/src/settings/DefaultActionsSettings.svelte index a19d00ec0..c0c293780 100644 --- a/packages/web/src/settings/DefaultActionsSettings.svelte +++ b/packages/web/src/settings/DefaultActionsSettings.svelte @@ -100,9 +100,4 @@ margin-top: var(--dim-large-form-margin); } - .tip { - margin-left: var(--dim-large-form-margin); - margin-top: var(--dim-large-form-margin); - } - \ No newline at end of file diff --git a/packages/web/src/settings/ExternalToolsSettings.svelte b/packages/web/src/settings/ExternalToolsSettings.svelte index a5958e4f6..56bbfbfb3 100644 --- a/packages/web/src/settings/ExternalToolsSettings.svelte +++ b/packages/web/src/settings/ExternalToolsSettings.svelte @@ -47,8 +47,4 @@ margin-top: var(--dim-large-form-margin); } - .tip { - margin-left: var(--dim-large-form-margin); - margin-top: var(--dim-large-form-margin); - } \ No newline at end of file diff --git a/packages/web/src/settings/GeneralSettings.svelte b/packages/web/src/settings/GeneralSettings.svelte index 459480980..acff0fedb 100644 --- a/packages/web/src/settings/GeneralSettings.svelte +++ b/packages/web/src/settings/GeneralSettings.svelte @@ -97,9 +97,4 @@ type="combo" margin-top: var(--dim-large-form-margin); } - .tip { - margin-left: var(--dim-large-form-margin); - margin-top: var(--dim-large-form-margin); - } - \ No newline at end of file diff --git a/packages/web/src/settings/LicenseSettings.svelte b/packages/web/src/settings/LicenseSettings.svelte index d25f6c51c..f9261d8b1 100644 --- a/packages/web/src/settings/LicenseSettings.svelte +++ b/packages/web/src/settings/LicenseSettings.svelte @@ -88,9 +88,4 @@ onChange={async value => { margin-left: var(--dim-large-form-margin); margin-top: var(--dim-large-form-margin); } - - .tip { - margin-left: var(--dim-large-form-margin); - margin-top: var(--dim-large-form-margin); - } \ No newline at end of file diff --git a/packages/web/src/settings/OtherSettings.svelte b/packages/web/src/settings/OtherSettings.svelte index 6ad9709b4..7ab2f36bb 100644 --- a/packages/web/src/settings/OtherSettings.svelte +++ b/packages/web/src/settings/OtherSettings.svelte @@ -61,9 +61,4 @@ options={[ margin-left: var(--dim-large-form-margin); margin-top: var(--dim-large-form-margin); } - - .tip { - margin-left: var(--dim-large-form-margin); - margin-top: var(--dim-large-form-margin); - } \ No newline at end of file diff --git a/packages/web/src/settings/ThemeSettings.svelte b/packages/web/src/settings/ThemeSettings.svelte index 4af6ad926..7d13e17d0 100644 --- a/packages/web/src/settings/ThemeSettings.svelte +++ b/packages/web/src/settings/ThemeSettings.svelte @@ -147,11 +147,6 @@ ORDER BY margin-top: var(--dim-large-form-margin); } - .tip { - margin-left: var(--dim-large-form-margin); - margin-top: var(--dim-large-form-margin); - } - .themes { display: flex; flex-wrap: wrap; From c3ea155a7b59456963ff2c735148573abff4de10 Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Fri, 28 Nov 2025 15:35:38 +0100 Subject: [PATCH 65/76] refresh database options --- .../commands/changeDatabaseStatusCommand.ts | 32 ++------------ packages/web/src/utility/common.ts | 42 ++++++++++++++++++- packages/web/src/widgets/SqlObjectList.svelte | 39 +++++++++++------ 3 files changed, 71 insertions(+), 42 deletions(-) diff --git a/packages/web/src/commands/changeDatabaseStatusCommand.ts b/packages/web/src/commands/changeDatabaseStatusCommand.ts index ff8b5f229..d5ed17452 100644 --- a/packages/web/src/commands/changeDatabaseStatusCommand.ts +++ b/packages/web/src/commands/changeDatabaseStatusCommand.ts @@ -3,7 +3,7 @@ import { currentDatabase, getCurrentDatabase } from '../stores'; import getElectron from '../utility/getElectron'; import registerCommand from './registerCommand'; import { apiCall } from '../utility/api'; -import { switchCurrentDatabase } from '../utility/common'; +import { getDatabasStatusMenu, switchCurrentDatabase } from '../utility/common'; import { __t } from '../translations'; registerCommand({ @@ -18,33 +18,7 @@ registerCommand({ conid: connection._id, database: name, }; - return [ - { - text: 'Sync model (incremental)', - onClick: () => { - apiCall('database-connections/sync-model', dbid); - }, - }, - { - text: 'Sync model (full)', - onClick: () => { - apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true }); - }, - }, - { - text: 'Reopen', - onClick: () => { - apiCall('database-connections/refresh', dbid); - }, - }, - { - text: 'Disconnect', - onClick: () => { - const electron = getElectron(); - if (electron) apiCall('database-connections/disconnect', dbid); - switchCurrentDatabase(null); - }, - }, - ]; + + return getDatabasStatusMenu(dbid); }, }); diff --git a/packages/web/src/utility/common.ts b/packages/web/src/utility/common.ts index 477d56670..2726e78a1 100644 --- a/packages/web/src/utility/common.ts +++ b/packages/web/src/utility/common.ts @@ -4,6 +4,8 @@ import _ from 'lodash'; import { getSchemaList } from './metadataLoaders'; import { showSnackbarError } from './snackbar'; import { _t } from '../translations'; +import { apiCall } from './api'; +import getElectron from './getElectron'; export class LoadingToken { isCanceled = false; @@ -63,7 +65,8 @@ export function getObjectTypeFieldLabel(objectTypeField, driver?) { if (objectTypeField == 'procedures') return _t('dbObject.procedures', { defaultMessage: 'Procedures' }); if (objectTypeField == 'functions') return _t('dbObject.functions', { defaultMessage: 'Functions' }); if (objectTypeField == 'triggers') return _t('dbObject.triggers', { defaultMessage: 'Triggers' }); - if (objectTypeField == 'schedulerEvents') return _t('dbObject.schedulerEvents', { defaultMessage: 'Scheduler Events' }); + if (objectTypeField == 'schedulerEvents') + return _t('dbObject.schedulerEvents', { defaultMessage: 'Scheduler Events' }); if (objectTypeField == 'matviews') return _t('dbObject.matviews', { defaultMessage: 'Materialized Views' }); if (objectTypeField == 'collections') return _t('dbObject.collections', { defaultMessage: 'Collections/Containers' }); return _.startCase(objectTypeField); @@ -151,3 +154,40 @@ export function getKeyTextFromEvent(e) { keyText += e.key; return keyText; } + +export function getDatabasStatusMenu(dbid) { + function callSchemalListChanged() { + apiCall('database-connections/dispatch-database-changed-event', { event: 'schema-list-changed', ...dbid }); + } + return [ + { + text: 'Refresh DB structure (incremental)', + onClick: () => { + apiCall('database-connections/sync-model', dbid); + callSchemalListChanged(); + }, + }, + { + text: 'Refresh DB structure (full)', + onClick: () => { + apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true }); + callSchemalListChanged(); + }, + }, + { + text: 'Reopen connection', + onClick: () => { + apiCall('database-connections/refresh', dbid); + callSchemalListChanged(); + }, + }, + { + text: 'Disconnect', + onClick: () => { + const electron = getElectron(); + if (electron) apiCall('database-connections/disconnect', dbid); + switchCurrentDatabase(null); + }, + }, + ]; +} diff --git a/packages/web/src/widgets/SqlObjectList.svelte b/packages/web/src/widgets/SqlObjectList.svelte index cf9c2c81d..1f9bc893b 100644 --- a/packages/web/src/widgets/SqlObjectList.svelte +++ b/packages/web/src/widgets/SqlObjectList.svelte @@ -31,7 +31,7 @@ import { chevronExpandIcon } from '../icons/expandIcons'; import ErrorInfo from '../elements/ErrorInfo.svelte'; import LoadingInfo from '../elements/LoadingInfo.svelte'; - import { getObjectTypeFieldLabel } from '../utility/common'; + import { getDatabasStatusMenu, getObjectTypeFieldLabel } from '../utility/common'; import DropDownButton from '../buttons/DropDownButton.svelte'; import FontIcon from '../icons/FontIcon.svelte'; import CloseSearchButton from '../buttons/CloseSearchButton.svelte'; @@ -120,11 +120,6 @@ // setInterval(() => (generateIndex += 1), 2000); // $: objectList = generateObjectList(generateIndex); - const handleRefreshDatabase = () => { - apiCall('database-connections/refresh', { conid, database }); - apiCall('database-connections/dispatch-database-changed-event', { event: 'schema-list-changed', conid, database }); - }; - function createAddMenu() { const res = []; if (driver?.databaseEngineTypes?.includes('document')) { @@ -147,6 +142,15 @@ return res; } + function createRefreshDatabaseMenu() { + return getDatabasStatusMenu({ conid, database }); + } + + function handleFullRefreshDatabase() { + apiCall('database-connections/sync-model', { conid, database, isFullRefresh: true }); + apiCall('database-connections/dispatch-database-changed-event', { event: 'schema-list-changed', conid, database }); + } + function createSearchMenu() { const res = []; res.push({ label: _t('sqlObject.searchBy', { defaultMessage: 'Search by:' }), isBold: true, disabled: true }); @@ -237,7 +241,18 @@ - {_t('common.refresh', { defaultMessage: 'Refresh' })} + {_t('common.refresh', { defaultMessage: 'Refresh' })} + + {:else if objectList.length == 0 && $status && $status.name != 'pending' && $status.name != 'checkStructure' && $status.name != 'loadStructure' && $objects} {/if} - - - + icon="icon dots-vertical" + /> Date: Fri, 28 Nov 2025 15:37:34 +0100 Subject: [PATCH 66/76] lang texts --- packages/web/src/utility/common.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/web/src/utility/common.ts b/packages/web/src/utility/common.ts index 2726e78a1..71bcca5c8 100644 --- a/packages/web/src/utility/common.ts +++ b/packages/web/src/utility/common.ts @@ -161,28 +161,28 @@ export function getDatabasStatusMenu(dbid) { } return [ { - text: 'Refresh DB structure (incremental)', + text: _t('command.database.refreshIncremental', { defaultMessage: 'Refresh DB structure (incremental)' }), onClick: () => { apiCall('database-connections/sync-model', dbid); callSchemalListChanged(); }, }, { - text: 'Refresh DB structure (full)', + text: _t('command.database.refreshFull', { defaultMessage: 'Refresh DB structure (full)' }), onClick: () => { apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true }); callSchemalListChanged(); }, }, { - text: 'Reopen connection', + text: _t('command.database.reopenConnection', { defaultMessage: 'Reopen connection' }), onClick: () => { apiCall('database-connections/refresh', dbid); callSchemalListChanged(); }, }, { - text: 'Disconnect', + text: _t('command.database.disconnect', { defaultMessage: 'Disconnect' }), onClick: () => { const electron = getElectron(); if (electron) apiCall('database-connections/disconnect', dbid); From a65842e31fb1958fb5d263212b0991399c5d0e9e Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Fri, 28 Nov 2025 16:07:36 +0100 Subject: [PATCH 67/76] table backups --- .../web/src/appobj/DatabaseObjectAppObject.svelte | 14 ++++++++++++-- packages/web/src/icons/FontIcon.svelte | 1 + packages/web/src/widgets/SqlObjectList.svelte | 11 ++++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte index 871e6da1d..6dfc28d17 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte +++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte @@ -1086,14 +1086,24 @@ } $: isPinned = !!$pinnedTables.find(x => testEqual(data, x)); + + $: backupParsed = + data.objectTypeField === 'tables' + ? data.pureName.match(/^_(.*)_(\d\d\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)$/) + : null; + $: backupTitle = + backupParsed != null + ? `${backupParsed[1]} (${backupParsed[2]}-${backupParsed[3]}-${backupParsed[4]} ${backupParsed[5]}:${backupParsed[6]}:${backupParsed[7]})` + : null; pinnedTables.update(list => [...list, data])} diff --git a/packages/web/src/icons/FontIcon.svelte b/packages/web/src/icons/FontIcon.svelte index 72fcd7c41..743461e0e 100644 --- a/packages/web/src/icons/FontIcon.svelte +++ b/packages/web/src/icons/FontIcon.svelte @@ -353,6 +353,7 @@ 'img data-deploy': 'mdi mdi-database-settings color-icon-green', 'img arrow-start-here': 'mdi mdi-arrow-down-bold-circle color-icon-green', 'img team-file': 'mdi mdi-account-file color-icon-red', + 'img table-backup': 'mdi mdi-cube color-icon-yellow', }; diff --git a/packages/web/src/widgets/SqlObjectList.svelte b/packages/web/src/widgets/SqlObjectList.svelte index 1f9bc893b..fa24ff1d8 100644 --- a/packages/web/src/widgets/SqlObjectList.svelte +++ b/packages/web/src/widgets/SqlObjectList.svelte @@ -232,6 +232,15 @@ $focusedConnectionOrDatabase?.database != extractDbNameFromComposite(database))); // $: console.log('STATUS', $status); + + function getAppObjectGroup(data) { + if (data.objectTypeField == 'tables') { + if (data.pureName.match(/^_(.*)_\d\d\d\d-\d\d-\d\d-\d\d-\d\d-\d\d$/)) { + return _t('dbObject.tableBackups', { defaultMessage: 'Table Backups' }); + } + } + return getObjectTypeFieldLabel(data.objectTypeField, driver); + } {#if $status && $status.name == 'error'} @@ -371,7 +380,7 @@ .filter(x => x.schemaName == null || ($appliedCurrentSchema ? x.schemaName == $appliedCurrentSchema : true)) .map(x => ({ ...x, conid, database }))} module={databaseObjectAppObject} - groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField, driver)} + groupFunc={getAppObjectGroup} subItemsComponent={(data, { isExpandedBySearch }) => data.objectTypeField == 'procedures' || data.objectTypeField == 'functions' ? isExpandedBySearch From d650d91d8228f51987028e2fd622c62c668ec06c Mon Sep 17 00:00:00 2001 From: "SPRINX0\\prochazka" Date: Mon, 1 Dec 2025 10:08:00 +0100 Subject: [PATCH 68/76] table restore script WIP --- packages/sqltree/src/dumpSqlCommand.ts | 7 ++- packages/sqltree/src/types.ts | 1 + .../src/appobj/DatabaseObjectAppObject.svelte | 55 +++++++++++++++---- .../web/src/utility/tableRestoreScript.ts | 45 +++++++++++++++ packages/web/src/widgets/SqlObjectList.svelte | 2 +- 5 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 packages/web/src/utility/tableRestoreScript.ts diff --git a/packages/sqltree/src/dumpSqlCommand.ts b/packages/sqltree/src/dumpSqlCommand.ts index e8286bafb..b3b9373a4 100644 --- a/packages/sqltree/src/dumpSqlCommand.ts +++ b/packages/sqltree/src/dumpSqlCommand.ts @@ -1,7 +1,7 @@ import type { SqlDumper } from 'dbgate-types'; import { Command, Select, Update, Delete, Insert } from './types'; import { dumpSqlExpression } from './dumpSqlExpression'; -import { dumpSqlFromDefinition, dumpSqlSourceRef } from './dumpSqlSource'; +import { dumpSqlFromDefinition, dumpSqlSourceDef, dumpSqlSourceRef } from './dumpSqlSource'; import { dumpSqlCondition } from './dumpSqlCondition'; export function dumpSqlSelect(dmp: SqlDumper, cmd: Select) { @@ -115,7 +115,10 @@ export function dumpSqlInsert(dmp: SqlDumper, cmd: Insert) { cmd.fields.map(x => x.targetColumn) ); dmp.putCollection(',', cmd.fields, x => dumpSqlExpression(dmp, x)); - if (dmp.dialect.requireFromDual) { + if (cmd.whereNotExistsSource) { + dmp.put(' ^from '); + dumpSqlSourceDef(dmp, cmd.whereNotExistsSource); + } else if (dmp.dialect.requireFromDual) { dmp.put(' ^from ^dual '); } dmp.put(' ^where ^not ^exists (^select * ^from %f ^where ', cmd.targetTable); diff --git a/packages/sqltree/src/types.ts b/packages/sqltree/src/types.ts index bce0e61d3..493745059 100644 --- a/packages/sqltree/src/types.ts +++ b/packages/sqltree/src/types.ts @@ -44,6 +44,7 @@ export interface Insert { fields: UpdateField[]; targetTable: NamedObjectInfo; insertWhereNotExistsCondition?: Condition; + whereNotExistsSource?: Source; } export interface AllowIdentityInsert { diff --git a/packages/web/src/appobj/DatabaseObjectAppObject.svelte b/packages/web/src/appobj/DatabaseObjectAppObject.svelte index 6dfc28d17..3ea5c6037 100644 --- a/packages/web/src/appobj/DatabaseObjectAppObject.svelte +++ b/packages/web/src/appobj/DatabaseObjectAppObject.svelte @@ -1,6 +1,7 @@
DateTimeCodeMessageConnectionDatabaseEngineCallerName{_t('logs.dateTab', { defaultMessage: 'Date' })}{_t('logs.timeTab', { defaultMessage: 'Time' })}{_t('logs.codeTab', { defaultMessage: 'Code' })}{_t('logs.messageTab', { defaultMessage: 'Message' })}{_t('logs.connectionTab', { defaultMessage: 'Connection' })}{_t('logs.databaseTab', { defaultMessage: 'Database' })}{_t('logs.engineTab', { defaultMessage: 'Engine' })}{_t('logs.callerTab', { defaultMessage: 'Caller' })}{_t('logs.nameTab', { defaultMessage: 'Name' })}
No data for selected date{_t('logs.noDataForSelectedDate', { defaultMessage: "No data for selected date" })}
Loading next rows... {_t('logs.loadingNextRows', { defaultMessage: "Loading next rows..." })}