Merge branch 'master' into feature/FK-test

This commit is contained in:
Stela Augustinova
2025-12-04 14:36:14 +01:00
41 changed files with 454 additions and 314 deletions

View File

@@ -43,7 +43,7 @@ jobs:
repository: dbgate/dbgate-pro repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro path: dbgate-pro
ref: 911941a53e91a5a777b8c7d455be0719234dde5f ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
- name: Merge dbgate/dbgate-pro - name: Merge dbgate/dbgate-pro
run: | run: |
mkdir ../dbgate-pro mkdir ../dbgate-pro

View File

@@ -43,7 +43,7 @@ jobs:
repository: dbgate/dbgate-pro repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro path: dbgate-pro
ref: 911941a53e91a5a777b8c7d455be0719234dde5f ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
- name: Merge dbgate/dbgate-pro - name: Merge dbgate/dbgate-pro
run: | run: |
mkdir ../dbgate-pro mkdir ../dbgate-pro

View File

@@ -39,7 +39,7 @@ jobs:
repository: dbgate/dbgate-pro repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro path: dbgate-pro
ref: 911941a53e91a5a777b8c7d455be0719234dde5f ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
- name: Merge dbgate/dbgate-pro - name: Merge dbgate/dbgate-pro
run: | run: |
mkdir ../dbgate-pro mkdir ../dbgate-pro

View File

@@ -44,7 +44,7 @@ jobs:
repository: dbgate/dbgate-pro repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro path: dbgate-pro
ref: 911941a53e91a5a777b8c7d455be0719234dde5f ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
- name: Merge dbgate/dbgate-pro - name: Merge dbgate/dbgate-pro
run: | run: |
mkdir ../dbgate-pro mkdir ../dbgate-pro

View File

@@ -35,7 +35,7 @@ jobs:
repository: dbgate/dbgate-pro repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro path: dbgate-pro
ref: 911941a53e91a5a777b8c7d455be0719234dde5f ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
- name: Merge dbgate/dbgate-pro - name: Merge dbgate/dbgate-pro
run: | run: |
mkdir ../dbgate-pro mkdir ../dbgate-pro

View File

@@ -26,7 +26,7 @@ jobs:
repository: dbgate/dbgate-pro repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro path: dbgate-pro
ref: 911941a53e91a5a777b8c7d455be0719234dde5f ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
- name: Merge dbgate/dbgate-pro - name: Merge dbgate/dbgate-pro
run: | run: |
mkdir ../dbgate-pro mkdir ../dbgate-pro

View File

@@ -8,13 +8,19 @@ Builds:
- linux - application for linux - linux - application for linux
- win - application for Windows - win - application for Windows
## 6.7.2 - not released ## 6.7.3
- FIXED: Fixed problem in analyser core - in PostgreSQL, after dropping table, dropped table still appeared in structure
- FIXED: PostgreSQL numeric columns do not align right #1254
- ADDED: Custom thousands separator #1213
## 6.7.2
- CHANGED: Settings modal redesign - now is settings opened in tab instead of modal, similarily as in VSCode - CHANGED: Settings modal redesign - now is settings opened in tab instead of modal, similarily as in VSCode
- FIXED: Fixed search in table shortcuts #1273 - FIXED: Fixed search in table shortcuts #1273
- CHANGED: Improved foreign key editor UX - CHANGED: Improved foreign key editor UX
- FIXED: Fixed incremental DB structure refresh for PostgreSQL, optimalized slow loading primary keys in PostgreSQL - FIXED: Fixed incremental DB structure refresh for PostgreSQL, optimalized slow loading primary keys in PostgreSQL
- CHANGED: You could now choose, how to refresh structure, added ability to disconnect or reconnect - CHANGED: You could now choose, how to refresh structure, added ability to disconnect or reconnect
- ADDED: Better processing of table backups, generate table restore script #1274 - ADDED: Better processing of table backups, generate table restore script #1274
- CHANGED: Improved storage of settings, especially for Team Premium edition
## 6.7.1 ## 6.7.1
- ADDED: LANGUAGE environment variable for the web version. #1266 - ADDED: LANGUAGE environment variable for the web version. #1266

View File

