mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-17 21:26:00 +00:00
Merge branch 'master' into feature/FK-test
This commit is contained in:
2
.github/workflows/build-app-pro-beta.yaml
vendored
2
.github/workflows/build-app-pro-beta.yaml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 911941a53e91a5a777b8c7d455be0719234dde5f
|
||||
ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
2
.github/workflows/build-app-pro.yaml
vendored
2
.github/workflows/build-app-pro.yaml
vendored
@@ -43,7 +43,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 911941a53e91a5a777b8c7d455be0719234dde5f
|
||||
ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
2
.github/workflows/build-cloud-pro.yaml
vendored
2
.github/workflows/build-cloud-pro.yaml
vendored
@@ -39,7 +39,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 911941a53e91a5a777b8c7d455be0719234dde5f
|
||||
ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
2
.github/workflows/build-docker-pro.yaml
vendored
2
.github/workflows/build-docker-pro.yaml
vendored
@@ -44,7 +44,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 911941a53e91a5a777b8c7d455be0719234dde5f
|
||||
ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
2
.github/workflows/build-npm-pro.yaml
vendored
2
.github/workflows/build-npm-pro.yaml
vendored
@@ -35,7 +35,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 911941a53e91a5a777b8c7d455be0719234dde5f
|
||||
ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
2
.github/workflows/e2e-pro.yaml
vendored
2
.github/workflows/e2e-pro.yaml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 911941a53e91a5a777b8c7d455be0719234dde5f
|
||||
ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -8,13 +8,19 @@ Builds:
|
||||
- linux - application for linux
|
||||
- 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
|
||||
- FIXED: Fixed search in table shortcuts #1273
|
||||
- CHANGED: Improved foreign key editor UX
|
||||
- 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
|
||||
- ADDED: Better processing of table backups, generate table restore script #1274
|
||||
- CHANGED: Improved storage of settings, especially for Team Premium edition
|
||||
|
||||
## 6.7.1
|
||||
- ADDED: LANGUAGE environment variable for the web version. #1266
|
||||
|
||||
@@ -10,6 +10,7 @@ module.exports = defineConfig({
|
||||
// baseUrl: 'http://localhost:3000',
|
||||
// trashAssetsBeforeRuns: false,
|
||||
chromeWebSecurity: false,
|
||||
reporter: process.env.CI ? 'mocha-reporter-gha' : 'spec',
|
||||
|
||||
setupNodeEvents(on, config) {
|
||||
// implement node event listeners here
|
||||
|
||||
@@ -110,7 +110,7 @@ describe('Charts', () => {
|
||||
cy.themeshot('new-object-window');
|
||||
});
|
||||
|
||||
it('Database chat - charts', () => {
|
||||
it.skip('Database chat - charts', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
@@ -125,7 +125,7 @@ describe('Charts', () => {
|
||||
cy.themeshot('database-chat-chart');
|
||||
});
|
||||
|
||||
it('Database chat', () => {
|
||||
it.skip('Database chat', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
@@ -146,7 +146,7 @@ describe('Charts', () => {
|
||||
// cy.themeshot('database-chat');
|
||||
});
|
||||
|
||||
it('Explain query error', () => {
|
||||
it.skip('Explain query error', () => {
|
||||
cy.contains('MySql-connection').click();
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('TabsPanel_buttonNewObject').click();
|
||||
@@ -199,7 +199,7 @@ describe('Charts', () => {
|
||||
cy.testid('WidgetIconPanel_settings');
|
||||
});
|
||||
|
||||
it.only('Settings', () => {
|
||||
it('Settings', () => {
|
||||
cy.testid('WidgetIconPanel_settings').click();
|
||||
cy.themeshot('app-settings-general');
|
||||
|
||||
@@ -234,10 +234,10 @@ describe('Charts', () => {
|
||||
cy.contains('Light').click();
|
||||
cy.get('body').find('.theme-light').should('exist');
|
||||
|
||||
// Connection
|
||||
cy.contains(/^Connection$/).click();
|
||||
// General
|
||||
cy.contains(/^General$/).click();
|
||||
cy.contains('charts_sample');
|
||||
cy.get('[data-testid=ConnectionSettings_lockedDatabaseMode]').check();
|
||||
cy.get('[data-testid=GeneralSettings_lockedDatabaseMode]').check();
|
||||
cy.contains('Connections').click();
|
||||
cy.contains('charts_sample').should('not.exist');
|
||||
|
||||
|
||||
@@ -210,7 +210,8 @@ describe('Import CSV', () => {
|
||||
cy.testid('ImportExportConfigurator_tableMappingSection').contains('20 rows written').should('be.visible');
|
||||
|
||||
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.contains('Rows: 20').should('be.visible');
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
"cypress-real-events": "^1.13.0",
|
||||
"env-cmd": "^10.1.0",
|
||||
"kill-port": "^2.0.1",
|
||||
"mocha-reporter-gha": "^1.1.1",
|
||||
"start-server-and-test": "^2.0.8"
|
||||
},
|
||||
"scripts": {
|
||||
"cy:open": "cypress open --config experimentalInteractiveRunEvents=true",
|
||||
|
||||
"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: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:cloud": "cypress run --spec cypress/e2e/cloud.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: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",
|
||||
@@ -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: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",
|
||||
|
||||
"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: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: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": "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"
|
||||
},
|
||||
|
||||
@@ -2,6 +2,34 @@
|
||||
# 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":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
|
||||
@@ -39,6 +67,11 @@
|
||||
debug "^3.1.0"
|
||||
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":
|
||||
version "9.3.0"
|
||||
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"
|
||||
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:
|
||||
version "2.1.3"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
|
||||
@@ -1292,6 +1332,11 @@ tunnel-agent@^0.6.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "0.14.5"
|
||||
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"
|
||||
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:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d"
|
||||
|
||||
@@ -28,12 +28,12 @@ describe('Schema tests', () => {
|
||||
const count = schemas1.length;
|
||||
expect(structure1.tables.length).toEqual(2);
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
})
|
||||
@@ -50,10 +50,10 @@ describe('Schema tests', () => {
|
||||
expect(schemas1.find(x => x.schemaName == 'myschema')).toBeTruthy();
|
||||
expect(structure1.tables.length).toEqual(2);
|
||||
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) {
|
||||
const structure2 = await driver.analyseIncremental(conn, structure1);
|
||||
const schemas2 = await driver.listSchemas(conn);
|
||||
expect(schemas2.find(x => x.schemaName == 'myschema')).toBeFalsy();
|
||||
expect(structure2).toBeNull();
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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',
|
||||
testWrapper(async (conn, driver, 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',
|
||||
testWrapper(async (conn, driver, 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',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await runCommandOnDriver(conn, driver, dmp => dmp.put(t1Sql(engine)));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "6.7.2-premium-beta.5",
|
||||
"version": "6.7.3",
|
||||
"name": "dbgate-all",
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
|
||||
@@ -289,16 +289,11 @@ module.exports = {
|
||||
const res = await lock.acquire('settings', async () => {
|
||||
const currentValue = await this.loadSettings();
|
||||
try {
|
||||
let updated = currentValue;
|
||||
let updated = {
|
||||
...currentValue,
|
||||
...values,
|
||||
};
|
||||
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({
|
||||
group: 'settings',
|
||||
config: updated,
|
||||
|
||||
@@ -360,6 +360,12 @@ module.exports = {
|
||||
"columnName": "value",
|
||||
"dataType": "varchar(1000)",
|
||||
"notNull": false
|
||||
},
|
||||
{
|
||||
"pureName": "config",
|
||||
"columnName": "valueType",
|
||||
"dataType": "varchar(50)",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"foreignKeys": [],
|
||||
|
||||
@@ -164,6 +164,11 @@ export class DatabaseAnalyser<TClient = any> {
|
||||
|
||||
const res = {};
|
||||
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
|
||||
.filter(x => x.action == 'remove' && x.objectTypeField == field)
|
||||
.map(x => x.objectId);
|
||||
|
||||
@@ -45,14 +45,15 @@ export function hexStringToArray(inputString) {
|
||||
|
||||
export function base64ToHex(base64String) {
|
||||
const binaryString = atob(base64String);
|
||||
const hexString = Array.from(binaryString, c =>
|
||||
c.charCodeAt(0).toString(16).padStart(2, '0')
|
||||
).join('');
|
||||
const hexString = Array.from(binaryString, c => c.charCodeAt(0).toString(16).padStart(2, '0')).join('');
|
||||
return '0x' + hexString.toUpperCase();
|
||||
};
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -68,9 +69,9 @@ export function parseCellValue(value, editorTypes?: DataEditorTypesBehaviour) {
|
||||
if (mHex) {
|
||||
return {
|
||||
$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' };
|
||||
}
|
||||
|
||||
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(
|
||||
value,
|
||||
intent:
|
||||
@@ -210,7 +231,7 @@ export function stringifyCellValue(
|
||||
| 'exportIntent'
|
||||
| 'clipboardIntent',
|
||||
editorTypes?: DataEditorTypesBehaviour,
|
||||
gridFormattingOptions?: { useThousandsSeparator?: boolean },
|
||||
gridFormattingOptions?: { thousandsSeparator?: string },
|
||||
jsonParsedValue?: any
|
||||
): {
|
||||
value: string;
|
||||
@@ -256,7 +277,7 @@ export function stringifyCellValue(
|
||||
// return { value: '0x' + arrayToHexString(value.data), gridStyle: 'valueCellStyle' };
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
if (editorTypes?.parseObjectIdAsDollar) {
|
||||
if (value?.$oid) {
|
||||
switch (intent) {
|
||||
@@ -270,13 +291,13 @@ export function stringifyCellValue(
|
||||
}
|
||||
if (value?.$bigint) {
|
||||
return {
|
||||
value: value.$bigint,
|
||||
value: formatCellNumber(value.$bigint, gridFormattingOptions),
|
||||
gridStyle: 'valueCellStyle',
|
||||
};
|
||||
}
|
||||
if (typeof value === 'bigint') {
|
||||
return {
|
||||
value: value.toString(),
|
||||
value: formatCellNumber(value.toString(), gridFormattingOptions),
|
||||
gridStyle: 'valueCellStyle',
|
||||
};
|
||||
}
|
||||
@@ -351,13 +372,8 @@ export function stringifyCellValue(
|
||||
if (_isNumber(value)) {
|
||||
switch (intent) {
|
||||
case 'gridCellIntent':
|
||||
return {
|
||||
value:
|
||||
gridFormattingOptions?.useThousandsSeparator && (value >= 10000 || value <= -10000)
|
||||
? value.toLocaleString()
|
||||
: value.toString(),
|
||||
gridStyle: 'valueCellStyle',
|
||||
};
|
||||
const separator = gridFormattingOptions?.thousandsSeparator;
|
||||
return { value: formatCellNumber(value, gridFormattingOptions), gridStyle: 'valueCellStyle' };
|
||||
default:
|
||||
return { value: value.toString() };
|
||||
}
|
||||
|
||||
@@ -40,8 +40,6 @@ import { getSettings } from '../utility/metadataLoaders';
|
||||
import { isMac, switchCurrentDatabase } from '../utility/common';
|
||||
import { doLogout } from '../clientAuth';
|
||||
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 ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||
import localforage from 'localforage';
|
||||
@@ -73,7 +71,8 @@ registerCommand({
|
||||
category: __t('command.theme', { defaultMessage: 'Theme' }),
|
||||
name: __t('command.theme.change', { defaultMessage: 'Change' }),
|
||||
toolbarName: __t('command.theme.changeToolbar', { defaultMessage: 'Change theme' }),
|
||||
onClick: () => openNewTab({
|
||||
onClick: () =>
|
||||
openNewTab({
|
||||
title: 'Settings',
|
||||
icon: 'icon settings',
|
||||
tabComponent: 'SettingsTab',
|
||||
@@ -1230,8 +1229,7 @@ registerCommand({
|
||||
},
|
||||
});
|
||||
|
||||
if ( hasPermission('application-log'))
|
||||
{
|
||||
if (hasPermission('application-log')) {
|
||||
registerCommand({
|
||||
id: 'app.showLogs',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
@@ -1246,8 +1244,7 @@ if ( hasPermission('application-log'))
|
||||
});
|
||||
}
|
||||
|
||||
if (hasPermission('widgets/plugins'))
|
||||
{
|
||||
if (hasPermission('widgets/plugins')) {
|
||||
registerCommand({
|
||||
id: 'app.managePlugins',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import { getBoolSettingsValue } from '../settings/settingsTools';
|
||||
import { getStringSettingsValue } from '../settings/settingsTools';
|
||||
import { stringifyCellValue } from 'dbgate-tools';
|
||||
|
||||
export let rowData;
|
||||
@@ -13,7 +13,7 @@
|
||||
value,
|
||||
'gridCellIntent',
|
||||
editorTypes,
|
||||
{ useThousandsSeparator: getBoolSettingsValue('dataGrid.thousandsSeparator', false) },
|
||||
{ thousandsSeparator: getStringSettingsValue('dataGrid.thousandsSeparatorChar', 'none') },
|
||||
jsonParsedValue
|
||||
);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script lang="ts">
|
||||
import _, { isPlainObject } from 'lodash';
|
||||
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 CellValue from './CellValue.svelte';
|
||||
import { openJsonLinesData } from '../utility/openJsonLinesData';
|
||||
@@ -80,7 +80,7 @@
|
||||
class:isFocusedColumn
|
||||
class:hasOverlayValue
|
||||
class:isMissingOverlayField
|
||||
class:alignRight={_.isNumber(value) && !showHint}
|
||||
class:alignRight={ (_.isNumber(value) || isTypeNumber(col.dataType)) && !showHint}
|
||||
{style}
|
||||
>
|
||||
{#if hasOverlayValue}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<script lang="ts">
|
||||
import FontIcon from "../icons/FontIcon.svelte";
|
||||
|
||||
export let type;
|
||||
export let label;
|
||||
export let noMargin = false;
|
||||
export let disabled = false;
|
||||
export let labelProps: any = {};
|
||||
export let labelIcon = null;
|
||||
</script>
|
||||
|
||||
<div class="largeFormMarker" class:noMargin>
|
||||
@@ -12,6 +15,9 @@
|
||||
<span {...labelProps} on:click={labelProps.onClick} class:disabled class='checkLabel'>{label}</span>
|
||||
{:else}
|
||||
<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>
|
||||
</div>
|
||||
<slot />
|
||||
|
||||
@@ -164,7 +164,12 @@
|
||||
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>
|
||||
{#if item.switchValue && item.switchStoreGetter}
|
||||
{#key switchIndex}
|
||||
|
||||
@@ -1,81 +1,64 @@
|
||||
<script lang="ts">
|
||||
import CheckboxField from "../forms/CheckboxField.svelte";
|
||||
import FormCheckboxField from "../forms/FormCheckboxField.svelte";
|
||||
import FormFieldTemplateLarge from "../forms/FormFieldTemplateLarge.svelte";
|
||||
import FormSelectField from "../forms/FormSelectField.svelte";
|
||||
import FormTextField from "../forms/FormTextField.svelte";
|
||||
import FormValues from "../forms/FormValues.svelte";
|
||||
import { lockedDatabaseMode } from "../stores";
|
||||
import { _t } from "../translations";
|
||||
|
||||
|
||||
import CheckboxField from '../forms/CheckboxField.svelte';
|
||||
import FormCheckboxField from '../forms/FormCheckboxField.svelte';
|
||||
import FormFieldTemplateLarge from '../forms/FormFieldTemplateLarge.svelte';
|
||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import FormValues from '../forms/FormValues.svelte';
|
||||
import { lockedDatabaseMode } from '../stores';
|
||||
import { _t } from '../translations';
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<FormValues let:values>
|
||||
<FormValues let:values>
|
||||
<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
|
||||
name="connection.autoRefresh"
|
||||
label={_t('settings.connection.autoRefresh', {
|
||||
name="connection.autoRefresh"
|
||||
label={_t('settings.connection.autoRefresh', {
|
||||
defaultMessage: 'Automatic refresh of database model on background',
|
||||
})}
|
||||
defaultValue={false}
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
<FormTextField
|
||||
name="connection.autoRefreshInterval"
|
||||
label={_t('settings.connection.autoRefreshInterval', {
|
||||
name="connection.autoRefreshInterval"
|
||||
label={_t('settings.connection.autoRefreshInterval', {
|
||||
defaultMessage: 'Interval between automatic DB structure reloads in seconds',
|
||||
})}
|
||||
defaultValue="30"
|
||||
disabled={values['connection.autoRefresh'] === false}
|
||||
})}
|
||||
defaultValue="30"
|
||||
disabled={values['connection.autoRefresh'] === false}
|
||||
/>
|
||||
<FormSelectField
|
||||
label={_t('settings.connection.sshBindHost', { defaultMessage: 'Local host address for SSH connections' })}
|
||||
name="connection.sshBindHost"
|
||||
isNative
|
||||
defaultValue="127.0.0.1"
|
||||
options={[
|
||||
label={_t('settings.connection.sshBindHost', { defaultMessage: 'Local host address for SSH connections' })}
|
||||
name="connection.sshBindHost"
|
||||
isNative
|
||||
defaultValue="127.0.0.1"
|
||||
options={[
|
||||
{ value: '127.0.0.1', label: '127.0.0.1 (IPv4)' },
|
||||
{ value: '::1', label: '::1 (IPv6)' },
|
||||
{ value: 'localhost', label: 'localhost (domain name)' },
|
||||
]}
|
||||
]}
|
||||
/>
|
||||
|
||||
<div class="heading">{_t('settings.session', { defaultMessage: 'Query sessions' })}</div>
|
||||
<FormCheckboxField
|
||||
name="session.autoClose"
|
||||
label={_t('settings.session.autoClose', {
|
||||
name="session.autoClose"
|
||||
label={_t('settings.session.autoClose', {
|
||||
defaultMessage: 'Automatic close query sessions after period without any activity',
|
||||
})}
|
||||
defaultValue={true}
|
||||
})}
|
||||
defaultValue={true}
|
||||
/>
|
||||
<FormTextField
|
||||
name="session.autoCloseTimeout"
|
||||
label={_t('settings.session.autoCloseTimeout', {
|
||||
name="session.autoCloseTimeout"
|
||||
label={_t('settings.session.autoCloseTimeout', {
|
||||
defaultMessage: 'Interval, after which query session without activity is closed (in minutes)',
|
||||
})}
|
||||
defaultValue="15"
|
||||
disabled={values['session.autoClose'] === false}
|
||||
})}
|
||||
defaultValue="15"
|
||||
disabled={values['session.autoClose'] === false}
|
||||
/>
|
||||
</FormValues>
|
||||
</FormValues>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
@@ -84,12 +67,11 @@
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.wrapper :global(input){
|
||||
.wrapper :global(input) {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.wrapper :global(select){
|
||||
.wrapper :global(select) {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -1,94 +1,105 @@
|
||||
<script lang="ts">
|
||||
import FormCheckboxField from "../forms/FormCheckboxField.svelte";
|
||||
import FormSelectField from "../forms/FormSelectField.svelte";
|
||||
import FormTextField from "../forms/FormTextField.svelte";
|
||||
import { _t } from "../translations";
|
||||
import { isProApp } from "../utility/proTools";
|
||||
|
||||
|
||||
import FormCheckboxField from '../forms/FormCheckboxField.svelte';
|
||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import { _t } from '../translations';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="heading">{_t('settings.dataGrid.title', { defaultMessage: 'Data grid' })}</div>
|
||||
<FormTextField
|
||||
name="dataGrid.pageSize"
|
||||
label={_t('settings.dataGrid.pageSize', {
|
||||
defaultMessage: 'Page size (number of rows for incremental loading, must be between 5 and 50000)',
|
||||
})}
|
||||
defaultValue="100"
|
||||
/>
|
||||
{#if isProApp()}
|
||||
<FormCheckboxField
|
||||
name="dataGrid.showHintColumns"
|
||||
label={_t('settings.dataGrid.showHintColumns', { defaultMessage: 'Show foreign key hints' })}
|
||||
defaultValue={true}
|
||||
data-testid="DataGridSettings_showHintColumns"
|
||||
/>
|
||||
{/if}
|
||||
<!-- <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} /> -->
|
||||
<div class="heading">{_t('settings.dataGrid.title', { defaultMessage: 'Data grid' })}</div>
|
||||
<FormTextField
|
||||
name="dataGrid.pageSize"
|
||||
label={_t('settings.dataGrid.pageSize', {
|
||||
defaultMessage: 'Page size (number of rows for incremental loading, must be between 5 and 50000)',
|
||||
})}
|
||||
defaultValue="100"
|
||||
/>
|
||||
{#if isProApp()}
|
||||
<FormCheckboxField
|
||||
name="dataGrid.showHintColumns"
|
||||
label={_t('settings.dataGrid.showHintColumns', { defaultMessage: 'Show foreign key hints' })}
|
||||
defaultValue={true}
|
||||
data-testid="DataGridSettings_showHintColumns"
|
||||
/>
|
||||
{/if}
|
||||
<!-- <FormCheckboxField name="dataGrid.showHintColumns" label="Show foreign key hints" defaultValue={true} /> -->
|
||||
|
||||
<FormCheckboxField
|
||||
name="dataGrid.thousandsSeparator"
|
||||
label={_t('settings.dataGrid.thousandsSeparator', {
|
||||
defaultMessage: 'Use thousands separator for numbers',
|
||||
})}
|
||||
/>
|
||||
<FormSelectField
|
||||
label={_t('settings.dataGrid.thousandsSeparator', { defaultMessage: 'Thousands separator for numbers' })}
|
||||
name="dataGrid.thousandsSeparatorChar"
|
||||
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
|
||||
name="dataGrid.defaultAutoRefreshInterval"
|
||||
label={_t('settings.dataGrid.defaultAutoRefreshInterval', {
|
||||
defaultMessage: 'Default grid auto refresh interval in seconds',
|
||||
})}
|
||||
defaultValue="10"
|
||||
/>
|
||||
<FormTextField
|
||||
name="dataGrid.defaultAutoRefreshInterval"
|
||||
label={_t('settings.dataGrid.defaultAutoRefreshInterval', {
|
||||
defaultMessage: 'Default grid auto refresh interval in seconds',
|
||||
})}
|
||||
defaultValue="10"
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="dataGrid.alignNumbersRight"
|
||||
label={_t('settings.dataGrid.alignNumbersRight', { defaultMessage: 'Align numbers to right' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
<FormCheckboxField
|
||||
name="dataGrid.alignNumbersRight"
|
||||
label={_t('settings.dataGrid.alignNumbersRight', { defaultMessage: 'Align numbers to right' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<FormTextField
|
||||
name="dataGrid.collectionPageSize"
|
||||
label={_t('settings.dataGrid.collectionPageSize', {
|
||||
defaultMessage: 'Collection page size (for MongoDB JSON view, must be between 5 and 1000)',
|
||||
})}
|
||||
defaultValue="50"
|
||||
/>
|
||||
<FormTextField
|
||||
name="dataGrid.collectionPageSize"
|
||||
label={_t('settings.dataGrid.collectionPageSize', {
|
||||
defaultMessage: 'Collection page size (for MongoDB JSON view, must be between 5 and 1000)',
|
||||
})}
|
||||
defaultValue="50"
|
||||
/>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.dataGrid.coloringMode', { defaultMessage: 'Row coloring mode' })}
|
||||
name="dataGrid.coloringMode"
|
||||
isNative
|
||||
defaultValue="36"
|
||||
options={[
|
||||
{
|
||||
value: '36',
|
||||
label: _t('settings.dataGrid.coloringMode.36', { defaultMessage: 'Every 3rd and 6th row' }),
|
||||
},
|
||||
{
|
||||
value: '2-primary',
|
||||
label: _t('settings.dataGrid.coloringMode.2-primary', {
|
||||
defaultMessage: 'Every 2-nd row, primary color',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: '2-secondary',
|
||||
label: _t('settings.dataGrid.coloringMode.2-secondary', {
|
||||
defaultMessage: 'Every 2-nd row, secondary color',
|
||||
}),
|
||||
},
|
||||
{ value: 'none', label: _t('settings.dataGrid.coloringMode.none', { defaultMessage: 'None' }) },
|
||||
]}
|
||||
/>
|
||||
<FormSelectField
|
||||
label={_t('settings.dataGrid.coloringMode', { defaultMessage: 'Row coloring mode' })}
|
||||
name="dataGrid.coloringMode"
|
||||
isNative
|
||||
defaultValue="36"
|
||||
options={[
|
||||
{
|
||||
value: '36',
|
||||
label: _t('settings.dataGrid.coloringMode.36', { defaultMessage: 'Every 3rd and 6th row' }),
|
||||
},
|
||||
{
|
||||
value: '2-primary',
|
||||
label: _t('settings.dataGrid.coloringMode.2-primary', {
|
||||
defaultMessage: 'Every 2-nd row, primary color',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: '2-secondary',
|
||||
label: _t('settings.dataGrid.coloringMode.2-secondary', {
|
||||
defaultMessage: 'Every 2-nd row, secondary color',
|
||||
}),
|
||||
},
|
||||
{ value: 'none', label: _t('settings.dataGrid.coloringMode.none', { defaultMessage: 'None' }) },
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="dataGrid.showAllColumnsWhenSearch"
|
||||
label={_t('settings.dataGrid.showAllColumnsWhenSearch', {
|
||||
defaultMessage: 'Show all columns when searching',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
<FormCheckboxField
|
||||
name="dataGrid.showAllColumnsWhenSearch"
|
||||
label={_t('settings.dataGrid.showAllColumnsWhenSearch', {
|
||||
defaultMessage: 'Show all columns when searching',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
@@ -99,11 +110,11 @@ defaultValue={false}
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.wrapper :global(select){
|
||||
.wrapper :global(select) {
|
||||
max-width: 400px;
|
||||
}
|
||||
|
||||
.wrapper :global(input){
|
||||
.wrapper :global(input) {
|
||||
max-width: 400px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
import { isMac } from '../utility/common';
|
||||
import getElectron from '../utility/getElectron';
|
||||
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
import CheckboxField from '../forms/CheckboxField.svelte';
|
||||
import { lockedDatabaseMode } from '../stores';
|
||||
|
||||
const electron = getElectron();
|
||||
let restartWarning = false;
|
||||
@@ -17,7 +20,11 @@
|
||||
|
||||
<div class="wrapper">
|
||||
<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
|
||||
isNative
|
||||
data-testid="SettingsModal_languageSelect"
|
||||
@@ -78,6 +85,24 @@
|
||||
/>
|
||||
{/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>
|
||||
|
||||
{#if electron}
|
||||
@@ -106,6 +131,7 @@
|
||||
defaultMessage: 'Show server name alongside database name in title of the tab group',
|
||||
})}
|
||||
defaultValue={false}
|
||||
disabled={!hasPermission('settings/change')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -29,6 +29,13 @@ export function getStringSettingsValue(name, defaultValue) {
|
||||
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' {
|
||||
return getStringSettingsValue('defaultAction.connectionClick', 'connect');
|
||||
}
|
||||
|
||||
@@ -3,111 +3,114 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import SettingsMenuControl from "../elements/SettingsMenuControl.svelte";
|
||||
import GeneralSettings from "../settings/GeneralSettings.svelte";
|
||||
import SettingsFormProvider from "../forms/SettingsFormProvider.svelte";
|
||||
import ConnectionSettings from "../settings/ConnectionSettings.svelte";
|
||||
import ThemeSettings from "../settings/ThemeSettings.svelte";
|
||||
import DefaultActionsSettings from "../settings/DefaultActionsSettings.svelte";
|
||||
import BehaviourSettings from "../settings/BehaviourSettings.svelte";
|
||||
import ExternalToolsSettings from "../settings/ExternalToolsSettings.svelte";
|
||||
import LicenseSettings from "../settings/LicenseSettings.svelte";
|
||||
import { isProApp } from "../utility/proTools";
|
||||
import { _t } from "../translations";
|
||||
import CommandListTab from "./CommandListTab.svelte";
|
||||
import DataGridSettings from "../settings/DataGridSettings.svelte";
|
||||
import SQLEditorSettings from "../settings/SQLEditorSettings.svelte";
|
||||
import AiSettingsTab from "../settings/AiSettingsTab.svelte";
|
||||
import SettingsMenuControl from '../elements/SettingsMenuControl.svelte';
|
||||
import GeneralSettings from '../settings/GeneralSettings.svelte';
|
||||
import SettingsFormProvider from '../forms/SettingsFormProvider.svelte';
|
||||
import ConnectionSettings from '../settings/ConnectionSettings.svelte';
|
||||
import ThemeSettings from '../settings/ThemeSettings.svelte';
|
||||
import DefaultActionsSettings from '../settings/DefaultActionsSettings.svelte';
|
||||
import BehaviourSettings from '../settings/BehaviourSettings.svelte';
|
||||
import ExternalToolsSettings from '../settings/ExternalToolsSettings.svelte';
|
||||
import LicenseSettings from '../settings/LicenseSettings.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { _t } from '../translations';
|
||||
import CommandListTab from './CommandListTab.svelte';
|
||||
import DataGridSettings from '../settings/DataGridSettings.svelte';
|
||||
import SQLEditorSettings from '../settings/SQLEditorSettings.svelte';
|
||||
import AiSettingsTab from '../settings/AiSettingsTab.svelte';
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
|
||||
export let selectedItem = 'general';
|
||||
export let selectedItem = 'general';
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
label: _t('settings.general', { defaultMessage: 'General' }),
|
||||
identifier: 'general',
|
||||
component: GeneralSettings,
|
||||
props: {},
|
||||
testid: 'settings-general',
|
||||
},
|
||||
{
|
||||
label: _t('settings.connection', { defaultMessage: 'Connection' }),
|
||||
identifier: 'connection',
|
||||
component: ConnectionSettings,
|
||||
props: {},
|
||||
testid: 'settings-connection',
|
||||
},
|
||||
{
|
||||
label: _t('settings.dataGrid.title', { defaultMessage: 'Data grid' }),
|
||||
identifier: 'data-grid',
|
||||
component: DataGridSettings,
|
||||
props: {},
|
||||
testid: 'settings-data-grid',
|
||||
},
|
||||
{
|
||||
label: _t('settings.sqlEditor.title', { defaultMessage: 'SQL Editor' }),
|
||||
identifier: 'sql-editor',
|
||||
component: SQLEditorSettings,
|
||||
props: {},
|
||||
testid: 'settings-sql-editor',
|
||||
},
|
||||
{
|
||||
label: _t('settings.theme', { defaultMessage: 'Themes' }),
|
||||
identifier: 'theme',
|
||||
component: ThemeSettings,
|
||||
props: {},
|
||||
testid: 'settings-themes',
|
||||
},
|
||||
{
|
||||
label: _t('settings.defaultActions', { defaultMessage: 'Default Actions' }),
|
||||
identifier: 'default-actions',
|
||||
component: DefaultActionsSettings,
|
||||
props: {},
|
||||
testid: 'settings-default-actions',
|
||||
},
|
||||
{
|
||||
label: _t('settings.behaviour', { defaultMessage: 'Behaviour' }),
|
||||
identifier: 'behaviour',
|
||||
component: BehaviourSettings,
|
||||
props: {},
|
||||
testid: 'settings-behaviour',
|
||||
},
|
||||
{
|
||||
label: _t('settings.externalTools', { defaultMessage: 'External Tools' }),
|
||||
identifier: 'external-tools',
|
||||
component: ExternalToolsSettings,
|
||||
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',
|
||||
component: LicenseSettings,
|
||||
props: {},
|
||||
testid: 'settings-license',
|
||||
},
|
||||
isProApp() && {
|
||||
label: _t('settings.AI', { defaultMessage: 'AI'}),
|
||||
identifier: 'ai',
|
||||
component: AiSettingsTab,
|
||||
props: {},
|
||||
testid: 'settings-ai',
|
||||
},
|
||||
];
|
||||
const menuItems = [
|
||||
{
|
||||
label: _t('settings.general', { defaultMessage: 'General' }),
|
||||
identifier: 'general',
|
||||
component: GeneralSettings,
|
||||
props: {},
|
||||
testid: 'settings-general',
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
label: _t('settings.connection', { defaultMessage: 'Connection' }),
|
||||
identifier: 'connection',
|
||||
component: ConnectionSettings,
|
||||
props: {},
|
||||
testid: 'settings-connection',
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
label: _t('settings.dataGrid.title', { defaultMessage: 'Data grid' }),
|
||||
identifier: 'data-grid',
|
||||
component: DataGridSettings,
|
||||
props: {},
|
||||
testid: 'settings-data-grid',
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
label: _t('settings.sqlEditor.title', { defaultMessage: 'SQL Editor' }),
|
||||
identifier: 'sql-editor',
|
||||
component: SQLEditorSettings,
|
||||
props: {},
|
||||
testid: 'settings-sql-editor',
|
||||
},
|
||||
{
|
||||
label: _t('settings.theme', { defaultMessage: 'Themes' }),
|
||||
identifier: 'theme',
|
||||
component: ThemeSettings,
|
||||
props: {},
|
||||
testid: 'settings-themes',
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
label: _t('settings.defaultActions', { defaultMessage: 'Default Actions' }),
|
||||
identifier: 'default-actions',
|
||||
component: DefaultActionsSettings,
|
||||
props: {},
|
||||
testid: 'settings-default-actions',
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
label: _t('settings.behaviour', { defaultMessage: 'Behaviour' }),
|
||||
identifier: 'behaviour',
|
||||
component: BehaviourSettings,
|
||||
props: {},
|
||||
testid: 'settings-behaviour',
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
label: _t('settings.externalTools', { defaultMessage: 'External Tools' }),
|
||||
identifier: 'external-tools',
|
||||
component: ExternalToolsSettings,
|
||||
props: {},
|
||||
testid: 'settings-external-tools',
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
label: _t('command.settings.shortcuts', { defaultMessage: 'Keyboard shortcuts' }),
|
||||
identifier: 'shortcuts',
|
||||
component: CommandListTab,
|
||||
props: {},
|
||||
testid: 'settings-shortcuts',
|
||||
},
|
||||
hasPermission('settings/change') &&
|
||||
isProApp() && {
|
||||
label: _t('settings.license', { defaultMessage: 'License' }),
|
||||
identifier: 'license',
|
||||
component: LicenseSettings,
|
||||
props: {},
|
||||
testid: 'settings-license',
|
||||
},
|
||||
hasPermission('settings/change') &&
|
||||
isProApp() && {
|
||||
label: _t('settings.AI', { defaultMessage: 'AI' }),
|
||||
identifier: 'ai',
|
||||
component: AiSettingsTab,
|
||||
props: {},
|
||||
testid: 'settings-ai',
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<SettingsFormProvider>
|
||||
<SettingsMenuControl
|
||||
items={menuItems}
|
||||
bind:value={selectedItem}
|
||||
flex1={true}
|
||||
flexColContainer={true}
|
||||
scrollableContentContainer={true}
|
||||
<SettingsMenuControl
|
||||
items={menuItems}
|
||||
bind:value={selectedItem}
|
||||
flex1={true}
|
||||
flexColContainer={true}
|
||||
scrollableContentContainer={true}
|
||||
/>
|
||||
</SettingsFormProvider>
|
||||
</SettingsFormProvider>
|
||||
|
||||
@@ -166,6 +166,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
|
||||
apiCall('database-connections/sync-model', dbid);
|
||||
callSchemalListChanged();
|
||||
},
|
||||
testid: 'DatabasStatusMenu_refreshIncremental',
|
||||
},
|
||||
{
|
||||
text: driver?.supportsIncrementalAnalysis
|
||||
@@ -175,6 +176,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
|
||||
apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true });
|
||||
callSchemalListChanged();
|
||||
},
|
||||
testid: 'DatabasStatusMenu_refreshFull',
|
||||
},
|
||||
{
|
||||
text: _t('command.database.reopenConnection', { defaultMessage: 'Reopen connection' }),
|
||||
@@ -182,6 +184,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
|
||||
apiCall('database-connections/refresh', dbid);
|
||||
callSchemalListChanged();
|
||||
},
|
||||
testid: 'DatabasStatusMenu_reopenConnection',
|
||||
},
|
||||
{
|
||||
text: _t('command.database.disconnect', { defaultMessage: 'Disconnect' }),
|
||||
@@ -190,6 +193,7 @@ export function getDatabasStatusMenu(dbid, driver = null) {
|
||||
if (electron) apiCall('database-connections/disconnect', dbid);
|
||||
switchCurrentDatabase(null);
|
||||
},
|
||||
testid: 'DatabasStatusMenu_disconnect',
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "Vyhledávání v databázi",
|
||||
"command.database.disconnect": "Odpojit",
|
||||
"command.database.export": "Exportovat databázi",
|
||||
"command.database.refresh": "Obnovit strukturu DB",
|
||||
"command.database.refreshFull": "Obnovit strukturu DB (úplně)",
|
||||
"command.database.refreshIncremental": "Obnovit strukturu DB (inkrementálně)",
|
||||
"command.database.reopenConnection": "Znovu otevřít připojení",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "Velikost písmen SQL příkazů",
|
||||
"settings.sqlEditor.title": "SQL editor",
|
||||
"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.title": "Nastavení",
|
||||
"settings.useNativeWindowTitle": "Použít nativní titulek okna",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "Datenbanksuche",
|
||||
"command.database.disconnect": "Trennen",
|
||||
"command.database.export": "Datenbank exportieren",
|
||||
"command.database.refresh": "DB-Struktur aktualisieren",
|
||||
"command.database.refreshFull": "DB-Struktur aktualisieren (vollständig)",
|
||||
"command.database.refreshIncremental": "DB-Struktur aktualisieren (inkrementell)",
|
||||
"command.database.reopenConnection": "Verbindung erneut öffnen",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "Groß-/Kleinschreibung der SQL-Befehle",
|
||||
"settings.sqlEditor.title": "SQL-Editor",
|
||||
"settings.tabGroup.showServerName": "Servername neben Datenbankname im Titel der Tab-Gruppe anzeigen",
|
||||
"settings.tabPreviewMode": "Tab-Vorschaumodus",
|
||||
"settings.theme": "Designs",
|
||||
"settings.title": "Einstellungen",
|
||||
"settings.useNativeWindowTitle": "Nativen Fenstertitel verwenden",
|
||||
|
||||
@@ -167,6 +167,7 @@
|
||||
"command.database.databaseSearch": "Database search",
|
||||
"command.database.disconnect": "Disconnect",
|
||||
"command.database.export": "Export database",
|
||||
"command.database.refresh": "Refresh DB structure",
|
||||
"command.database.refreshFull": "Refresh DB structure (full)",
|
||||
"command.database.refreshIncremental": "Refresh DB structure (incremental)",
|
||||
"command.database.reopenConnection": "Reopen connection",
|
||||
@@ -1190,6 +1191,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "SQL commands case",
|
||||
"settings.sqlEditor.title": "SQL Editor",
|
||||
"settings.tabGroup.showServerName": "Show server name alongside database name in title of the tab group",
|
||||
"settings.tabPreviewMode": "Tab Preview Mode",
|
||||
"settings.theme": "Themes",
|
||||
"settings.useNativeWindowTitle": "Use native window title",
|
||||
"settings.useSystemNativeMenu": "Use system native menu",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "Búsqueda en base de datos",
|
||||
"command.database.disconnect": "Desconectar",
|
||||
"command.database.export": "Exportar base de datos",
|
||||
"command.database.refresh": "Refrescar estructura de BD",
|
||||
"command.database.refreshFull": "Refrescar estructura de BD (completa)",
|
||||
"command.database.refreshIncremental": "Refrescar estructura de BD (incremental)",
|
||||
"command.database.reopenConnection": "Reabrir conexión",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "Mayúsculas/minúsculas de comandos 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.tabPreviewMode": "Modo de vista previa de pestaña",
|
||||
"settings.theme": "Temas",
|
||||
"settings.title": "Configuración",
|
||||
"settings.useNativeWindowTitle": "Usar título de ventana nativo",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "Recherche dans la base de données",
|
||||
"command.database.disconnect": "Déconnecter",
|
||||
"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.refreshIncremental": "Rafraîchir la structure de BD (incrémentale)",
|
||||
"command.database.reopenConnection": "Rouvrir la connexion",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "Casse des commandes 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.tabPreviewMode": "Mode aperçu d'onglet",
|
||||
"settings.theme": "Thèmes",
|
||||
"settings.title": "Paramètres",
|
||||
"settings.useNativeWindowTitle": "Utiliser le titre de fenêtre natif",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "Ricerca database",
|
||||
"command.database.disconnect": "Disconnetti",
|
||||
"command.database.export": "Esporta database",
|
||||
"command.database.refresh": "Aggiorna struttura DB",
|
||||
"command.database.refreshFull": "Aggiorna struttura DB (completo)",
|
||||
"command.database.refreshIncremental": "Aggiorna struttura DB (incrementale)",
|
||||
"command.database.reopenConnection": "Riapri connessione",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "Maiuscole/minuscole comandi SQL",
|
||||
"settings.sqlEditor.title": "Editor SQL",
|
||||
"settings.tabGroup.showServerName": "Mostra nome server accanto al nome database nel titolo del gruppo schede",
|
||||
"settings.tabPreviewMode": "Modalità anteprima scheda",
|
||||
"settings.theme": "Temi",
|
||||
"settings.title": "Impostazioni",
|
||||
"settings.useNativeWindowTitle": "Usa titolo finestra nativo",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "データベース検索",
|
||||
"command.database.disconnect": "切断",
|
||||
"command.database.export": "データベースをエクスポート",
|
||||
"command.database.refresh": "DB構造を更新",
|
||||
"command.database.refreshFull": "DB構造を更新(フル)",
|
||||
"command.database.refreshIncremental": "DB構造を更新(増分)",
|
||||
"command.database.reopenConnection": "接続を再度開く",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "SQLコマンドの大文字小文字",
|
||||
"settings.sqlEditor.title": "SQLエディター",
|
||||
"settings.tabGroup.showServerName": "タブグループのタイトルにデータベース名と並んでサーバー名を表示",
|
||||
"settings.tabPreviewMode": "タブプレビューモード",
|
||||
"settings.theme": "テーマ",
|
||||
"settings.title": "設定",
|
||||
"settings.useNativeWindowTitle": "ネイティブウィンドウタイトルを使用",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "Pesquisar banco de dados",
|
||||
"command.database.disconnect": "Desconectar",
|
||||
"command.database.export": "Exportar banco de dados",
|
||||
"command.database.refresh": "Atualizar estrutura do BD",
|
||||
"command.database.refreshFull": "Atualizar estrutura do BD (completa)",
|
||||
"command.database.refreshIncremental": "Atualizar estrutura do BD (incremental)",
|
||||
"command.database.reopenConnection": "Reabrir conexão",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "Maiúsculas/minúsculas de comandos 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.tabPreviewMode": "Modo de visualização de aba",
|
||||
"settings.theme": "Temas",
|
||||
"settings.title": "Configurações",
|
||||
"settings.useNativeWindowTitle": "Usar título de janela nativo",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "Hľadanie v databáze",
|
||||
"command.database.disconnect": "Odpojiť",
|
||||
"command.database.export": "Exportovať databázu",
|
||||
"command.database.refresh": "Obnoviť štruktúru DB",
|
||||
"command.database.refreshFull": "Obnoviť štruktúru DB (úplne)",
|
||||
"command.database.refreshIncremental": "Obnoviť štruktúru DB (inkrementálne)",
|
||||
"command.database.reopenConnection": "Znovu otvoriť pripojenie",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "Veľkosť písmen",
|
||||
"settings.sqlEditor.title": "SQL editor",
|
||||
"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.title": "Nastavenia",
|
||||
"settings.useNativeWindowTitle": "Použiť natívne menu",
|
||||
|
||||
@@ -171,6 +171,7 @@
|
||||
"command.database.databaseSearch": "数据库搜索",
|
||||
"command.database.disconnect": "断开连接",
|
||||
"command.database.export": "导出数据库",
|
||||
"command.database.refresh": "刷新数据库结构",
|
||||
"command.database.refreshFull": "刷新数据库结构(完整)",
|
||||
"command.database.refreshIncremental": "刷新数据库结构(增量)",
|
||||
"command.database.reopenConnection": "重新打开连接",
|
||||
@@ -1198,6 +1199,7 @@
|
||||
"settings.sqlEditor.sqlCommandsCase": "SQL命令大小写",
|
||||
"settings.sqlEditor.title": "SQL 编辑器",
|
||||
"settings.tabGroup.showServerName": "在标签页组标题中显示服务器名称和数据库名称",
|
||||
"settings.tabPreviewMode": "标签页预览模式",
|
||||
"settings.theme": "主题",
|
||||
"settings.title": "设置",
|
||||
"settings.useNativeWindowTitle": "使用原生窗口标题",
|
||||
|
||||
@@ -7,7 +7,7 @@ checkout-and-merge-pro:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: 911941a53e91a5a777b8c7d455be0719234dde5f
|
||||
ref: ae1fcf6e61c6f7dfbb21005daa259c68e899a80a
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
Reference in New Issue
Block a user