@@ -10,6 +10,7 @@ module.exports = defineConfig({
// baseUrl: 'http://localhost:3000', // baseUrl: 'http://localhost:3000',
// trashAssetsBeforeRuns: false, // trashAssetsBeforeRuns: false,
chromeWebSecurity: false, chromeWebSecurity: false,
reporter: process.env.CI ? 'mocha-reporter-gha' : 'spec',
setupNodeEvents(on, config) { setupNodeEvents(on, config) {
// implement node event listeners here // implement node event listeners here

View File

@@ -110,7 +110,7 @@ describe('Charts', () => {
cy.themeshot('new-object-window'); cy.themeshot('new-object-window');
}); });
it('Database chat - charts', () => { it.skip('Database chat - charts', () => {
cy.contains('MySql-connection').click(); cy.contains('MySql-connection').click();
cy.contains('MyChinook').click(); cy.contains('MyChinook').click();
cy.testid('TabsPanel_buttonNewObject').click(); cy.testid('TabsPanel_buttonNewObject').click();
@@ -125,7 +125,7 @@ describe('Charts', () => {
cy.themeshot('database-chat-chart'); cy.themeshot('database-chat-chart');
}); });
it('Database chat', () => { it.skip('Database chat', () => {
cy.contains('MySql-connection').click(); cy.contains('MySql-connection').click();
cy.contains('MyChinook').click(); cy.contains('MyChinook').click();
cy.testid('TabsPanel_buttonNewObject').click(); cy.testid('TabsPanel_buttonNewObject').click();
@@ -146,7 +146,7 @@ describe('Charts', () => {
// cy.themeshot('database-chat'); // cy.themeshot('database-chat');
}); });
it('Explain query error', () => { it.skip('Explain query error', () => {
cy.contains('MySql-connection').click(); cy.contains('MySql-connection').click();
cy.contains('MyChinook').click(); cy.contains('MyChinook').click();
cy.testid('TabsPanel_buttonNewObject').click(); cy.testid('TabsPanel_buttonNewObject').click();
@@ -199,7 +199,7 @@ describe('Charts', () => {
cy.testid('WidgetIconPanel_settings'); cy.testid('WidgetIconPanel_settings');
}); });
it.only('Settings', () => { it('Settings', () => {
cy.testid('WidgetIconPanel_settings').click(); cy.testid('WidgetIconPanel_settings').click();
cy.themeshot('app-settings-general'); cy.themeshot('app-settings-general');
@@ -234,10 +234,10 @@ describe('Charts', () => {
cy.contains('Light').click(); cy.contains('Light').click();
cy.get('body').find('.theme-light').should('exist'); cy.get('body').find('.theme-light').should('exist');
// Connection // General
cy.contains(/^Connection$/).click(); cy.contains(/^General$/).click();
cy.contains('charts_sample'); cy.contains('charts_sample');
cy.get('[data-testid=ConnectionSettings_lockedDatabaseMode]').check(); cy.get('[data-testid=GeneralSettings_lockedDatabaseMode]').check();
cy.contains('Connections').click(); cy.contains('Connections').click();
cy.contains('charts_sample').should('not.exist'); cy.contains('charts_sample').should('not.exist');

View File

@@ -210,7 +210,8 @@ describe('Import CSV', () => {
cy.testid('ImportExportConfigurator_tableMappingSection').contains('20 rows written').should('be.visible'); cy.testid('ImportExportConfigurator_tableMappingSection').contains('20 rows written').should('be.visible');
cy.testid('SqlObjectList_refreshButton').click(); cy.testid('SqlObjectList_refreshButton').click();
cy.contains('Refresh DB structure (incremental)').click(); cy.testid('DatabasStatusMenu_refreshFull').click();
// cy.contains('Refresh DB structure (incremental)').click();
cy.testid('SqlObjectList_container').contains('customers-20').click(); cy.testid('SqlObjectList_container').contains('customers-20').click();
cy.contains('Rows: 20').should('be.visible'); cy.contains('Rows: 20').should('be.visible');

View File

@@ -10,11 +10,11 @@
"cypress-real-events": "^1.13.0", "cypress-real-events": "^1.13.0",
"env-cmd": "^10.1.0", "env-cmd": "^10.1.0",
"kill-port": "^2.0.1", "kill-port": "^2.0.1",
"mocha-reporter-gha": "^1.1.1",
"start-server-and-test": "^2.0.8" "start-server-and-test": "^2.0.8"
}, },
"scripts": { "scripts": {
"cy:open": "cypress open --config experimentalInteractiveRunEvents=true", "cy:open": "cypress open --config experimentalInteractiveRunEvents=true",
"cy:run:add-connection": "cypress run --spec cypress/e2e/add-connection.cy.js", "cy:run:add-connection": "cypress run --spec cypress/e2e/add-connection.cy.js",
"cy:run:portal": "cypress run --spec cypress/e2e/portal.cy.js", "cy:run:portal": "cypress run --spec cypress/e2e/portal.cy.js",
"cy:run:oauth": "cypress run --spec cypress/e2e/oauth.cy.js", "cy:run:oauth": "cypress run --spec cypress/e2e/oauth.cy.js",
@@ -23,7 +23,6 @@
"cy:run:multi-sql": "cypress run --spec cypress/e2e/multi-sql.cy.js", "cy:run:multi-sql": "cypress run --spec cypress/e2e/multi-sql.cy.js",
"cy:run:cloud": "cypress run --spec cypress/e2e/cloud.cy.js", "cy:run:cloud": "cypress run --spec cypress/e2e/cloud.cy.js",
"cy:run:charts": "cypress run --spec cypress/e2e/charts.cy.js", "cy:run:charts": "cypress run --spec cypress/e2e/charts.cy.js",
"start:add-connection": "node clearTestingData && cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests", "start:add-connection": "node clearTestingData && cd .. && node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:portal": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests", "start:portal": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/portal/.env node e2e-tests/init/portal.js && env-cmd -f e2e-tests/env/portal/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:oauth": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests", "start:oauth": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/oauth/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
@@ -32,7 +31,6 @@
"start:multi-sql": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/multi-sql/.env node e2e-tests/init/multi-sql.js && env-cmd -f e2e-tests/env/multi-sql/.env node packer/build/bundle.js --listen-api --run-e2e-tests", "start:multi-sql": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/multi-sql/.env node e2e-tests/init/multi-sql.js && env-cmd -f e2e-tests/env/multi-sql/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:cloud": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/cloud/.env node packer/build/bundle.js --listen-api --run-e2e-tests", "start:cloud": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/cloud/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"start:charts": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/charts/.env node e2e-tests/init/charts.js && env-cmd -f e2e-tests/env/charts/.env node packer/build/bundle.js --listen-api --run-e2e-tests", "start:charts": "node clearTestingData && cd .. && env-cmd -f e2e-tests/env/charts/.env node e2e-tests/init/charts.js && env-cmd -f e2e-tests/env/charts/.env node packer/build/bundle.js --listen-api --run-e2e-tests",
"test:add-connection": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection", "test:add-connection": "start-server-and-test start:add-connection http://localhost:3000 cy:run:add-connection",
"test:portal": "start-server-and-test start:portal http://localhost:3000 cy:run:portal", "test:portal": "start-server-and-test start:portal http://localhost:3000 cy:run:portal",
"test:oauth": "start-server-and-test start:oauth http://localhost:3000 cy:run:oauth", "test:oauth": "start-server-and-test start:oauth http://localhost:3000 cy:run:oauth",
@@ -41,7 +39,6 @@
"test:multi-sql": "start-server-and-test start:multi-sql http://localhost:3000 cy:run:multi-sql", "test:multi-sql": "start-server-and-test start:multi-sql http://localhost:3000 cy:run:multi-sql",
"test:cloud": "start-server-and-test start:cloud http://localhost:3000 cy:run:cloud", "test:cloud": "start-server-and-test start:cloud http://localhost:3000 cy:run:cloud",
"test:charts": "start-server-and-test start:charts http://localhost:3000 cy:run:charts", "test:charts": "start-server-and-test start:charts http://localhost:3000 cy:run:charts",
"test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team && yarn test:multi-sql && yarn test:cloud && yarn test:charts", "test": "yarn test:add-connection && yarn test:portal && yarn test:oauth && yarn test:browse-data && yarn test:team && yarn test:multi-sql && yarn test:cloud && yarn test:charts",
"test:ci": "yarn test" "test:ci": "yarn test"
}, },

View File

@@ -2,6 +2,34 @@
# yarn lockfile v1 # yarn lockfile v1
"@actions/core@^1.10.1":
version "1.11.1"
resolved "https://registry.yarnpkg.com/@actions/core/-/core-1.11.1.tgz#ae683aac5112438021588030efb53b1adb86f172"
integrity sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==
dependencies:
"@actions/exec" "^1.1.1"
"@actions/http-client" "^2.0.1"
"@actions/exec@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@actions/exec/-/exec-1.1.1.tgz#2e43f28c54022537172819a7cf886c844221a611"
integrity sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==
dependencies:
"@actions/io" "^1.0.1"
"@actions/http-client@^2.0.1":
version "2.2.3"
resolved "https://registry.yarnpkg.com/@actions/http-client/-/http-client-2.2.3.tgz#31fc0b25c0e665754ed39a9f19a8611fc6dab674"
integrity sha512-mx8hyJi/hjFvbPokCg4uRd4ZX78t+YyRPtnKWwIl+RzNaVuFpQHfmlGVfsKEJN8LwTCvL+DfVgAM04XaHkm6bA==
dependencies:
tunnel "^0.0.6"
undici "^5.25.4"
"@actions/io@^1.0.1":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@actions/io/-/io-1.1.3.tgz#4cdb6254da7962b07473ff5c335f3da485d94d71"
integrity sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q==
"@colors/colors@1.5.0": "@colors/colors@1.5.0":
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
@@ -39,6 +67,11 @@
debug "^3.1.0" debug "^3.1.0"
lodash.once "^4.1.1" lodash.once "^4.1.1"
"@fastify/busboy@^2.0.0":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.1.1.tgz#b9da6a878a371829a0502c9b6c1c143ef6663f4d"
integrity sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==
"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": "@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0":
version "9.3.0" version "9.3.0"
resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb"
@@ -947,6 +980,13 @@ minimist@^1.2.8:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
mocha-reporter-gha@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/mocha-reporter-gha/-/mocha-reporter-gha-1.1.1.tgz#e1248abd0769f55b57b36ccd7db2b0b6573d5adf"
integrity sha512-CFbcgM56V4yWlbF91XuwrE6a5X/IqjVXTPefO7m8cY8Es8G1UhJ2KKOrk16AcSemRzVWXp2Fdy3bWJ7j45snWw==
dependencies:
"@actions/core" "^1.10.1"
ms@^2.1.1, ms@^2.1.3: ms@^2.1.1, ms@^2.1.3:
version "2.1.3" version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
@@ -1292,6 +1332,11 @@ tunnel-agent@^0.6.0:
dependencies: dependencies:
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
tunnel@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c"
integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==
tweetnacl@^0.14.3, tweetnacl@~0.14.0: tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5" version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
@@ -1307,6 +1352,13 @@ undici-types@~6.20.0:
resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433"
integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg== integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==
undici@^5.25.4:
version "5.29.0"
resolved "https://registry.yarnpkg.com/undici/-/undici-5.29.0.tgz#419595449ae3f2cdcba3580a2e8903399bd1f5a3"
integrity sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg==
dependencies:
"@fastify/busboy" "^2.0.0"
universalify@^2.0.0: universalify@^2.0.0:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"

View File

@@ -28,12 +28,12 @@ describe('Schema tests', () => {
const count = schemas1.length; const count = schemas1.length;
expect(structure1.tables.length).toEqual(2); expect(structure1.tables.length).toEqual(2);
await runCommandOnDriver(conn, driver, dmp => dmp.createSchema('myschema')); await runCommandOnDriver(conn, driver, dmp => dmp.createSchema('myschema'));
const structure2 = await driver.analyseIncremental(conn, structure1);
const schemas2 = await driver.listSchemas(conn);
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeTruthy();
expect(schemas2.length).toEqual(count + 1);
expect(schemas2.find(x => x.isDefault).schemaName).toEqual(engine.defaultSchemaName);
if (!engine.skipIncrementalAnalysis) { if (!engine.skipIncrementalAnalysis) {
const structure2 = await driver.analyseIncremental(conn, structure1);
const schemas2 = await driver.listSchemas(conn);
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeTruthy();
expect(schemas2.length).toEqual(count + 1);
expect(schemas2.find(x => x.isDefault).schemaName).toEqual(engine.defaultSchemaName);
expect(structure2).toBeNull(); expect(structure2).toBeNull();
} }
}) })
@@ -50,10 +50,10 @@ describe('Schema tests', () => {
expect(schemas1.find(x => x.schemaName == 'myschema')).toBeTruthy(); expect(schemas1.find(x => x.schemaName == 'myschema')).toBeTruthy();
expect(structure1.tables.length).toEqual(2); expect(structure1.tables.length).toEqual(2);
await runCommandOnDriver(conn, driver, dmp => dmp.dropSchema('myschema')); await runCommandOnDriver(conn, driver, dmp => dmp.dropSchema('myschema'));
const structure2 = await driver.analyseIncremental(conn, structure1);
const schemas2 = await driver.listSchemas(conn);
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeFalsy();
if (!engine.skipIncrementalAnalysis) { if (!engine.skipIncrementalAnalysis) {
const structure2 = await driver.analyseIncremental(conn, structure1);
const schemas2 = await driver.listSchemas(conn);
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeFalsy();
expect(structure2).toBeNull(); expect(structure2).toBeNull();
} }
}) })

View File

@@ -94,7 +94,7 @@ describe('Table analyse', () => {
}) })
); );
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))( test.each(engines.map(engine => [engine.label, engine]))(
'Table add - incremental analysis - %s', 'Table add - incremental analysis - %s',
testWrapper(async (conn, driver, engine) => { testWrapper(async (conn, driver, engine) => {
await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine))); await runCommandOnDriver(conn, driver, dmp => dmp.put(t2Sql(engine)));
@@ -112,7 +112,7 @@ describe('Table analyse', () => {
}) })
); );
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))( test.each(engines.map(engine => [engine.label, engine]))(
'Table remove - incremental analysis - %s', 'Table remove - incremental analysis - %s',
testWrapper(async (conn, driver, engine) => { testWrapper(async (conn, driver, engine) => {
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine))); await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
@@ -130,7 +130,7 @@ describe('Table analyse', () => {
}) })
); );
test.each(engines.filter(x => !x.skipIncrementalAnalysis).map(engine => [engine.label, engine]))( test.each(engines.map(engine => [engine.label, engine]))(
'Table change - incremental analysis - %s', 'Table change - incremental analysis - %s',
testWrapper(async (conn, driver, engine) => { testWrapper(async (conn, driver, engine) => {
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine))); await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));

View File

@@ -1,6 +1,6 @@
{ {
"private": true, "private": true,
"version": "6.7.2-premium-beta.5", "version": "6.7.3",
"name": "dbgate-all", "name": "dbgate-all",
"workspaces": [ "workspaces": [
"packages/*", "packages/*",

View File

@@ -289,16 +289,11 @@ module.exports = {
const res = await lock.acquire('settings', async () => { const res = await lock.acquire('settings', async () => {
const currentValue = await this.loadSettings(); const currentValue = await this.loadSettings();
try { try {
let updated = currentValue; let updated = {
...currentValue,
...values,
};
if (process.env.STORAGE_DATABASE) { if (process.env.STORAGE_DATABASE) {
updated = {
...currentValue,
..._.mapValues(values, v => {
if (v === true) return 'true';
if (v === false) return 'false';
return v;
}),
};
await storage.writeConfig({ await storage.writeConfig({
group: 'settings', group: 'settings',
config: updated, config: updated,

View File

@@ -360,6 +360,12 @@ module.exports = {
"columnName": "value", "columnName": "value",
"dataType": "varchar(1000)", "dataType": "varchar(1000)",
"notNull": false "notNull": false
},
{
"pureName": "config",
"columnName": "valueType",
"dataType": "varchar(50)",
"notNull": false
} }
], ],
"foreignKeys": [], "foreignKeys": [],

View File

@@ -164,6 +164,11 @@ export class DatabaseAnalyser<TClient = any> {
const res = {}; const res = {};
for (const field of STRUCTURE_FIELDS) { for (const field of STRUCTURE_FIELDS) {
const isAll = this.modifications.some(x => x.action == 'all' && x.objectTypeField == field);
if (isAll) {
res[field] = newlyAnalysed[field] || [];
continue;
}
const removedIds = this.modifications const removedIds = this.modifications
.filter(x => x.action == 'remove' && x.objectTypeField == field) .filter(x => x.action == 'remove' && x.objectTypeField == field)
.map(x => x.objectId); .map(x => x.objectId);

View File

@@ -45,14 +45,15 @@ export function hexStringToArray(inputString) {
export function base64ToHex(base64String) { export function base64ToHex(base64String) {
const binaryString = atob(base64String); const binaryString = atob(base64String);
const hexString = Array.from(binaryString, c => const hexString = Array.from(binaryString, c => c.charCodeAt(0).toString(16).padStart(2, '0')).join('');
c.charCodeAt(0).toString(16).padStart(2, '0')
).join('');
return '0x' + hexString.toUpperCase(); return '0x' + hexString.toUpperCase();
}; }
export function hexToBase64(hexString) { export function hexToBase64(hexString) {
const binaryString = hexString.match(/.{1,2}/g).map(byte => String.fromCharCode(parseInt(byte, 16))).join(''); const binaryString = hexString
.match(/.{1,2}/g)
.map(byte => String.fromCharCode(parseInt(byte, 16)))
.join('');
return btoa(binaryString); return btoa(binaryString);
} }
@@ -68,9 +69,9 @@ export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
if (mHex) { if (mHex) {
return { return {
$binary: { $binary: {
base64: hexToBase64(value.substring(2)) base64: hexToBase64(value.substring(2)),
} },
} };
} }
} }
@@ -200,6 +201,26 @@ function stringifyJsonToGrid(value): ReturnType<typeof stringifyCellValue> {
return { value: '(JSON)', gridStyle: 'nullCellStyle' }; return { value: '(JSON)', gridStyle: 'nullCellStyle' };
} }
function formatNumberCustomSeparator(value, thousandsSeparator) {
const [intPart, decPart] = value.split('.');
const intPartWithSeparator = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
return decPart ? `${intPartWithSeparator}.${decPart}` : intPartWithSeparator;
}
function formatCellNumber(value, gridFormattingOptions?: { thousandsSeparator?: string }) {
const separator = gridFormattingOptions?.thousandsSeparator;
if (_isNumber(value)) {
if (separator === 'none' || (value < 1000 && value > -1000)) return value.toString();
if (separator === 'system') return value.toLocaleString();
}
// fallback for system locale
if (separator === 'space' || separator === 'system') return formatNumberCustomSeparator(value.toString(), ' ');
if (separator === 'narrowspace') return formatNumberCustomSeparator(value.toString(), '\u202F');
if (separator === 'comma') return formatNumberCustomSeparator(value.toString(), ',');
if (separator === 'dot') return formatNumberCustomSeparator(value.toString(), '.');
return value.toString();
}
export function stringifyCellValue( export function stringifyCellValue(
value, value,
intent: intent:
@@ -210,7 +231,7 @@ export function stringifyCellValue(
| 'exportIntent' | 'exportIntent'
| 'clipboardIntent', | 'clipboardIntent',
editorTypes?: DataEditorTypesBehaviour, editorTypes?: DataEditorTypesBehaviour,
gridFormattingOptions?: { useThousandsSeparator?: boolean }, gridFormattingOptions?: { thousandsSeparator?: string },
jsonParsedValue?: any jsonParsedValue?: any
): { ): {
value: string; value: string;
@@ -256,7 +277,7 @@ export function stringifyCellValue(
// return { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' }; // return { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' };
// } // }
} }
if (editorTypes?.parseObjectIdAsDollar) { if (editorTypes?.parseObjectIdAsDollar) {
if (value?.$oid) { if (value?.$oid) {
switch (intent) { switch (intent) {
@@ -270,13 +291,13 @@ export function stringifyCellValue(
} }
if (value?.$bigint) { if (value?.$bigint) {
return { return {
value: value.$bigint, value: formatCellNumber(value.$bigint, gridFormattingOptions),
gridStyle: 'valueCellStyle', gridStyle: 'valueCellStyle',
}; };
} }
if (typeof value === 'bigint') { if (typeof value === 'bigint') {
return { return {
value: value.toString(), value: formatCellNumber(value.toString(), gridFormattingOptions),
gridStyle: 'valueCellStyle', gridStyle: 'valueCellStyle',
}; };
} }
@@ -351,13 +372,8 @@ export function stringifyCellValue(
if (_isNumber(value)) { if (_isNumber(value)) {
switch (intent) { switch (intent) {
case 'gridCellIntent': case 'gridCellIntent':
return { const separator = gridFormattingOptions?.thousandsSeparator;
value: return { value: formatCellNumber(value, gridFormattingOptions), gridStyle: 'valueCellStyle' };
gridFormattingOptions?.useThousandsSeparator && (value >= 10000 || value <= -10000)
? value.toLocaleString()
: value.toString(),
gridStyle: 'valueCellStyle',
};
default: default:
return { value: value.toString() }; return { value: value.toString() };
} }

View File

@@ -40,8 +40,6 @@ import { getSettings } from '../utility/metadataLoaders';
import { isMac, switchCurrentDatabase } from '../utility/common'; import { isMac, switchCurrentDatabase } from '../utility/common';
import { doLogout } from '../clientAuth'; import { doLogout } from '../clientAuth';
import { disconnectServerConnection } from '../appobj/ConnectionAppObject.svelte'; import { disconnectServerConnection } from '../appobj/ConnectionAppObject.svelte';
import UploadErrorModal from '../modals/UploadErrorModal.svelte';
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
import NewCollectionModal from '../modals/NewCollectionModal.svelte'; import NewCollectionModal from '../modals/NewCollectionModal.svelte';
import ConfirmModal from '../modals/ConfirmModal.svelte'; import ConfirmModal from '../modals/ConfirmModal.svelte';
import localforage from 'localforage'; import localforage from 'localforage';
@@ -73,7 +71,8 @@ registerCommand({
category: __t('command.theme', { defaultMessage: 'Theme' }), category: __t('command.theme', { defaultMessage: 'Theme' }),
name: __t('command.theme.change', { defaultMessage: 'Change' }), name: __t('command.theme.change', { defaultMessage: 'Change' }),
toolbarName: __t('command.theme.changeToolbar', { defaultMessage: 'Change theme' }), toolbarName: __t('command.theme.changeToolbar', { defaultMessage: 'Change theme' }),
onClick: () => openNewTab({ onClick: () =>
openNewTab({
title: 'Settings', title: 'Settings',
icon: 'icon settings', icon: 'icon settings',
tabComponent: 'SettingsTab', tabComponent: 'SettingsTab',
@@ -1230,8 +1229,7 @@ registerCommand({
}, },
}); });
if ( hasPermission('application-log')) if (hasPermission('application-log')) {
{
registerCommand({ registerCommand({
id: 'app.showLogs', id: 'app.showLogs',
category: __t('command.application', { defaultMessage: 'Application' }), category: __t('command.application', { defaultMessage: 'Application' }),
@@ -1246,8 +1244,7 @@ if ( hasPermission('application-log'))
}); });
} }
if (hasPermission('widgets/plugins')) if (hasPermission('widgets/plugins')) {
{
registerCommand({ registerCommand({
id: 'app.managePlugins', id: 'app.managePlugins',
category: __t('command.application', { defaultMessage: 'Application' }), category: __t('command.application', { defaultMessage: 'Application' }),

View File

@@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import _ from 'lodash'; import _ from 'lodash';
import { getBoolSettingsValue } from '../settings/settingsTools'; import { getStringSettingsValue } from '../settings/settingsTools';
import { stringifyCellValue } from 'dbgate-tools'; import { stringifyCellValue } from 'dbgate-tools';
export let rowData; export let rowData;
@@ -13,7 +13,7 @@
value, value,
'gridCellIntent', 'gridCellIntent',
editorTypes, editorTypes,
{ useThousandsSeparator: getBoolSettingsValue('dataGrid.thousandsSeparator', false) }, { thousandsSeparator: getStringSettingsValue('dataGrid.thousandsSeparatorChar', 'none') },
jsonParsedValue jsonParsedValue
); );

View File

@@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import _, { isPlainObject } from 'lodash'; import _, { isPlainObject } from 'lodash';
import ShowFormButton from '../formview/ShowFormButton.svelte'; import ShowFormButton from '../formview/ShowFormButton.svelte';
import { detectTypeIcon, getConvertValueMenu, isJsonLikeLongString, safeJsonParse } from 'dbgate-tools'; import { detectTypeIcon, getConvertValueMenu, isJsonLikeLongString, safeJsonParse, isTypeNumber } from 'dbgate-tools';
import { openJsonDocument } from '../tabs/JsonTab.svelte'; import { openJsonDocument } from '../tabs/JsonTab.svelte';
import CellValue from './CellValue.svelte'; import CellValue from './CellValue.svelte';
import { openJsonLinesData } from '../utility/openJsonLinesData'; import { openJsonLinesData } from '../utility/openJsonLinesData';
@@ -80,7 +80,7 @@
class:isFocusedColumn class:isFocusedColumn
class:hasOverlayValue class:hasOverlayValue
class:isMissingOverlayField class:isMissingOverlayField
class:alignRight={_.isNumber(value) && !showHint} class:alignRight={ (_.isNumber(value) || isTypeNumber(col.dataType)) && !showHint}
{style} {style}
> >
{#if hasOverlayValue} {#if hasOverlayValue}

View File

@@ -1,9 +1,12 @@
<script lang="ts"> <script lang="ts">
import FontIcon from "../icons/FontIcon.svelte";
export let type; export let type;
export let label; export let label;
export let noMargin = false; export let noMargin = false;
export let disabled = false; export let disabled = false;
export let labelProps: any = {}; export let labelProps: any = {};
export let labelIcon = null;
</script> </script>
<div class="largeFormMarker" class:noMargin> <div class="largeFormMarker" class:noMargin>
@@ -12,6 +15,9 @@
<span {...labelProps} on:click={labelProps.onClick} class:disabled class='checkLabel'>{label}</span> <span {...labelProps} on:click={labelProps.onClick} class:disabled class='checkLabel'>{label}</span>
{:else} {:else}
<div class="label" {...labelProps} on:click={labelProps.onClick}> <div class="label" {...labelProps} on:click={labelProps.onClick}>
{#if labelIcon}
<FontIcon icon={labelIcon} padRight />
{/if}
<span {...labelProps} on:click={labelProps.onClick} class:disabled>{label}</span> <span {...labelProps} on:click={labelProps.onClick} class:disabled>{label}</span>
</div> </div>
<slot /> <slot />

View File

@@ -164,7 +164,12 @@
changeActiveSubmenu(); changeActiveSubmenu();
}} }}
> >
<a on:click={e => handleClick(e, item)} class:disabled={item.disabled} class:bold={item.isBold}> <a
on:click={e => handleClick(e, item)}
class:disabled={item.disabled}
class:bold={item.isBold}
data-testid={item.testid}
>
<span> <span>
{#if item.switchValue && item.switchStoreGetter} {#if item.switchValue && item.switchStoreGetter}
{#key switchIndex} {#key switchIndex}

View File

@@ -1,81 +1,64 @@
<script lang="ts"> <script lang="ts">
import CheckboxField from "../forms/CheckboxField.svelte"; import CheckboxField from '../forms/CheckboxField.svelte';
import FormCheckboxField from "../forms/FormCheckboxField.svelte"; import FormCheckboxField from '../forms/FormCheckboxField.svelte';
import FormFieldTemplateLarge from "../forms/FormFieldTemplateLarge.svelte"; import FormFieldTemplateLarge from '../forms/FormFieldTemplateLarge.svelte';
import FormSelectField from "../forms/FormSelectField.svelte"; import FormSelectField from '../forms/FormSelectField.svelte';
import FormTextField from "../forms/FormTextField.svelte"; import FormTextField from '../forms/FormTextField.svelte';
import FormValues from "../forms/FormValues.svelte"; import FormValues from '../forms/FormValues.svelte';
import { lockedDatabaseMode } from "../stores"; import { lockedDatabaseMode } from '../stores';
import { _t } from "../translations"; import { _t } from '../translations';
</script> </script>
<div class="wrapper"> <div class="wrapper">
<FormValues let:values> <FormValues let:values>
<div class="heading">{_t('settings.connection', { defaultMessage: 'Connection' })}</div> <div class="heading">{_t('settings.connection', { defaultMessage: 'Connection' })}</div>
<FormFieldTemplateLarge
label={_t('settings.connection.showOnlyTabsFromSelectedDatabase', {
defaultMessage: 'Show only tabs from selected database',
})}
type="checkbox"
labelProps={{
onClick: () => {
$lockedDatabaseMode = !$lockedDatabaseMode;
},
}}
>
<CheckboxField checked={$lockedDatabaseMode} on:change={e => ($lockedDatabaseMode = e.target.checked)} data-testid="ConnectionSettings_lockedDatabaseMode"/>
</FormFieldTemplateLarge>
<FormCheckboxField <FormCheckboxField
name="connection.autoRefresh" name="connection.autoRefresh"
label={_t('settings.connection.autoRefresh', { label={_t('settings.connection.autoRefresh', {
defaultMessage: 'Automatic refresh of database model on background', defaultMessage: 'Automatic refresh of database model on background',
})} })}
defaultValue={false} defaultValue={false}
/> />
<FormTextField <FormTextField
name="connection.autoRefreshInterval" name="connection.autoRefreshInterval"
label={_t('settings.connection.autoRefreshInterval', { label={_t('settings.connection.autoRefreshInterval', {
defaultMessage: 'Interval between automatic DB structure reloads in seconds', defaultMessage: 'Interval between automatic DB structure reloads in seconds',
})} })}
defaultValue="30" defaultValue="30"
disabled={values['connection.autoRefresh'] === false} disabled={values['connection.autoRefresh'] === false}
/> />
<FormSelectField <FormSelectField
label={_t('settings.connection.sshBindHost', { defaultMessage: 'Local host address for SSH connections' })} label={_t('settings.connection.sshBindHost', { defaultMessage: 'Local host address for SSH connections' })}
name="connection.sshBindHost" name="connection.sshBindHost"
isNative isNative
defaultValue="127.0.0.1" defaultValue="127.0.0.1"
options={[ options={[
{ value: '127.0.0.1', label: '127.0.0.1 (IPv4)' }, { value: '127.0.0.1', label: '127.0.0.1 (IPv4)' },
{ value: '::1', label: '::1 (IPv6)' }, { value: '::1', label: '::1 (IPv6)' },
{ value: 'localhost', label: 'localhost (domain name)' }, { value: 'localhost', label: 'localhost (domain name)' },
]} ]}
/> />
<div class="heading">{_t('settings.session', { defaultMessage: 'Query sessions' })}</div> <div class="heading">{_t('settings.session', { defaultMessage: 'Query sessions' })}</div>
<FormCheckboxField <FormCheckboxField
name="session.autoClose" name="session.autoClose"
label={_t('settings.session.autoClose', { label={_t('settings.session.autoClose', {
defaultMessage: 'Automatic close query sessions after period without any activity', defaultMessage: 'Automatic close query sessions after period without any activity',
})} })}
defaultValue={true} defaultValue={true}
/> />
<FormTextField <FormTextField
name="session.autoCloseTimeout" name="session.autoCloseTimeout"
label={_t('settings.session.autoCloseTimeout', { label={_t('settings.session.autoCloseTimeout', {
defaultMessage: 'Interval, after which query session without activity is closed (in minutes)', defaultMessage: 'Interval, after which query session without activity is closed (in minutes)',
})} })}
defaultValue="15" defaultValue="15"
disabled={values['session.autoClose'] === false} disabled={values['session.autoClose'] === false}
/> />
</FormValues> </FormValues>
</div> </div>
<style> <style>
.heading { .heading {
font-size: 20px; font-size: 20px;
@@ -84,12 +67,11 @@
margin-top: var(--dim-large-form-margin); margin-top: var(--dim-large-form-margin);
} }
.wrapper :global(input){ .wrapper :global(input) {
max-width: 400px; max-width: 400px;
} }
.wrapper :global(select){ .wrapper :global(select) {
max-width: 400px; max-width: 400px;
} }
</style>
</style>

View File

@@ -1,94 +1,105 @@
<script lang="ts"> <script lang="ts">
import FormCheckboxField from "../forms/FormCheckboxField.svelte"; import FormCheckboxField from '../forms/FormCheckboxField.svelte';
import FormSelectField from "../forms/FormSelectField.svelte"; import FormSelectField from '../forms/FormSelectField.svelte';
import FormTextField from "../forms/FormTextField.svelte"; import FormTextField from '../forms/FormTextField.svelte';
import { _t } from "../translations"; import { _t } from '../translations';
import { isProApp } from "../utility/proTools"; import { isProApp } from '../utility/proTools';
</script> </script>
<div class="wrapper"> <div class="wrapper">
<div class="heading">{_t('settings.dataGrid.title', { defaultMessage: 'Data grid' })}</div> <div class="heading">{_t('settings.dataGrid.title', { defaultMessage: 'Data grid' })}</div>
<FormTextField <FormTextField
name="dataGrid.pageSize" name="dataGrid.pageSize"
label={_t('settings.dataGrid.pageSize', { label={_t('settings.dataGrid.pageSize', {
defaultMessage: 'Page size (number of rows for incremental loading, must be between 5 and 50000)', defaultMessage: 'Page size (number of rows for incremental loading, must be between 5 and 50000)',
})} })}
defaultValue="100" defaultValue="100"
/> />
{#if isProApp()} {#if isProApp()}
<FormCheckboxField <FormCheckboxField
name="dataGrid.showHintColumns" name="dataGrid.showHintColumns"
label={_t('settings.dataGrid.showHintColumns', { defaultMessage: 'Show foreign key hints' })} label={_t('settings.dataGrid.showHintColumns', { defaultMessage: 'Show foreign key hints' })}
defaultValue={true} defaultValue={true}
data-testid="DataGridSettings_showHintColumns" data-testid="DataGridSettings_showHintColumns"
/> />
{/if} {/if}
<!-- <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} /> --> <!-- <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} /> -->
<FormCheckboxField <FormSelectField
name="dataGrid.thousandsSeparator" label={_t('settings.dataGrid.thousandsSeparator', { defaultMessage: 'Thousands separator for numbers' })}
label={_t('settings.dataGrid.thousandsSeparator', { name="dataGrid.thousandsSeparatorChar"
defaultMessage: 'Use thousands separator for numbers', isNative
})} defaultValue="none"
/> options={[
{ value: 'none', label: _t('settings.dataGrid.thousandsSeparator.none', { defaultMessage: 'None' }) },
{ value: 'system', label: _t('settings.dataGrid.thousandsSeparator.system', { defaultMessage: 'System' }) },
{ value: 'space', label: _t('settings.dataGrid.thousandsSeparator.space', { defaultMessage: 'Space' }) },
{
value: 'narrowspace',
label: _t('settings.dataGrid.thousandsSeparator.narrowSpace', {
defaultMessage: 'Narrow space',
}),
},
{ value: 'comma', label: _t('settings.dataGrid.thousandsSeparator.comma', { defaultMessage: 'Comma (,)' }) },
{ value: 'dot', label: _t('settings.dataGrid.thousandsSeparator.dot', { defaultMessage: 'Dot (.)' }) },
]}
/>
<FormTextField <FormTextField
name="dataGrid.defaultAutoRefreshInterval" name="dataGrid.defaultAutoRefreshInterval"
label={_t('settings.dataGrid.defaultAutoRefreshInterval', { label={_t('settings.dataGrid.defaultAutoRefreshInterval', {
defaultMessage: 'Default grid auto refresh interval in seconds', defaultMessage: 'Default grid auto refresh interval in seconds',
})} })}
defaultValue="10" defaultValue="10"
/> />
<FormCheckboxField <FormCheckboxField
name="dataGrid.alignNumbersRight" name="dataGrid.alignNumbersRight"
label={_t('settings.dataGrid.alignNumbersRight', { defaultMessage: 'Align numbers to right' })} label={_t('settings.dataGrid.alignNumbersRight', { defaultMessage: 'Align numbers to right' })}
defaultValue={false} defaultValue={false}
/> />
<FormTextField <FormTextField
name="dataGrid.collectionPageSize" name="dataGrid.collectionPageSize"
label={_t('settings.dataGrid.collectionPageSize', { label={_t('settings.dataGrid.collectionPageSize', {
defaultMessage: 'Collection page size (for MongoDB JSON view, must be between 5 and 1000)', defaultMessage: 'Collection page size (for MongoDB JSON view, must be between 5 and 1000)',
})} })}
defaultValue="50" defaultValue="50"
/> />
<FormSelectField <FormSelectField
label={_t('settings.dataGrid.coloringMode', { defaultMessage: 'Row coloring mode' })} label={_t('settings.dataGrid.coloringMode', { defaultMessage: 'Row coloring mode' })}
name="dataGrid.coloringMode" name="dataGrid.coloringMode"
isNative isNative
defaultValue="36" defaultValue="36"
options={[ options={[
{ {
value: '36', value: '36',
label: _t('settings.dataGrid.coloringMode.36', { defaultMessage: 'Every 3rd and 6th row' }), label: _t('settings.dataGrid.coloringMode.36', { defaultMessage: 'Every 3rd and 6th row' }),
}, },
{ {
value: '2-primary', value: '2-primary',
label: _t('settings.dataGrid.coloringMode.2-primary', { label: _t('settings.dataGrid.coloringMode.2-primary', {
defaultMessage: 'Every 2-nd row, primary color', defaultMessage: 'Every 2-nd row, primary color',
}), }),
}, },
{ {
value: '2-secondary', value: '2-secondary',
label: _t('settings.dataGrid.coloringMode.2-secondary', { label: _t('settings.dataGrid.coloringMode.2-secondary', {
defaultMessage: 'Every 2-nd row, secondary color', defaultMessage: 'Every 2-nd row, secondary color',
}), }),
}, },
{ value: 'none', label: _t('settings.dataGrid.coloringMode.none', { defaultMessage: 'None' }) }, { value: 'none', label: _t('settings.dataGrid.coloringMode.none', { defaultMessage: 'None' }) },
]} ]}
/> />
<FormCheckboxField <FormCheckboxField
name="dataGrid.showAllColumnsWhenSearch" name="dataGrid.showAllColumnsWhenSearch"
label={_t('settings.dataGrid.showAllColumnsWhenSearch', { label={_t('settings.dataGrid.showAllColumnsWhenSearch', {
defaultMessage: 'Show all columns when searching', defaultMessage: 'Show all columns when searching',
})} })}
defaultValue={false} defaultValue={false}
/> />
</div> </div>
<style> <style>
@@ -99,11 +110,11 @@ defaultValue={false}
margin-top: var(--dim-large-form-margin); margin-top: var(--dim-large-form-margin);
} }
.wrapper :global(select){ .wrapper :global(select) {
max-width: 400px; max-width: 400px;
} }
.wrapper :global(input){ .wrapper :global(input) {
max-width: 400px; max-width: 400px;
} }
</style> </style>

View File

@@ -10,6 +10,9 @@
import { isMac } from '../utility/common'; import { isMac } from '../utility/common';
import getElectron from '../utility/getElectron'; import getElectron from '../utility/getElectron';
import ConfirmModal from '../modals/ConfirmModal.svelte'; import ConfirmModal from '../modals/ConfirmModal.svelte';
import hasPermission from '../utility/hasPermission';
import CheckboxField from '../forms/CheckboxField.svelte';
import { lockedDatabaseMode } from '../stores';
const electron = getElectron(); const electron = getElectron();
let restartWarning = false; let restartWarning = false;
@@ -17,7 +20,11 @@
<div class="wrapper"> <div class="wrapper">
<div class="heading">{_t('settings.application', { defaultMessage: 'Application' })}</div> <div class="heading">{_t('settings.application', { defaultMessage: 'Application' })}</div>
<FormFieldTemplateLarge label={_t('settings.localization.language', { defaultMessage: 'Language' })} type="combo"> <FormFieldTemplateLarge
label={_t('settings.localization.language', { defaultMessage: 'Language' })}
type="combo"
labelIcon="mdi mdi-translate"
>
<SelectField <SelectField
isNative isNative
data-testid="SettingsModal_languageSelect" data-testid="SettingsModal_languageSelect"
@@ -78,6 +85,24 @@
/> />
{/if} {/if}
<FormFieldTemplateLarge
label={_t('settings.connection.showOnlyTabsFromSelectedDatabase', {
defaultMessage: 'Show only tabs from selected database',
})}
type="checkbox"
labelProps={{
onClick: () => {
$lockedDatabaseMode = !$lockedDatabaseMode;
},
}}
>
<CheckboxField
checked={$lockedDatabaseMode}
on:change={e => ($lockedDatabaseMode = e.target['checked'])}
data-testid="GeneralSettings_lockedDatabaseMode"
/>
</FormFieldTemplateLarge>
<div class="heading">{_t('settings.appearance', { defaultMessage: 'Appearance' })}</div> <div class="heading">{_t('settings.appearance', { defaultMessage: 'Appearance' })}</div>
{#if electron} {#if electron}
@@ -106,6 +131,7 @@
defaultMessage: 'Show server name alongside database name in title of the tab group', defaultMessage: 'Show server name alongside database name in title of the tab group',
})} })}
defaultValue={false} defaultValue={false}
disabled={!hasPermission('settings/change')}
/> />
</div> </div>

View File

@@ -29,6 +29,13 @@ export function getStringSettingsValue(name, defaultValue) {
return res; return res;
} }
export function getObjectSettingsValue(name, defaultValue) {
const settings = getCurrentSettings();
const res = settings[name];
if (res == null) return defaultValue;
return res;
}
export function getConnectionClickActionSetting(): 'connect' | 'openDetails' | 'none' { export function getConnectionClickActionSetting(): 'connect' | 'openDetails' | 'none' {
return getStringSettingsValue('defaultAction.connectionClick', 'connect'); return getStringSettingsValue('defaultAction.connectionClick', 'connect');
} }

View File

@@ -3,111 +3,114 @@
</script> </script>
<script lang="ts"> <script lang="ts">
import SettingsMenuControl from "../elements/SettingsMenuControl.svelte"; import SettingsMenuControl from '../elements/SettingsMenuControl.svelte';
import GeneralSettings from "../settings/GeneralSettings.svelte"; import GeneralSettings from '../settings/GeneralSettings.svelte';
import SettingsFormProvider from "../forms/SettingsFormProvider.svelte"; import SettingsFormProvider from '../forms/SettingsFormProvider.svelte';
import ConnectionSettings from "../settings/ConnectionSettings.svelte"; import ConnectionSettings from '../settings/ConnectionSettings.svelte';
import ThemeSettings from "../settings/ThemeSettings.svelte"; import ThemeSettings from '../settings/ThemeSettings.svelte';
import DefaultActionsSettings from "../settings/DefaultActionsSettings.svelte"; import DefaultActionsSettings from '../settings/DefaultActionsSettings.svelte';
import BehaviourSettings from "../settings/BehaviourSettings.svelte"; import BehaviourSettings from '../settings/BehaviourSettings.svelte';
import ExternalToolsSettings from "../settings/ExternalToolsSettings.svelte"; import ExternalToolsSettings from '../settings/ExternalToolsSettings.svelte';
import LicenseSettings from "../settings/LicenseSettings.svelte"; import LicenseSettings from '../settings/LicenseSettings.svelte';
import { isProApp } from "../utility/proTools"; import { isProApp } from '../utility/proTools';
import { _t } from "../translations"; import { _t } from '../translations';
import CommandListTab from "./CommandListTab.svelte"; import CommandListTab from './CommandListTab.svelte';
import DataGridSettings from "../settings/DataGridSettings.svelte"; import DataGridSettings from '../settings/DataGridSettings.svelte';
import SQLEditorSettings from "../settings/SQLEditorSettings.svelte"; import SQLEditorSettings from '../settings/SQLEditorSettings.svelte';
import AiSettingsTab from "../settings/AiSettingsTab.svelte"; import AiSettingsTab from '../settings/AiSettingsTab.svelte';
import hasPermission from '../utility/hasPermission';
export let selectedItem = 'general'; export let selectedItem = 'general';
const menuItems = [ const menuItems = [
{ {
label: _t('settings.general', { defaultMessage: 'General' }), label: _t('settings.general', { defaultMessage: 'General' }),
identifier: 'general', identifier: 'general',
component: GeneralSettings, component: GeneralSettings,
props: {}, props: {},
testid: 'settings-general', testid: 'settings-general',
}, },
{ hasPermission('settings/change') && {
label: _t('settings.connection', { defaultMessage: 'Connection' }), label: _t('settings.connection', { defaultMessage: 'Connection' }),
identifier: 'connection', identifier: 'connection',
component: ConnectionSettings, component: ConnectionSettings,
props: {}, props: {},
testid: 'settings-connection', testid: 'settings-connection',
}, },
{ hasPermission('settings/change') && {
label: _t('settings.dataGrid.title', { defaultMessage: 'Data grid' }), label: _t('settings.dataGrid.title', { defaultMessage: 'Data grid' }),
identifier: 'data-grid', identifier: 'data-grid',
component: DataGridSettings, component: DataGridSettings,
props: {}, props: {},
testid: 'settings-data-grid', testid: 'settings-data-grid',
}, },
{ hasPermission('settings/change') && {
label: _t('settings.sqlEditor.title', { defaultMessage: 'SQL Editor' }), label: _t('settings.sqlEditor.title', { defaultMessage: 'SQL Editor' }),
identifier: 'sql-editor', identifier: 'sql-editor',
component: SQLEditorSettings, component: SQLEditorSettings,
props: {}, props: {},
testid: 'settings-sql-editor', testid: 'settings-sql-editor',
}, },
{ {
label: _t('settings.theme', { defaultMessage: 'Themes' }), label: _t('settings.theme', { defaultMessage: 'Themes' }),
identifier: 'theme', identifier: 'theme',
component: ThemeSettings, component: ThemeSettings,
props: {}, props: {},
testid: 'settings-themes', testid: 'settings-themes',
}, },
{ hasPermission('settings/change') && {
label: _t('settings.defaultActions', { defaultMessage: 'Default Actions' }), label: _t('settings.defaultActions', { defaultMessage: 'Default Actions' }),
identifier: 'default-actions', identifier: 'default-actions',
component: DefaultActionsSettings, component: DefaultActionsSettings,
props: {}, props: {},
testid: 'settings-default-actions', testid: 'settings-default-actions',
}, },
{ hasPermission('settings/change') && {
label: _t('settings.behaviour', { defaultMessage: 'Behaviour' }), label: _t('settings.behaviour', { defaultMessage: 'Behaviour' }),
identifier: 'behaviour', identifier: 'behaviour',
component: BehaviourSettings, component: BehaviourSettings,
props: {}, props: {},
testid: 'settings-behaviour', testid: 'settings-behaviour',
}, },
{ hasPermission('settings/change') && {
label: _t('settings.externalTools', { defaultMessage: 'External Tools' }), label: _t('settings.externalTools', { defaultMessage: 'External Tools' }),
identifier: 'external-tools', identifier: 'external-tools',
component: ExternalToolsSettings, component: ExternalToolsSettings,
props: {}, props: {},
testid: 'settings-external-tools', testid: 'settings-external-tools',
}, },
{ hasPermission('settings/change') && {
label: _t('command.settings.shortcuts', { defaultMessage: 'Keyboard shortcuts' }), label: _t('command.settings.shortcuts', { defaultMessage: 'Keyboard shortcuts' }),
identifier: 'shortcuts', identifier: 'shortcuts',
component: CommandListTab, component: CommandListTab,
props: {}, props: {},
testid: 'settings-shortcuts', testid: 'settings-shortcuts',
}, },
isProApp() && { hasPermission('settings/change') &&
label: _t('settings.license', { defaultMessage: 'License' }), isProApp() && {
identifier: 'license', label: _t('settings.license', { defaultMessage: 'License' }),
component: LicenseSettings, identifier: 'license',
props: {}, component: LicenseSettings,
testid: 'settings-license', props: {},
}, testid: 'settings-license',
isProApp() && { },
label: _t('settings.AI', { defaultMessage: 'AI'}), hasPermission('settings/change') &&
identifier: 'ai', isProApp() && {
component: AiSettingsTab, label: _t('settings.AI', { defaultMessage: 'AI' }),
props: {}, identifier: 'ai',
testid: 'settings-ai', component: AiSettingsTab,
}, props: {},
]; testid: 'settings-ai',
},
];
</script> </script>
<SettingsFormProvider> <SettingsFormProvider>
<SettingsMenuControl <SettingsMenuControl
items={menuItems} items={menuItems}
bind:value={selectedItem} bind:value={selectedItem}
flex1={true} flex1={true}
flexColContainer={true} flexColContainer={true}
scrollableContentContainer={true} scrollableContentContainer={true}
/> />
</SettingsFormProvider> </SettingsFormProvider>

View File

@@ -166,6 +166,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
apiCall('database-connections/sync-model', dbid); apiCall('database-connections/sync-model', dbid);
callSchemalListChanged(); callSchemalListChanged();
}, },
testid: 'DatabasStatusMenu_refreshIncremental',
}, },
{ {
text: driver?.supportsIncrementalAnalysis text: driver?.supportsIncrementalAnalysis
@@ -175,6 +176,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true }); apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true });
callSchemalListChanged(); callSchemalListChanged();
}, },
testid: 'DatabasStatusMenu_refreshFull',
}, },
{ {
text: _t('command.database.reopenConnection', { defaultMessage: 'Reopen connection' }), text: _t('command.database.reopenConnection', { defaultMessage: 'Reopen connection' }),
@@ -182,6 +184,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
apiCall('database-connections/refresh', dbid); apiCall('database-connections/refresh', dbid);
callSchemalListChanged(); callSchemalListChanged();
}, },
testid: 'DatabasStatusMenu_reopenConnection',
}, },
{ {
text: _t('command.database.disconnect', { defaultMessage: 'Disconnect' }), text: _t('command.database.disconnect', { defaultMessage: 'Disconnect' }),
@@ -190,6 +193,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
if (electron) apiCall('database-connections/disconnect', dbid); if (electron) apiCall('database-connections/disconnect', dbid);
switchCurrentDatabase(null); switchCurrentDatabase(null);
}, },
testid: 'DatabasStatusMenu_disconnect',
}, },
]); ]);
} }

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "Vyhledávání v databázi", "command.database.databaseSearch": "Vyhledávání v databázi",
"command.database.disconnect": "Odpojit", "command.database.disconnect": "Odpojit",
"command.database.export": "Exportovat databázi", "command.database.export": "Exportovat databázi",
"command.database.refresh": "Obnovit strukturu DB",
"command.database.refreshFull": "Obnovit strukturu DB (úplně)", "command.database.refreshFull": "Obnovit strukturu DB (úplně)",
"command.database.refreshIncremental": "Obnovit strukturu DB (inkrementálně)", "command.database.refreshIncremental": "Obnovit strukturu DB (inkrementálně)",
"command.database.reopenConnection": "Znovu otevřít připojení", "command.database.reopenConnection": "Znovu otevřít připojení",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "Velikost písmen SQL příkazů", "settings.sqlEditor.sqlCommandsCase": "Velikost písmen SQL příkazů",
"settings.sqlEditor.title": "SQL editor", "settings.sqlEditor.title": "SQL editor",
"settings.tabGroup.showServerName": "Zobrazit název serveru vedle názvu databáze v záhlaví skupiny karet", "settings.tabGroup.showServerName": "Zobrazit název serveru vedle názvu databáze v záhlaví skupiny karet",
"settings.tabPreviewMode": "Režim náhledu karet",
"settings.theme": "Vzhled", "settings.theme": "Vzhled",
"settings.title": "Nastavení", "settings.title": "Nastavení",
"settings.useNativeWindowTitle": "Použít nativní titulek okna", "settings.useNativeWindowTitle": "Použít nativní titulek okna",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "Datenbanksuche", "command.database.databaseSearch": "Datenbanksuche",
"command.database.disconnect": "Trennen", "command.database.disconnect": "Trennen",
"command.database.export": "Datenbank exportieren", "command.database.export": "Datenbank exportieren",
"command.database.refresh": "DB-Struktur aktualisieren",
"command.database.refreshFull": "DB-Struktur aktualisieren (vollständig)", "command.database.refreshFull": "DB-Struktur aktualisieren (vollständig)",
"command.database.refreshIncremental": "DB-Struktur aktualisieren (inkrementell)", "command.database.refreshIncremental": "DB-Struktur aktualisieren (inkrementell)",
"command.database.reopenConnection": "Verbindung erneut öffnen", "command.database.reopenConnection": "Verbindung erneut öffnen",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "Groß-/Kleinschreibung der SQL-Befehle", "settings.sqlEditor.sqlCommandsCase": "Groß-/Kleinschreibung der SQL-Befehle",
"settings.sqlEditor.title": "SQL-Editor", "settings.sqlEditor.title": "SQL-Editor",
"settings.tabGroup.showServerName": "Servername neben Datenbankname im Titel der Tab-Gruppe anzeigen", "settings.tabGroup.showServerName": "Servername neben Datenbankname im Titel der Tab-Gruppe anzeigen",
"settings.tabPreviewMode": "Tab-Vorschaumodus",
"settings.theme": "Designs", "settings.theme": "Designs",
"settings.title": "Einstellungen", "settings.title": "Einstellungen",
"settings.useNativeWindowTitle": "Nativen Fenstertitel verwenden", "settings.useNativeWindowTitle": "Nativen Fenstertitel verwenden",

View File

@@ -167,6 +167,7 @@
"command.database.databaseSearch": "Database search", "command.database.databaseSearch": "Database search",
"command.database.disconnect": "Disconnect", "command.database.disconnect": "Disconnect",
"command.database.export": "Export database", "command.database.export": "Export database",
"command.database.refresh": "Refresh DB structure",
"command.database.refreshFull": "Refresh DB structure (full)", "command.database.refreshFull": "Refresh DB structure (full)",
"command.database.refreshIncremental": "Refresh DB structure (incremental)", "command.database.refreshIncremental": "Refresh DB structure (incremental)",
"command.database.reopenConnection": "Reopen connection", "command.database.reopenConnection": "Reopen connection",
@@ -1190,6 +1191,7 @@
"settings.sqlEditor.sqlCommandsCase": "SQL commands case", "settings.sqlEditor.sqlCommandsCase": "SQL commands case",
"settings.sqlEditor.title": "SQL Editor", "settings.sqlEditor.title": "SQL Editor",
"settings.tabGroup.showServerName": "Show server name alongside database name in title of the tab group", "settings.tabGroup.showServerName": "Show server name alongside database name in title of the tab group",
"settings.tabPreviewMode": "Tab Preview Mode",
"settings.theme": "Themes", "settings.theme": "Themes",
"settings.useNativeWindowTitle": "Use native window title", "settings.useNativeWindowTitle": "Use native window title",
"settings.useSystemNativeMenu": "Use system native menu", "settings.useSystemNativeMenu": "Use system native menu",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "Búsqueda en base de datos", "command.database.databaseSearch": "Búsqueda en base de datos",
"command.database.disconnect": "Desconectar", "command.database.disconnect": "Desconectar",
"command.database.export": "Exportar base de datos", "command.database.export": "Exportar base de datos",
"command.database.refresh": "Refrescar estructura de BD",
"command.database.refreshFull": "Refrescar estructura de BD (completa)", "command.database.refreshFull": "Refrescar estructura de BD (completa)",
"command.database.refreshIncremental": "Refrescar estructura de BD (incremental)", "command.database.refreshIncremental": "Refrescar estructura de BD (incremental)",
"command.database.reopenConnection": "Reabrir conexión", "command.database.reopenConnection": "Reabrir conexión",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "Mayúsculas/minúsculas de comandos SQL", "settings.sqlEditor.sqlCommandsCase": "Mayúsculas/minúsculas de comandos SQL",
"settings.sqlEditor.title": "Editor SQL", "settings.sqlEditor.title": "Editor SQL",
"settings.tabGroup.showServerName": "Mostrar nombre del servidor junto con nombre de base de datos en el título del grupo de pestañas", "settings.tabGroup.showServerName": "Mostrar nombre del servidor junto con nombre de base de datos en el título del grupo de pestañas",
"settings.tabPreviewMode": "Modo de vista previa de pestaña",
"settings.theme": "Temas", "settings.theme": "Temas",
"settings.title": "Configuración", "settings.title": "Configuración",
"settings.useNativeWindowTitle": "Usar título de ventana nativo", "settings.useNativeWindowTitle": "Usar título de ventana nativo",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "Recherche dans la base de données", "command.database.databaseSearch": "Recherche dans la base de données",
"command.database.disconnect": "Déconnecter", "command.database.disconnect": "Déconnecter",
"command.database.export": "Exporter la base de données", "command.database.export": "Exporter la base de données",
"command.database.refresh": "Rafraîchir la structure de BD",
"command.database.refreshFull": "Rafraîchir la structure de BD (complète)", "command.database.refreshFull": "Rafraîchir la structure de BD (complète)",
"command.database.refreshIncremental": "Rafraîchir la structure de BD (incrémentale)", "command.database.refreshIncremental": "Rafraîchir la structure de BD (incrémentale)",
"command.database.reopenConnection": "Rouvrir la connexion", "command.database.reopenConnection": "Rouvrir la connexion",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "Casse des commandes SQL", "settings.sqlEditor.sqlCommandsCase": "Casse des commandes SQL",
"settings.sqlEditor.title": "Éditeur SQL", "settings.sqlEditor.title": "Éditeur SQL",
"settings.tabGroup.showServerName": "Afficher le nom du serveur à côté du nom de la base de données dans le titre du groupe d'onglets", "settings.tabGroup.showServerName": "Afficher le nom du serveur à côté du nom de la base de données dans le titre du groupe d'onglets",
"settings.tabPreviewMode": "Mode aperçu d'onglet",
"settings.theme": "Thèmes", "settings.theme": "Thèmes",
"settings.title": "Paramètres", "settings.title": "Paramètres",
"settings.useNativeWindowTitle": "Utiliser le titre de fenêtre natif", "settings.useNativeWindowTitle": "Utiliser le titre de fenêtre natif",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "Ricerca database", "command.database.databaseSearch": "Ricerca database",
"command.database.disconnect": "Disconnetti", "command.database.disconnect": "Disconnetti",
"command.database.export": "Esporta database", "command.database.export": "Esporta database",
"command.database.refresh": "Aggiorna struttura DB",
"command.database.refreshFull": "Aggiorna struttura DB (completo)", "command.database.refreshFull": "Aggiorna struttura DB (completo)",
"command.database.refreshIncremental": "Aggiorna struttura DB (incrementale)", "command.database.refreshIncremental": "Aggiorna struttura DB (incrementale)",
"command.database.reopenConnection": "Riapri connessione", "command.database.reopenConnection": "Riapri connessione",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "Maiuscole/minuscole comandi SQL", "settings.sqlEditor.sqlCommandsCase": "Maiuscole/minuscole comandi SQL",
"settings.sqlEditor.title": "Editor SQL", "settings.sqlEditor.title": "Editor SQL",
"settings.tabGroup.showServerName": "Mostra nome server accanto al nome database nel titolo del gruppo schede", "settings.tabGroup.showServerName": "Mostra nome server accanto al nome database nel titolo del gruppo schede",
"settings.tabPreviewMode": "Modalità anteprima scheda",
"settings.theme": "Temi", "settings.theme": "Temi",
"settings.title": "Impostazioni", "settings.title": "Impostazioni",
"settings.useNativeWindowTitle": "Usa titolo finestra nativo", "settings.useNativeWindowTitle": "Usa titolo finestra nativo",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "データベース検索", "command.database.databaseSearch": "データベース検索",
"command.database.disconnect": "切断", "command.database.disconnect": "切断",
"command.database.export": "データベースをエクスポート", "command.database.export": "データベースをエクスポート",
"command.database.refresh": "DB構造を更新",
"command.database.refreshFull": "DB構造を更新フル", "command.database.refreshFull": "DB構造を更新フル",
"command.database.refreshIncremental": "DB構造を更新増分", "command.database.refreshIncremental": "DB構造を更新増分",
"command.database.reopenConnection": "接続を再度開く", "command.database.reopenConnection": "接続を再度開く",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "SQLコマンドの大文字小文字", "settings.sqlEditor.sqlCommandsCase": "SQLコマンドの大文字小文字",
"settings.sqlEditor.title": "SQLエディター", "settings.sqlEditor.title": "SQLエディター",
"settings.tabGroup.showServerName": "タブグループのタイトルにデータベース名と並んでサーバー名を表示", "settings.tabGroup.showServerName": "タブグループのタイトルにデータベース名と並んでサーバー名を表示",
"settings.tabPreviewMode": "タブプレビューモード",
"settings.theme": "テーマ", "settings.theme": "テーマ",
"settings.title": "設定", "settings.title": "設定",
"settings.useNativeWindowTitle": "ネイティブウィンドウタイトルを使用", "settings.useNativeWindowTitle": "ネイティブウィンドウタイトルを使用",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "Pesquisar banco de dados", "command.database.databaseSearch": "Pesquisar banco de dados",
"command.database.disconnect": "Desconectar", "command.database.disconnect": "Desconectar",
"command.database.export": "Exportar banco de dados", "command.database.export": "Exportar banco de dados",
"command.database.refresh": "Atualizar estrutura do BD",
"command.database.refreshFull": "Atualizar estrutura do BD (completa)", "command.database.refreshFull": "Atualizar estrutura do BD (completa)",
"command.database.refreshIncremental": "Atualizar estrutura do BD (incremental)", "command.database.refreshIncremental": "Atualizar estrutura do BD (incremental)",
"command.database.reopenConnection": "Reabrir conexão", "command.database.reopenConnection": "Reabrir conexão",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "Maiúsculas/minúsculas de comandos SQL", "settings.sqlEditor.sqlCommandsCase": "Maiúsculas/minúsculas de comandos SQL",
"settings.sqlEditor.title": "Editor SQL", "settings.sqlEditor.title": "Editor SQL",
"settings.tabGroup.showServerName": "Mostrar nome do servidor junto ao nome do banco de dados no título do grupo de abas", "settings.tabGroup.showServerName": "Mostrar nome do servidor junto ao nome do banco de dados no título do grupo de abas",
"settings.tabPreviewMode": "Modo de visualização de aba",
"settings.theme": "Temas", "settings.theme": "Temas",
"settings.title": "Configurações", "settings.title": "Configurações",
"settings.useNativeWindowTitle": "Usar título de janela nativo", "settings.useNativeWindowTitle": "Usar título de janela nativo",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "Hľadanie v databáze", "command.database.databaseSearch": "Hľadanie v databáze",
"command.database.disconnect": "Odpojiť", "command.database.disconnect": "Odpojiť",
"command.database.export": "Exportovať databázu", "command.database.export": "Exportovať databázu",
"command.database.refresh": "Obnoviť štruktúru DB",
"command.database.refreshFull": "Obnoviť štruktúru DB (úplne)", "command.database.refreshFull": "Obnoviť štruktúru DB (úplne)",
"command.database.refreshIncremental": "Obnoviť štruktúru DB (inkrementálne)", "command.database.refreshIncremental": "Obnoviť štruktúru DB (inkrementálne)",
"command.database.reopenConnection": "Znovu otvoriť pripojenie", "command.database.reopenConnection": "Znovu otvoriť pripojenie",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "Veľkosť písmen", "settings.sqlEditor.sqlCommandsCase": "Veľkosť písmen",
"settings.sqlEditor.title": "SQL editor", "settings.sqlEditor.title": "SQL editor",
"settings.tabGroup.showServerName": "Zobraziť názov servera vedľa názvu databázy v názve skupiny kariet", "settings.tabGroup.showServerName": "Zobraziť názov servera vedľa názvu databázy v názve skupiny kariet",
"settings.tabPreviewMode": "Režim náhľadu kariet",
"settings.theme": "Vzhľad", "settings.theme": "Vzhľad",
"settings.title": "Nastavenia", "settings.title": "Nastavenia",
"settings.useNativeWindowTitle": "Použiť natívne menu", "settings.useNativeWindowTitle": "Použiť natívne menu",

View File

@@ -171,6 +171,7 @@
"command.database.databaseSearch": "数据库搜索", "command.database.databaseSearch": "数据库搜索",
"command.database.disconnect": "断开连接", "command.database.disconnect": "断开连接",
"command.database.export": "导出数据库", "command.database.export": "导出数据库",
"command.database.refresh": "刷新数据库结构",
"command.database.refreshFull": "刷新数据库结构(完整)", "command.database.refreshFull": "刷新数据库结构(完整)",
"command.database.refreshIncremental": "刷新数据库结构(增量)", "command.database.refreshIncremental": "刷新数据库结构(增量)",
"command.database.reopenConnection": "重新打开连接", "command.database.reopenConnection": "重新打开连接",
@@ -1198,6 +1199,7 @@
"settings.sqlEditor.sqlCommandsCase": "SQL命令大小写", "settings.sqlEditor.sqlCommandsCase": "SQL命令大小写",
"settings.sqlEditor.title": "SQL 编辑器", "settings.sqlEditor.title": "SQL 编辑器",
"settings.tabGroup.showServerName": "在标签页组标题中显示服务器名称和数据库名称", "settings.tabGroup.showServerName": "在标签页组标题中显示服务器名称和数据库名称",
"settings.tabPreviewMode": "标签页预览模式",
"settings.theme": "主题", "settings.theme": "主题",
"settings.title": "设置", "settings.title": "设置",
"settings.useNativeWindowTitle": "使用原生窗口标题", "settings.useNativeWindowTitle": "使用原生窗口标题",

View File

@@ -7,7 +7,7 @@ checkout-and-merge-pro:
repository: dbgate/dbgate-pro repository: dbgate/dbgate-pro
token: ${{ secrets.GH_TOKEN }} token: ${{ secrets.GH_TOKEN }}
path: dbgate-pro path: dbgate-pro
ref: 911941a53e91a5a777b8c7d455be0719234dde5f ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
- name: Merge dbgate/dbgate-pro - name: Merge dbgate/dbgate-pro
run: | run: |
mkdir ../dbgate-pro mkdir ../dbgate-pro