Compare commits
93 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 106344b33e | |||
| 85a2a4b873 | |||
| 4ab694de0c | |||
| 5e193c1725 | |||
| 2b055c028c | |||
| 6ae381b1fd | |||
| 352b6cbe04 | |||
| e5e6d2701e | |||
| 9ad1924488 | |||
| 2aadbfc64a | |||
| 1c5d652f93 | |||
| b2355a3b2d | |||
| 6bd81cbff5 | |||
| b912190c5e | |||
| 43a826e2e5 | |||
| 8ae64a9dcf | |||
| 4ce9faf39b | |||
| d650d91d82 | |||
| d3322a4a15 | |||
| a65842e31f | |||
| 74fde66b51 | |||
| c3ea155a7b | |||
| c4b81e3d2c | |||
| 6f6ed1a741 | |||
| 311680c090 | |||
| 5e54aa553a | |||
| 6913970830 | |||
| 014e453e57 | |||
| 25b5341f76 | |||
| 1df51f9609 | |||
| 65d13189b3 | |||
| 0913011120 | |||
| 30ddc18eb1 | |||
| 697d755744 | |||
| e3f23ddc79 | |||
| 094acc40e8 | |||
| ebd4991de8 | |||
| d04a8fad4c | |||
| cb14bffc5a | |||
| a4c4d17381 | |||
| 21eb27f6e3 | |||
| abf0fc7942 | |||
| c2703edfde | |||
| d14b90ab20 | |||
| 48f4924932 | |||
| 765551988a | |||
| 4883eb0d1b | |||
| 06a9a93d1c | |||
| c92a0e1d43 | |||
| c6b5ee164b | |||
| c65075f887 | |||
| a1f678a3a1 | |||
| fe3fefaa4e | |||
| 3ccebcb0d1 | |||
| dbbae0eef2 | |||
| f11c4881f3 | |||
| 6398c6d7ce | |||
| 973ce8c3a7 | |||
| d971869283 | |||
| 987002b8f3 | |||
| f73fe495a5 | |||
| fe7b0e2bc7 | |||
| 23937c54e0 | |||
| b3d0fd9d2f | |||
| 497aaf6143 | |||
| 9d6db3a93b | |||
| 8a6f3e6809 | |||
| 6c419716a4 | |||
| d1a769205c | |||
| b784e342c9 | |||
| 0d82fd51c7 | |||
| 3b4d905485 | |||
| 53c63f0f4b | |||
| 5553e3cd8d | |||
| 1e195e07e0 | |||
| b6f0e15951 | |||
| da224303fe | |||
| 67ee130a9e | |||
| 18d908fa63 | |||
| c61f58854e | |||
| f789ecd2f1 | |||
| 1fdc30804a | |||
| 5ba10d0acb | |||
| 12803d8154 | |||
| 36c391ccff | |||
| 765fb6297c | |||
| 66255769ad | |||
| 04a8d38641 | |||
| 859d020031 | |||
| 3c541117d0 | |||
| 80ca2e5215 | |||
| 19f2aa2997 | |||
| ec657f30c7 |
@@ -43,7 +43,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
ref: 8df782559b84d6b59342c9488f3ca340074f35d6
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -43,7 +43,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
ref: 8df782559b84d6b59342c9488f3ca340074f35d6
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
ref: 8df782559b84d6b59342c9488f3ca340074f35d6
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -44,7 +44,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
ref: 8df782559b84d6b59342c9488f3ca340074f35d6
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
ref: 8df782559b84d6b59342c9488f3ca340074f35d6
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
ref: 8df782559b84d6b59342c9488f3ca340074f35d6
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -42,24 +42,6 @@ jobs:
|
||||
run: |
|
||||
cd packages/tools
|
||||
yarn test:ci
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: integration-tests/result.json
|
||||
action-name: Integration tests
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/filterparser/result.json
|
||||
action-name: Filter parser test results
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/datalib/result.json
|
||||
action-name: Datalib (perspectives) test results
|
||||
services:
|
||||
postgres-integr:
|
||||
image: postgres
|
||||
|
||||
@@ -24,6 +24,7 @@ docker/plugins
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.translation
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
|
||||
@@ -8,6 +8,19 @@ Builds:
|
||||
- linux - application for linux
|
||||
- win - application for Windows
|
||||
|
||||
## 6.7.1
|
||||
- ADDED: LANGUAGE environment variable for the web version. #1266
|
||||
- ADDED: New localizations (Italian, Portugese (Brazil), Japanese)
|
||||
- ADDED: Option to detect language from browser settings in web version
|
||||
- FIXED: Check updates option no longer available in 6.7.0 #1263
|
||||
- FIXED: A MERGE statement must be terminated by a semi-colon (;), but dbgate stripped it. #1257
|
||||
- ADDED: Show table size #552
|
||||
- ADDED: Sort tables by size and by row count
|
||||
- ADDED: Connect to Legacy MongoDB (Premium) #540
|
||||
- FIXED: Fixed problems in saving team files in Team Premium edition
|
||||
- CHANGED: Files are by default saved to team folders in Team Premium edition
|
||||
- ADDED: Other files types supported in Team Premium edition (diagrams, query design, perspectives, import/export jobs, shell scripts, database compare jobs)
|
||||
|
||||
## 6.7.0
|
||||
- ADDED: Added localization support, now you can use DbGate in multiple languages (French, Spanish, German, Czech, Slovak, Simplified Chinese) #347 #705 #939 #1079
|
||||
- CHANGED: Solved many issues with binary fields, huge performance improvements in binary fields processing
|
||||
|
||||
@@ -76,6 +76,8 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
|
||||
{ command: 'app.zoomIn', hideDisabled: true },
|
||||
{ command: 'app.zoomOut', hideDisabled: true },
|
||||
{ command: 'app.zoomReset', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'app.showLogs', hideDisabled: true },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -95,6 +97,8 @@ module.exports = ({ editMenu, isMac }, currentTranslations = null) => [
|
||||
{ divider: true },
|
||||
{ command: 'app.exportConnections', hideDisabled: true },
|
||||
{ command: 'app.importConnections', hideDisabled: true },
|
||||
{ divider: true },
|
||||
{ command: 'app.managePlugins', hideDisabled: true },
|
||||
],
|
||||
},
|
||||
...(isMac
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
require('dotenv').config({ path: '.env.translation' });
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const OpenAI = require('openai');
|
||||
|
||||
const client = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
|
||||
|
||||
const translationsDir = path.join(__dirname, '../../translations');
|
||||
const enFilePath = path.join(translationsDir, 'en.json');
|
||||
|
||||
const languageNames = {
|
||||
'cs.json': 'Czech',
|
||||
'de.json': 'German',
|
||||
'es.json': 'Spanish',
|
||||
'fr.json': 'French',
|
||||
'it.json': 'Italian',
|
||||
'ja.json': 'Japanese',
|
||||
'pt.json': 'Portuguese',
|
||||
'sk.json': 'Slovak',
|
||||
'zh.json': 'Chinese'
|
||||
};
|
||||
|
||||
// Read source (english)
|
||||
const enTranslations = JSON.parse(fs.readFileSync(enFilePath, 'utf8'));
|
||||
const enKeys = Object.keys(enTranslations);
|
||||
|
||||
// Get all translation files
|
||||
const translationFiles = fs.readdirSync(translationsDir)
|
||||
.filter(file => file.endsWith('.json') && file !== 'en.json')
|
||||
.sort();
|
||||
|
||||
console.log(`Found ${enKeys.length} keys in en.json\n`);
|
||||
console.log('='.repeat(80));
|
||||
|
||||
async function translateMissingIds({file, translations, missingIds}){
|
||||
const languageName = languageNames[file];
|
||||
if (!languageName) {
|
||||
console.log(`No language name mapping for file: ${file}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// Build object with only missing translations
|
||||
const needed = {};
|
||||
missingIds.forEach(key => {
|
||||
needed[key] = enTranslations[key];
|
||||
});
|
||||
|
||||
// Get all existing translations as style examples
|
||||
const existingTranslations = {};
|
||||
Object.keys(translations).forEach(key => {
|
||||
if (translations[key] && !translations[key].startsWith('***')) {
|
||||
existingTranslations[key] = {
|
||||
en: enTranslations[key],
|
||||
translated: translations[key]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const prompt = `You are a professional translator for DbGate, a database management application.
|
||||
|
||||
Translate the following English UI strings to ${languageName}.
|
||||
|
||||
IMPORTANT RULES:
|
||||
1. Preserve ALL placeholders exactly as they appear: {plugin}, {columnNumber}, {0}, {1}, etc.
|
||||
2. Maintain technical terminology appropriately for database software
|
||||
3. Match the translation style, tone, and formality of the existing translations shown below
|
||||
4. Keep the same level of brevity or verbosity as the existing translations
|
||||
5. Return ONLY valid JSON - no markdown, no explanations, no code blocks
|
||||
6. Use the same keys as provided
|
||||
|
||||
EXISTING TRANSLATIONS (for style reference):
|
||||
${JSON.stringify(existingTranslations, null, 2)}
|
||||
|
||||
STRINGS TO TRANSLATE:
|
||||
${JSON.stringify(needed, null, 2)}
|
||||
|
||||
Return format: {"key": "translated value", ...}`;
|
||||
|
||||
const response = await client.chat.completions.create({
|
||||
model: 'gpt-5.1',
|
||||
messages: [
|
||||
{ role: 'system', content: 'You are a professional translator specializing in software localization. Match the style and tone of existing translations. Return only valid JSON.' },
|
||||
{ role: 'user', content: prompt }
|
||||
],
|
||||
temperature: 0.2
|
||||
});
|
||||
|
||||
let translatedJson = response.choices[0].message.content.trim();
|
||||
|
||||
// Remove markdown code blocks if present
|
||||
translatedJson = translatedJson.replace(/^```json\n?/, '').replace(/\n?```$/, '');
|
||||
|
||||
return JSON.parse(translatedJson);
|
||||
}
|
||||
|
||||
(async () => {
|
||||
for (const file of translationFiles) {
|
||||
const filePath = path.join(translationsDir, file);
|
||||
const translations = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
||||
|
||||
const missingIds = enKeys.filter(key => !translations.hasOwnProperty(key) || (typeof translations[key] === 'string' && translations[key].startsWith('***')));
|
||||
|
||||
|
||||
console.log(`\n${file.toUpperCase()}`);
|
||||
console.log('-'.repeat(80));
|
||||
|
||||
if (missingIds.length === 0) {
|
||||
console.log('✓ All translations complete!');
|
||||
continue;
|
||||
} else {
|
||||
console.log(`Found ${missingIds.length} untranslated IDs\n`);
|
||||
}
|
||||
|
||||
const newTranslations = await translateMissingIds({file, translations, missingIds});
|
||||
|
||||
if (!newTranslations) {
|
||||
console.log(`Skipping file due to translation error: ${file}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const [key, value] of Object.entries(newTranslations)) {
|
||||
translations[key] = value;
|
||||
console.log(`Translated: ${key} => ${value}`);
|
||||
}
|
||||
|
||||
fs.writeFileSync(filePath, JSON.stringify(translations, null, 2) + '\n', 'utf8');
|
||||
console.log(`\n✓ Updated translations written to ${file}`);
|
||||
}
|
||||
|
||||
console.log('\n' + '='.repeat(80));
|
||||
console.log('Translation complete!\n');
|
||||
})();
|
||||
@@ -60,7 +60,7 @@ describe('Data browser data', () => {
|
||||
cy.contains('MyChinook').click();
|
||||
cy.testid('SqlObjectList_search').clear().type('album');
|
||||
cy.contains('Tables (1/11)');
|
||||
cy.contains('347 rows, InnoDB');
|
||||
cy.contains('347 rows, 65.5 KB, InnoDB');
|
||||
cy.testid('SqlObjectList_searchMenuDropDown').click();
|
||||
cy.contains('Column name').click();
|
||||
cy.contains('Tables (2/11)');
|
||||
|
||||
@@ -12,6 +12,7 @@ const {
|
||||
} = require('dbgate-tools');
|
||||
|
||||
function pickImportantTableInfo(engine, table) {
|
||||
if (!table) return table;
|
||||
const props = ['columnName', 'defaultValue'];
|
||||
if (!engine.skipNullability) props.push('notNull');
|
||||
if (!engine.skipAutoIncrement) props.push('autoIncrement');
|
||||
@@ -25,6 +26,13 @@ function pickImportantTableInfo(engine, table) {
|
||||
.map(props =>
|
||||
_.omitBy(props, (v, k) => k == 'defaultValue' && v == 'NULL' && engine.setNullDefaultInsteadOfDrop)
|
||||
),
|
||||
// foreignKeys: table.foreignKeys
|
||||
// .sort((a, b) => a.refTableName.localeCompare(b.refTableName))
|
||||
// .map(fk => ({
|
||||
// constraintType: fk.constraintType,
|
||||
// refTableName: fk.refTableName,
|
||||
// columns: fk.columns.map(col => ({ columnName: col.columnName, refColumnName: col.refColumnName })),
|
||||
// })),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,7 +41,7 @@ function checkTableStructure(engine, t1, t2) {
|
||||
expect(pickImportantTableInfo(engine, t1)).toEqual(pickImportantTableInfo(engine, t2));
|
||||
}
|
||||
|
||||
async function testTableDiff(engine, conn, driver, mangle) {
|
||||
async function testTableDiff(engine, conn, driver, mangle, changedTable = 't1') {
|
||||
const initQuery = formatQueryWithoutParams(driver, `create table ~t0 (~id int not null primary key)`);
|
||||
await driver.query(conn, transformSqlForEngine(engine, initQuery));
|
||||
|
||||
@@ -68,17 +76,38 @@ async function testTableDiff(engine, conn, driver, mangle) {
|
||||
await driver.query(conn, transformSqlForEngine(engine, query));
|
||||
}
|
||||
|
||||
const tget = x => x.tables.find(y => y.pureName == 't1');
|
||||
const structure1 = generateDbPairingId(extendDatabaseInfo(await driver.analyseFull(conn)));
|
||||
if (!engine.skipReferences) {
|
||||
const query = formatQueryWithoutParams(
|
||||
driver,
|
||||
`create table ~t3 (~id int not null primary key, ~fkval int ${
|
||||
driver.dialect.implicitNullDeclaration ? '' : 'null'
|
||||
})`
|
||||
);
|
||||
|
||||
await driver.query(conn, transformSqlForEngine(engine, query));
|
||||
}
|
||||
|
||||
const tget = x => x?.tables?.find(y => y.pureName == changedTable);
|
||||
const structure1Source = await driver.analyseFull(conn);
|
||||
const structure1 = generateDbPairingId(extendDatabaseInfo(structure1Source));
|
||||
let structure2 = _.cloneDeep(structure1);
|
||||
mangle(tget(structure2));
|
||||
structure2 = extendDatabaseInfo(structure2);
|
||||
|
||||
const { sql } = getAlterTableScript(tget(structure1), tget(structure2), {}, structure1, structure2, driver);
|
||||
|
||||
// sleep 1s - some engines have update datetime precision only to seconds
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
|
||||
console.log('RUNNING ALTER SQL', driver.engine, ':', sql);
|
||||
|
||||
await driver.script(conn, sql);
|
||||
|
||||
// if (!engine.skipIncrementalAnalysis) {
|
||||
// const structure2RealIncremental = await driver.analyseIncremental(conn, structure1Source);
|
||||
// checkTableStructure(engine, tget(structure2RealIncremental), tget(structure2));
|
||||
// }
|
||||
|
||||
const structure2Real = extendDatabaseInfo(await driver.analyseFull(conn));
|
||||
|
||||
checkTableStructure(engine, tget(structure2Real), tget(structure2));
|
||||
@@ -214,6 +243,48 @@ describe('Alter table', () => {
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
|
||||
'Drop FK - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(
|
||||
engine,
|
||||
conn,
|
||||
driver,
|
||||
tbl => {
|
||||
tbl.foreignKeys = [];
|
||||
},
|
||||
't2'
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
test.each(engines.filter(x => !x.skipReferences).map(engine => [engine.label, engine]))(
|
||||
'Create FK - %s',
|
||||
testWrapper(async (conn, driver, engine) => {
|
||||
await testTableDiff(
|
||||
engine,
|
||||
conn,
|
||||
driver,
|
||||
tbl => {
|
||||
tbl.foreignKeys = [
|
||||
{
|
||||
constraintType: 'foreignKey',
|
||||
pureName: 't3',
|
||||
refTableName: 't1',
|
||||
columns: [
|
||||
{
|
||||
columnName: 'fkval',
|
||||
refColumnName: 'col_ref',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
},
|
||||
't3'
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
// test.each(engines.map(engine => [engine.label, engine]))(
|
||||
// 'Change autoincrement - %s',
|
||||
// testWrapper(async (conn, driver, engine) => {
|
||||
|
||||
@@ -28,12 +28,14 @@ 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);
|
||||
expect(structure2).toBeNull();
|
||||
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();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
@@ -48,10 +50,12 @@ 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();
|
||||
expect(structure2).toBeNull();
|
||||
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();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -187,6 +187,7 @@ const mariaDbEngine = {
|
||||
/** @type {import('dbgate-types').TestEngineInfo} */
|
||||
const postgreSqlEngine = {
|
||||
label: 'PostgreSQL',
|
||||
skipIncrementalAnalysis: true,
|
||||
connection: {
|
||||
engine: 'postgres@dbgate-plugin-postgres',
|
||||
password: 'Pwd2020Db',
|
||||
@@ -757,11 +758,11 @@ const enginesOnCi = [
|
||||
const enginesOnLocal = [
|
||||
// all engines, which would be run on local test
|
||||
// cassandraEngine,
|
||||
//mysqlEngine,
|
||||
// mysqlEngine,
|
||||
// mariaDbEngine,
|
||||
//postgreSqlEngine,
|
||||
postgreSqlEngine,
|
||||
//sqlServerEngine,
|
||||
sqliteEngine,
|
||||
// sqliteEngine,
|
||||
// cockroachDbEngine,
|
||||
// clickhouseEngine,
|
||||
// libsqlFileEngine,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
module.exports = {
|
||||
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"cross-env": "^7.0.3",
|
||||
"jest": "^27.0.1",
|
||||
"jest": "^28.1.3",
|
||||
"pino-pretty": "^11.2.2",
|
||||
"tmp": "^0.2.3"
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"version": "6.7.1-premium-beta.3",
|
||||
"version": "6.7.2-premium-beta.2",
|
||||
"name": "dbgate-all",
|
||||
"workspaces": [
|
||||
"packages/*",
|
||||
|
||||
@@ -71,6 +71,7 @@ module.exports = {
|
||||
const isLicenseValid = checkedLicense?.status == 'ok';
|
||||
const logoutUrl = storageConnectionError ? null : await authProvider.getLogoutUrl();
|
||||
const adminConfig = storageConnectionError ? null : await storage.readConfig({ group: 'admin' });
|
||||
const settingsConfig = storageConnectionError ? null : await storage.readConfig({ group: 'settings' });
|
||||
|
||||
storage.startRefreshLicense();
|
||||
|
||||
@@ -121,6 +122,7 @@ module.exports = {
|
||||
allowPrivateCloud: platformInfo.isElectron || !!process.env.ALLOW_DBGATE_PRIVATE_CLOUD,
|
||||
...currentVersion,
|
||||
redirectToDbGateCloudLogin: !!process.env.REDIRECT_TO_DBGATE_CLOUD_LOGIN,
|
||||
preferrendLanguage: settingsConfig?.['storage.language'] || process.env.LANGUAGE || null,
|
||||
};
|
||||
|
||||
return configResult;
|
||||
|
||||
@@ -1533,6 +1533,12 @@ module.exports = {
|
||||
"columnName": "name",
|
||||
"dataType": "varchar(250)",
|
||||
"notNull": true
|
||||
},
|
||||
{
|
||||
"pureName": "team_file_types",
|
||||
"columnName": "format",
|
||||
"dataType": "varchar(50)",
|
||||
"notNull": false
|
||||
}
|
||||
],
|
||||
"foreignKeys": [],
|
||||
@@ -1549,7 +1555,38 @@ module.exports = {
|
||||
"preloadedRows": [
|
||||
{
|
||||
"id": -1,
|
||||
"name": "sql"
|
||||
"name": "sql",
|
||||
"format": "text"
|
||||
},
|
||||
{
|
||||
"id": -2,
|
||||
"name": "diagrams",
|
||||
"format": "json"
|
||||
},
|
||||
{
|
||||
"id": -3,
|
||||
"name": "query",
|
||||
"format": "json"
|
||||
},
|
||||
{
|
||||
"id": -4,
|
||||
"name": "perspectives",
|
||||
"format": "json"
|
||||
},
|
||||
{
|
||||
"id": -5,
|
||||
"name": "impexp",
|
||||
"format": "json"
|
||||
},
|
||||
{
|
||||
"id": -6,
|
||||
"name": "shell",
|
||||
"format": "text"
|
||||
},
|
||||
{
|
||||
"id": -7,
|
||||
"name": "dbcompare",
|
||||
"format": "json"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -2,4 +2,5 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleFileExtensions: ['js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
@@ -35,6 +35,12 @@ program
|
||||
.option('-u, --user <user>', 'user name')
|
||||
.option('-p, --password <password>', 'password')
|
||||
.option('-d, --database <database>', 'database name')
|
||||
.option('--url <url>', 'database url')
|
||||
.option('--file <file>', 'database file')
|
||||
.option('--socket-path <socketPath>', 'socket path')
|
||||
.option('--service-name <serviceName>', 'service name (for Oracle)')
|
||||
.option('--auth-type <authType>', 'authentication type')
|
||||
.option('--use-ssl', 'use SSL connection')
|
||||
.option('--auto-index-foreign-keys', 'automatically adds indexes to all foreign keys')
|
||||
.option(
|
||||
'--load-data-condition <condition>',
|
||||
@@ -48,7 +54,7 @@ program
|
||||
.command('deploy <modelFolder>')
|
||||
.description('Deploys model to database')
|
||||
.action(modelFolder => {
|
||||
const { engine, server, user, password, database, transaction } = program.opts();
|
||||
const { engine, server, user, password, database, url, file, transaction } = program.opts();
|
||||
// const hooks = [];
|
||||
// if (program.autoIndexForeignKeys) hooks.push(dbmodel.hooks.autoIndexForeignKeys);
|
||||
|
||||
@@ -60,6 +66,13 @@ program
|
||||
user,
|
||||
password,
|
||||
database,
|
||||
databaseUrl: url,
|
||||
useDatabaseUrl: !!url,
|
||||
databaseFile: file,
|
||||
socketPath: program.socketPath,
|
||||
serviceName: program.serviceName,
|
||||
authType: program.authType,
|
||||
useSsl: program.useSsl,
|
||||
},
|
||||
modelFolder,
|
||||
useTransaction: transaction,
|
||||
|
||||
@@ -2,4 +2,5 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleFileExtensions: ['js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { SqlDumper } from 'dbgate-types';
|
||||
import { Command, Select, Update, Delete, Insert } from './types';
|
||||
import { dumpSqlExpression } from './dumpSqlExpression';
|
||||
import { dumpSqlFromDefinition, dumpSqlSourceRef } from './dumpSqlSource';
|
||||
import { dumpSqlFromDefinition, dumpSqlSourceDef, dumpSqlSourceRef } from './dumpSqlSource';
|
||||
import { dumpSqlCondition } from './dumpSqlCondition';
|
||||
|
||||
export function dumpSqlSelect(dmp: SqlDumper, cmd: Select) {
|
||||
@@ -115,7 +115,10 @@ export function dumpSqlInsert(dmp: SqlDumper, cmd: Insert) {
|
||||
cmd.fields.map(x => x.targetColumn)
|
||||
);
|
||||
dmp.putCollection(',', cmd.fields, x => dumpSqlExpression(dmp, x));
|
||||
if (dmp.dialect.requireFromDual) {
|
||||
if (cmd.whereNotExistsSource) {
|
||||
dmp.put(' ^from ');
|
||||
dumpSqlSourceDef(dmp, cmd.whereNotExistsSource);
|
||||
} else if (dmp.dialect.requireFromDual) {
|
||||
dmp.put(' ^from ^dual ');
|
||||
}
|
||||
dmp.put(' ^where ^not ^exists (^select * ^from %f ^where ', cmd.targetTable);
|
||||
|
||||
@@ -2,6 +2,7 @@ import _ from 'lodash';
|
||||
import type { SqlDumper } from 'dbgate-types';
|
||||
import { Expression, ColumnRefExpression } from './types';
|
||||
import { dumpSqlSourceRef } from './dumpSqlSource';
|
||||
import { dumpSqlSelect } from './dumpSqlCommand';
|
||||
|
||||
export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) {
|
||||
switch (expr.exprType) {
|
||||
@@ -67,5 +68,11 @@ export function dumpSqlExpression(dmp: SqlDumper, expr: Expression) {
|
||||
});
|
||||
dmp.put(')');
|
||||
break;
|
||||
|
||||
case 'select':
|
||||
dmp.put('(');
|
||||
dumpSqlSelect(dmp, expr.select);
|
||||
dmp.put(')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ export interface Insert {
|
||||
fields: UpdateField[];
|
||||
targetTable: NamedObjectInfo;
|
||||
insertWhereNotExistsCondition?: Condition;
|
||||
whereNotExistsSource?: Source;
|
||||
}
|
||||
|
||||
export interface AllowIdentityInsert {
|
||||
@@ -226,6 +227,11 @@ export interface RowNumberExpression {
|
||||
orderBy: OrderByExpression[];
|
||||
}
|
||||
|
||||
export interface SelectExpression {
|
||||
exprType: 'select';
|
||||
select: Select;
|
||||
}
|
||||
|
||||
export type Expression =
|
||||
| ColumnRefExpression
|
||||
| ValueExpression
|
||||
@@ -235,7 +241,8 @@ export type Expression =
|
||||
| CallExpression
|
||||
| MethodCallExpression
|
||||
| TranformExpression
|
||||
| RowNumberExpression;
|
||||
| RowNumberExpression
|
||||
| SelectExpression;
|
||||
export type OrderByExpression = Expression & { direction: 'ASC' | 'DESC' };
|
||||
|
||||
export type ResultField = Expression & { alias?: string };
|
||||
|
||||
@@ -2,4 +2,5 @@ module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
moduleFileExtensions: ['js'],
|
||||
reporters: ['default', 'github-actions'],
|
||||
};
|
||||
|
||||
Vendored
+1
@@ -16,6 +16,7 @@ export interface SqlDumper extends AlterProcessor {
|
||||
transform(type: TransformType, dumpExpr: () => void);
|
||||
createDatabase(name: string);
|
||||
dropDatabase(name: string);
|
||||
comment(value: string);
|
||||
|
||||
callableTemplate(func: CallableObjectInfo);
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
initializeAppUpdates();
|
||||
installCloudListeners();
|
||||
refreshPublicCloudFiles();
|
||||
saveSelectedLanguageToCache();
|
||||
saveSelectedLanguageToCache(config.preferrendLanguage);
|
||||
|
||||
const electron = getElectron();
|
||||
if (electron) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts" context="module">
|
||||
import { copyTextToClipboard } from '../utility/clipboard';
|
||||
import { _t, _tval, DefferedTranslationResult } from '../translations';
|
||||
import sqlFormatter from 'sql-formatter';
|
||||
|
||||
export const extractKey = ({ schemaName, pureName }) => (schemaName ? `${schemaName}.${pureName}` : pureName);
|
||||
export const createMatcher =
|
||||
@@ -88,7 +89,8 @@
|
||||
isRename?: boolean;
|
||||
isTruncate?: boolean;
|
||||
isCopyTableName?: boolean;
|
||||
isDuplicateTable?: boolean;
|
||||
isTableBackup?: boolean;
|
||||
isTableRestore?: boolean;
|
||||
isDiagram?: boolean;
|
||||
functionName?: string;
|
||||
isExport?: boolean;
|
||||
@@ -106,6 +108,8 @@
|
||||
}
|
||||
|
||||
function createMenusCore(objectTypeField, driver, data): DbObjMenuItem[] {
|
||||
const backupMatch = data.objectTypeField === 'tables' ? data.pureName.match(TABLE_BACKUP_REGEX) : null;
|
||||
|
||||
switch (objectTypeField) {
|
||||
case 'tables':
|
||||
return [
|
||||
@@ -175,11 +179,18 @@
|
||||
isCopyTableName: true,
|
||||
requiresWriteAccess: false,
|
||||
},
|
||||
hasPermission('dbops/table/backup') && {
|
||||
label: _t('dbObject.createTableBackup', { defaultMessage: 'Create table backup' }),
|
||||
isDuplicateTable: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/table/backup') &&
|
||||
!backupMatch && {
|
||||
label: _t('dbObject.createTableBackup', { defaultMessage: 'Create table backup' }),
|
||||
isTableBackup: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/table/restore') &&
|
||||
backupMatch && {
|
||||
label: _t('dbObject.createRestoreScript', { defaultMessage: 'Create restore script' }),
|
||||
isTableRestore: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
hasPermission('dbops/model/view') && {
|
||||
label: _t('dbObject.showDiagram', { defaultMessage: 'Show diagram' }),
|
||||
isDiagram: true,
|
||||
@@ -637,7 +648,7 @@
|
||||
});
|
||||
},
|
||||
});
|
||||
} else if (menu.isDuplicateTable) {
|
||||
} else if (menu.isTableBackup) {
|
||||
const driver = await getDriver();
|
||||
const dmp = driver.createDumper();
|
||||
const newTable = _.cloneDeep(data);
|
||||
@@ -671,6 +682,25 @@
|
||||
},
|
||||
engine: driver.engine,
|
||||
});
|
||||
} else if (menu.isTableRestore) {
|
||||
const backupMatch = data.objectTypeField === 'tables' ? data.pureName.match(TABLE_BACKUP_REGEX) : null;
|
||||
|
||||
const driver = await getDriver();
|
||||
const dmp = driver.createDumper();
|
||||
const db = await getDatabaseInfo(data);
|
||||
if (db) {
|
||||
const originalTable = db?.tables?.find(x => x.pureName == backupMatch[1] && x.schemaName == data.schemaName);
|
||||
if (originalTable) {
|
||||
createTableRestoreScript(data, originalTable, dmp);
|
||||
newQuery({
|
||||
title: _t('dbObject.restoreScript', {
|
||||
defaultMessage: 'Restore {name} #',
|
||||
values: { name: backupMatch[1] },
|
||||
}),
|
||||
initialData: sqlFormatter.format(dmp.s),
|
||||
});
|
||||
}
|
||||
}
|
||||
} else if (menu.isImport) {
|
||||
const { conid, database } = data;
|
||||
openImportExportTab({
|
||||
@@ -1008,6 +1038,8 @@
|
||||
|
||||
return handleDatabaseObjectClick(data, { forceNewTab, tabPreviewMode, focusTab });
|
||||
}
|
||||
|
||||
export const TABLE_BACKUP_REGEX = /^_(.*)_(\d\d\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)-(\d\d)$/;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
@@ -1025,7 +1057,7 @@
|
||||
} from '../stores';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import { extractDbNameFromComposite, filterNameCompoud, getConnectionLabel } from 'dbgate-tools';
|
||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||
import { getConnectionInfo, getDatabaseInfo } from '../utility/metadataLoaders';
|
||||
import fullDisplayName from '../utility/fullDisplayName';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import { findEngineDriver } from 'dbgate-tools';
|
||||
@@ -1047,6 +1079,8 @@
|
||||
import { getBoolSettingsValue, getOpenDetailOnArrowsSettings } from '../settings/settingsTools';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import formatFileSize from '../utility/formatFileSize';
|
||||
import { createTableRestoreScript } from '../utility/tableRestoreScript';
|
||||
import newQuery from '../query/newQuery';
|
||||
|
||||
export let data;
|
||||
export let passProps;
|
||||
@@ -1086,14 +1120,21 @@
|
||||
}
|
||||
|
||||
$: isPinned = !!$pinnedTables.find(x => testEqual(data, x));
|
||||
|
||||
$: backupParsed = data.objectTypeField === 'tables' ? data.pureName.match(TABLE_BACKUP_REGEX) : null;
|
||||
$: backupTitle =
|
||||
backupParsed != null
|
||||
? `${backupParsed[1]} (${backupParsed[2]}-${backupParsed[3]}-${backupParsed[4]} ${backupParsed[5]}:${backupParsed[6]}:${backupParsed[7]})`
|
||||
: null;
|
||||
</script>
|
||||
|
||||
<AppObjectCore
|
||||
{...$$restProps}
|
||||
module={$$props.module}
|
||||
{data}
|
||||
title={data.schemaName && !passProps?.hideSchemaName ? `${data.schemaName}.${data.pureName}` : data.pureName}
|
||||
icon={databaseObjectIcons[data.objectTypeField]}
|
||||
title={backupTitle ??
|
||||
(data.schemaName && !passProps?.hideSchemaName ? `${data.schemaName}.${data.pureName}` : data.pureName)}
|
||||
icon={backupParsed ? 'img table-backup' : databaseObjectIcons[data.objectTypeField]}
|
||||
menu={createMenu}
|
||||
showPinnedInsteadOfUnpin={passProps?.showPinnedInsteadOfUnpin}
|
||||
onPin={passProps?.ingorePin ? null : isPinned ? null : () => pinnedTables.update(list => [...list, data])}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import getElectron from '../utility/getElectron';
|
||||
import InlineButtonLabel from '../buttons/InlineButtonLabel.svelte';
|
||||
import resolveApi, { resolveApiHeaders } from '../utility/resolveApi';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import uuidv1 from 'uuid/v1';
|
||||
|
||||
@@ -49,11 +50,11 @@
|
||||
</script>
|
||||
|
||||
{#if electron}
|
||||
<InlineButton on:click={handleOpenElectronFile} title="Open file" data-testid={$$props['data-testid']}>
|
||||
<InlineButton on:click={handleOpenElectronFile} title={_t('files.openFile', { defaultMessage: "Open file" })} data-testid={$$props['data-testid']}>
|
||||
<FontIcon {icon} />
|
||||
</InlineButton>
|
||||
{:else}
|
||||
<InlineButtonLabel on:click={() => {}} title="Upload file" data-testid={$$props['data-testid']} htmlFor={inputId}>
|
||||
<InlineButtonLabel on:click={() => {}} title={_t('files.uploadFile', { defaultMessage: "Upload file" })} data-testid={$$props['data-testid']} htmlFor={inputId}>
|
||||
<FontIcon {icon} />
|
||||
</InlineButtonLabel>
|
||||
{/if}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import FormStyledButtonLikeLabel from '../buttons/FormStyledButtonLikeLabel.svelte';
|
||||
import uploadFiles from '../utility/uploadFiles';
|
||||
import { _t } from '../translations';
|
||||
|
||||
const handleChange = e => {
|
||||
const files = [...e.target.files];
|
||||
@@ -9,6 +10,6 @@
|
||||
</script>
|
||||
|
||||
<div class="m-1">
|
||||
<FormStyledButtonLikeLabel htmlFor="uploadFileButton">Upload file</FormStyledButtonLikeLabel>
|
||||
<FormStyledButtonLikeLabel htmlFor="uploadFileButton">{_t('files.uploadFile', { defaultMessage: "Upload file" })}</FormStyledButtonLikeLabel>
|
||||
<input type="file" id="uploadFileButton" hidden on:change={handleChange} />
|
||||
</div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { currentDatabase, getCurrentDatabase } from '../stores';
|
||||
import getElectron from '../utility/getElectron';
|
||||
import registerCommand from './registerCommand';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { switchCurrentDatabase } from '../utility/common';
|
||||
import { getDatabasStatusMenu, switchCurrentDatabase } from '../utility/common';
|
||||
import { __t } from '../translations';
|
||||
|
||||
registerCommand({
|
||||
@@ -18,33 +18,7 @@ registerCommand({
|
||||
conid: connection._id,
|
||||
database: name,
|
||||
};
|
||||
return [
|
||||
{
|
||||
text: 'Sync model (incremental)',
|
||||
onClick: () => {
|
||||
apiCall('database-connections/sync-model', dbid);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Sync model (full)',
|
||||
onClick: () => {
|
||||
apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true });
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Reopen',
|
||||
onClick: () => {
|
||||
apiCall('database-connections/refresh', dbid);
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Disconnect',
|
||||
onClick: () => {
|
||||
const electron = getElectron();
|
||||
if (electron) apiCall('database-connections/disconnect', dbid);
|
||||
switchCurrentDatabase(null);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
return getDatabasStatusMenu(dbid);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -11,11 +11,11 @@ import {
|
||||
promoWidgetPreview,
|
||||
visibleToolbar,
|
||||
visibleWidgetSideBar,
|
||||
selectedWidget,
|
||||
} from '../stores';
|
||||
import registerCommand from './registerCommand';
|
||||
import { get } from 'svelte/store';
|
||||
import AboutModal from '../modals/AboutModal.svelte';
|
||||
import SettingsModal from '../settings/SettingsModal.svelte';
|
||||
import SqlGeneratorModal from '../modals/SqlGeneratorModal.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import newQuery, { newDiagram, newPerspective, newQueryDesign } from '../query/newQuery';
|
||||
@@ -73,7 +73,14 @@ registerCommand({
|
||||
category: __t('command.theme', { defaultMessage: 'Theme' }),
|
||||
name: __t('command.theme.change', { defaultMessage: 'Change' }),
|
||||
toolbarName: __t('command.theme.changeToolbar', { defaultMessage: 'Change theme' }),
|
||||
onClick: () => showModal(SettingsModal, { selectedTab: 'theme' }),
|
||||
onClick: () => openNewTab({
|
||||
title: 'Settings',
|
||||
icon: 'icon settings',
|
||||
tabComponent: 'SettingsTab',
|
||||
props: {
|
||||
selectedItem: 'theme',
|
||||
},
|
||||
}),
|
||||
// getSubCommands: () => get(extensions).themes.map(themeCommand),
|
||||
});
|
||||
|
||||
@@ -115,13 +122,13 @@ registerCommand({
|
||||
toolbar: true,
|
||||
icon: 'icon new-connection',
|
||||
toolbarName: __t('command.new.connection', { defaultMessage: 'Add connection' }),
|
||||
category: __t('command.new', { defaultMessage: 'New'}),
|
||||
category: __t('command.new', { defaultMessage: 'New' }),
|
||||
toolbarOrder: 1,
|
||||
name: __t('command.new.connection', { defaultMessage: 'Connection' }),
|
||||
testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase,
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'New Connection',
|
||||
title: _t('common.newConnection', { defaultMessage: 'New Connection' }),
|
||||
icon: 'img connection',
|
||||
tabComponent: 'ConnectionTab',
|
||||
});
|
||||
@@ -140,7 +147,7 @@ registerCommand({
|
||||
!getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase && !!getCloudSigninTokenHolder(),
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'New Connection on Cloud',
|
||||
title: _t('common.newConnectionCloud', { defaultMessage: 'New Connection on Cloud' }),
|
||||
icon: 'img cloud-connection',
|
||||
tabComponent: 'ConnectionTab',
|
||||
props: {
|
||||
@@ -561,7 +568,10 @@ registerCommand({
|
||||
testEnabled: () => true,
|
||||
onClick: () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: _t('command.file.resetLayoutConfirm', { defaultMessage: 'Really reset layout data? All opened tabs, settings and layout data will be lost. Connections and saved files will be preserved. After this, restart DbGate for applying changes.' }),
|
||||
message: _t('command.file.resetLayoutConfirm', {
|
||||
defaultMessage:
|
||||
'Really reset layout data? All opened tabs, settings and layout data will be lost. Connections and saved files will be preserved. After this, restart DbGate for applying changes.',
|
||||
}),
|
||||
onConfirm: async () => {
|
||||
await apiCall('config/delete-settings');
|
||||
localStorage.clear();
|
||||
@@ -665,7 +675,9 @@ registerCommand({
|
||||
'currentArchive',
|
||||
];
|
||||
for (const key of keys) removeLocalStorage(key);
|
||||
showSnackbarSuccess(_t('command.view.restart', { defaultMessage: 'Restart DbGate (or reload on web) for applying changes' }));
|
||||
showSnackbarSuccess(
|
||||
_t('command.view.restart', { defaultMessage: 'Restart DbGate (or reload on web) for applying changes' })
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -762,6 +774,19 @@ if (isProApp()) {
|
||||
}
|
||||
|
||||
if (hasPermission('settings/change')) {
|
||||
registerCommand({
|
||||
id: 'settings.settingsTab',
|
||||
category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
name: __t('command.settings.settingsTab', { defaultMessage: 'Settings tab' }),
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: _t('command.settings.settingsTab', { defaultMessage: 'Settings tab' }),
|
||||
icon: 'icon settings',
|
||||
tabComponent: 'SettingsTab',
|
||||
props: {},
|
||||
});
|
||||
},
|
||||
});
|
||||
registerCommand({
|
||||
id: 'settings.commands',
|
||||
category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
@@ -777,14 +802,14 @@ if (hasPermission('settings/change')) {
|
||||
testEnabled: () => hasPermission('settings/change'),
|
||||
});
|
||||
|
||||
registerCommand({
|
||||
id: 'settings.show',
|
||||
category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
name: __t('command.settings.change', { defaultMessage: 'Change' }),
|
||||
toolbarName: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
onClick: () => showModal(SettingsModal),
|
||||
testEnabled: () => hasPermission('settings/change'),
|
||||
});
|
||||
// registerCommand({
|
||||
// id: 'settings.show',
|
||||
// category: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
// name: __t('command.settings.change', { defaultMessage: 'Change' }),
|
||||
// toolbarName: __t('command.settings', { defaultMessage: 'Settings' }),
|
||||
// onClick: () => showModal(SettingsModal),
|
||||
// testEnabled: () => hasPermission('settings/change'),
|
||||
// });
|
||||
}
|
||||
|
||||
registerCommand({
|
||||
@@ -799,7 +824,9 @@ registerCommand({
|
||||
registerCommand({
|
||||
id: 'file.exit',
|
||||
category: __t('command.file', { defaultMessage: 'File' }),
|
||||
name: isMac() ? __t('command.file.quit', { defaultMessage: 'Quit' }) : __t('command.file.exit', { defaultMessage: 'Exit' }),
|
||||
name: isMac()
|
||||
? __t('command.file.quit', { defaultMessage: 'Quit' })
|
||||
: __t('command.file.exit', { defaultMessage: 'Exit' }),
|
||||
// keyText: isMac() ? 'Command+Q' : null,
|
||||
testEnabled: () => getElectron() != null,
|
||||
onClick: () => getElectron().send('quit-app'),
|
||||
@@ -862,6 +889,7 @@ export function registerFileCommands({
|
||||
undoRedo = false,
|
||||
executeAdditionalCondition = null,
|
||||
copyPaste = false,
|
||||
defaultTeamFolder = false,
|
||||
}) {
|
||||
if (save) {
|
||||
registerCommand({
|
||||
@@ -874,7 +902,7 @@ export function registerFileCommands({
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save', folder, format, fileExtension),
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save', folder, format, fileExtension, defaultTeamFolder),
|
||||
});
|
||||
registerCommand({
|
||||
id: idPrefix + '.saveAs',
|
||||
@@ -882,14 +910,14 @@ export function registerFileCommands({
|
||||
category,
|
||||
name: __t('command.saveAs', { defaultMessage: 'Save As' }),
|
||||
testEnabled: () => getCurrentEditor() != null,
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save-as', folder, format, fileExtension),
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save-as', folder, format, fileExtension, defaultTeamFolder),
|
||||
});
|
||||
registerCommand({
|
||||
id: idPrefix + '.saveToDisk',
|
||||
category,
|
||||
name: __t('command.saveToDisk', { defaultMessage: 'Save to disk' }),
|
||||
testEnabled: () => getCurrentEditor() != null && getElectron() != null,
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save-to-disk', folder, format, fileExtension),
|
||||
onClick: () => saveTabFile(getCurrentEditor(), 'save-to-disk', folder, format, fileExtension, defaultTeamFolder),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1202,6 +1230,35 @@ registerCommand({
|
||||
},
|
||||
});
|
||||
|
||||
if ( hasPermission('application-log'))
|
||||
{
|
||||
registerCommand({
|
||||
id: 'app.showLogs',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.showLogs', { defaultMessage: 'View application logs' }),
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'Application log',
|
||||
icon: 'img applog',
|
||||
tabComponent: 'AppLogTab',
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (hasPermission('widgets/plugins'))
|
||||
{
|
||||
registerCommand({
|
||||
id: 'app.managePlugins',
|
||||
category: __t('command.application', { defaultMessage: 'Application' }),
|
||||
name: __t('command.application.managePlugins', { defaultMessage: 'Manage plugins' }),
|
||||
onClick: () => {
|
||||
selectedWidget.set('plugins');
|
||||
visibleWidgetSideBar.set(true);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const electron = getElectron();
|
||||
if (electron) {
|
||||
electron.addEventListener('run-command', (e, commandId) => runCommand(commandId));
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
import moveDrag from '../utility/moveDrag';
|
||||
import ColumnLine from './ColumnLine.svelte';
|
||||
import DomTableRef from './DomTableRef';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
@@ -185,8 +186,8 @@
|
||||
const handleSetTableAlias = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: alias || '',
|
||||
label: 'New alias',
|
||||
header: 'Set table alias',
|
||||
label: _t('designerTable.newAlias', { defaultMessage: 'New alias' }),
|
||||
header: _t('designerTable.setTableAlias', { defaultMessage: 'Set table alias' }),
|
||||
onConfirm: newAlias => {
|
||||
onChangeTable({
|
||||
...table,
|
||||
@@ -210,13 +211,13 @@
|
||||
return settings?.tableMenu({ designer, designerId, onRemoveTable });
|
||||
}
|
||||
return [
|
||||
{ text: 'Remove', onClick: () => onRemoveTable({ designerId }) },
|
||||
{ text: _t('common.remove', { defaultMessage: 'Remove' }), onClick: () => onRemoveTable({ designerId }) },
|
||||
{ divider: true },
|
||||
settings?.allowTableAlias &&
|
||||
!isMultipleTableSelection && [
|
||||
{ text: 'Set table alias', onClick: handleSetTableAlias },
|
||||
{ text: _t('designerTable.setTableAlias', { defaultMessage: 'Set table alias' }), onClick: handleSetTableAlias },
|
||||
alias && {
|
||||
text: 'Remove table alias',
|
||||
text: _t('designerTable.removeTableAlias', { defaultMessage: 'Remove table alias' }),
|
||||
onClick: () =>
|
||||
onChangeTable({
|
||||
...table,
|
||||
@@ -225,11 +226,11 @@
|
||||
},
|
||||
],
|
||||
settings?.allowAddAllReferences &&
|
||||
!isMultipleTableSelection && { text: 'Add references', onClick: () => onAddAllReferences(table) },
|
||||
settings?.allowChangeColor && { text: 'Change color', onClick: () => onChangeTableColor(table) },
|
||||
!isMultipleTableSelection && { text: _t('designerTable.addReferences', { defaultMessage: 'Add references' }), onClick: () => onAddAllReferences(table) },
|
||||
settings?.allowChangeColor && { text: _t('designerTable.changeColor', { defaultMessage: 'Change color' }), onClick: () => onChangeTableColor(table) },
|
||||
settings?.allowDefineVirtualReferences &&
|
||||
!isMultipleTableSelection && {
|
||||
text: 'Define virtual foreign key',
|
||||
text: _t('designerTable.defineVirtualForeignKey', { defaultMessage: 'Define virtual foreign key' }),
|
||||
onClick: () => handleDefineVirtualForeignKey(table),
|
||||
},
|
||||
settings?.appendTableSystemMenu &&
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import HorizontalSplitter from './HorizontalSplitter.svelte';
|
||||
|
||||
interface MenuItemDef {
|
||||
label: string;
|
||||
slot?: number;
|
||||
component?: any;
|
||||
props?: any;
|
||||
testid?: string;
|
||||
identifier?: string;
|
||||
}
|
||||
|
||||
export let items: MenuItemDef[];
|
||||
export let value: string | number = 0;
|
||||
export let containerMaxWidth = undefined;
|
||||
export let containerMaxHeight = undefined;
|
||||
export let flex1 = true;
|
||||
export let flexColContainer = false;
|
||||
export let maxHeight100 = false;
|
||||
export let scrollableContentContainer = false;
|
||||
export let contentTestId = undefined;
|
||||
export let onUserChange = null;
|
||||
|
||||
export function setValue(index) {
|
||||
value = index;
|
||||
}
|
||||
export function getValue() {
|
||||
return value;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="main" class:maxHeight100 class:flex1>
|
||||
<HorizontalSplitter initialValue="20%">
|
||||
<svelte:fragment slot="1">
|
||||
<div class="menu">
|
||||
{#each _.compact(items) as item, index}
|
||||
<div
|
||||
class="menu-item"
|
||||
class:selected={value == (item.identifier ?? index)}
|
||||
on:click={() => {
|
||||
value = item.identifier ?? index;
|
||||
onUserChange?.(item.identifier ?? index);
|
||||
}}
|
||||
data-testid={item.testid}
|
||||
>
|
||||
<span class="ml-2 noselect">
|
||||
{item.label}
|
||||
</span>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="2">
|
||||
<div
|
||||
class="content-container"
|
||||
class:scrollableContentContainer
|
||||
style:max-height={containerMaxHeight}
|
||||
data-testid={contentTestId}
|
||||
>
|
||||
{#each _.compact(items) as item, index}
|
||||
<div
|
||||
class="container"
|
||||
class:flexColContainer
|
||||
class:maxHeight100
|
||||
class:itemVisible={(item.identifier ?? index) == value}
|
||||
style:max-width={containerMaxWidth}
|
||||
>
|
||||
<svelte:component
|
||||
this={item.component}
|
||||
{...item.props}
|
||||
itemVisible={(item.identifier ?? index) == value}
|
||||
menuControlHiddenItem={(item.identifier ?? index) != value}
|
||||
/>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</HorizontalSplitter>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.main {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.main.flex1 {
|
||||
flex: 1;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.main.maxHeight100 {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.menu {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background-color: var(--theme-bg-2);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.menu::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
white-space: nowrap;
|
||||
padding: 12px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
border-bottom: 1px solid var(--theme-border);
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.menu-item:first-child {
|
||||
border-top: 1px solid var(--theme-border);
|
||||
}
|
||||
|
||||
.menu-item:hover {
|
||||
background-color: var(--theme-bg-hover);
|
||||
}
|
||||
|
||||
.menu-item.selected {
|
||||
background-color: var(--theme-bg-1);
|
||||
font-weight: 600;
|
||||
border-left: 3px solid var(--theme-font-link);
|
||||
}
|
||||
|
||||
.content-container {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.scrollableContentContainer {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.container.maxHeight100 {
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.container.flexColContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.container {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
overflow-y: auto;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container:not(.itemVisible) {
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -7,6 +7,7 @@
|
||||
import { getFormContext } from './FormProviderCore.svelte';
|
||||
|
||||
import FormSelectField from './FormSelectField.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let folderName;
|
||||
export let name;
|
||||
@@ -28,10 +29,10 @@
|
||||
<div>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="All files"
|
||||
value={_t('common.allFiles', { defaultMessage: "All files" })}
|
||||
on:click={() => setFieldValue(name, _.uniq([...($values[name] || []), ...($files && $files.map(x => x.name))]))}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Remove all" on:click={() => setFieldValue(name, [])} />
|
||||
<FormStyledButton type="button" value={_t('common.removeAll', { defaultMessage: "Remove all" })} on:click={() => setFieldValue(name, [])} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -353,6 +353,7 @@
|
||||
'img data-deploy': 'mdi mdi-database-settings color-icon-green',
|
||||
'img arrow-start-here': 'mdi mdi-arrow-down-bold-circle color-icon-green',
|
||||
'img team-file': 'mdi mdi-account-file color-icon-red',
|
||||
'img table-backup': 'mdi mdi-cube color-icon-yellow',
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
import ElectronFilesInput from './ElectronFilesInput.svelte';
|
||||
import { addFilesToSourceList } from './ImportExportConfigurator.svelte';
|
||||
import UploadButton from '../buttons/UploadButton.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let setPreviewSource = undefined;
|
||||
|
||||
@@ -55,10 +56,10 @@
|
||||
{:else}
|
||||
<UploadButton />
|
||||
{/if}
|
||||
<FormStyledButton value="Add web URL" on:click={handleAddUrl} />
|
||||
<FormStyledButton value={_t('importExport.addWebUrl', { defaultMessage: "Add web URL" })} on:click={handleAddUrl} />
|
||||
</div>
|
||||
|
||||
<div class="wrapper">Drag & drop imported files here</div>
|
||||
<div class="wrapper">{_t('importExport.dragDropImportedFilesHere', { defaultMessage: "Drag & drop imported files here" })}</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { getFormContext } from '../forms/FormProviderCore.svelte';
|
||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||
import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let conidName;
|
||||
export let databaseName;
|
||||
@@ -41,7 +42,7 @@
|
||||
{#if $dbinfo && $dbinfo[field]?.length > 0}
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value={`All ${field}`}
|
||||
value={_t('common.allFields', { defaultMessage: 'All {field}', values: { field } })}
|
||||
data-testid={`FormTablesSelect_buttonAll_${field}`}
|
||||
on:click={() =>
|
||||
setFieldValue(
|
||||
@@ -52,7 +53,7 @@
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
<FormStyledButton type="button" value="Remove all" on:click={() => setFieldValue(name, [])} />
|
||||
<FormStyledButton type="button" value={_t('common.removeAll', { defaultMessage: "Remove all" })} on:click={() => setFieldValue(name, [])} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@
|
||||
import createRef from '../utility/createRef';
|
||||
import DropDownButton from '../buttons/DropDownButton.svelte';
|
||||
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
// export let uploadedFile = undefined;
|
||||
// export let openedFile = undefined;
|
||||
@@ -211,7 +212,7 @@
|
||||
</div>
|
||||
|
||||
<div class="m-2">
|
||||
<div class="title"><FontIcon icon="icon tables" /> Map source tables/files</div>
|
||||
<div class="title"><FontIcon icon="icon tables" /> {_t('importExport.mapSourceTablesFiles', { defaultMessage: "Map source tables/files" })}</div>
|
||||
|
||||
{#key targetEditKey}
|
||||
{#key progressHolder}
|
||||
@@ -220,34 +221,34 @@
|
||||
columns={[
|
||||
{
|
||||
fieldName: 'source',
|
||||
header: 'Source',
|
||||
header: _t('importExport.source', { defaultMessage: "Source" }),
|
||||
component: SourceName,
|
||||
getProps: row => ({ name: row }),
|
||||
},
|
||||
{
|
||||
fieldName: 'action',
|
||||
header: 'Action',
|
||||
header: _t('importExport.action', { defaultMessage: "Action" }),
|
||||
component: SourceAction,
|
||||
getProps: row => ({ name: row, targetDbinfo }),
|
||||
},
|
||||
{
|
||||
fieldName: 'target',
|
||||
header: 'Target',
|
||||
header: _t('importExport.target', { defaultMessage: "Target" }),
|
||||
slot: 1,
|
||||
},
|
||||
supportsPreview && {
|
||||
fieldName: 'preview',
|
||||
header: 'Preview',
|
||||
header: _t('importExport.preview', { defaultMessage: "Preview" }),
|
||||
slot: 0,
|
||||
},
|
||||
!!progressHolder && {
|
||||
fieldName: 'status',
|
||||
header: 'Status',
|
||||
header: _t('importExport.status', { defaultMessage: "Status" }),
|
||||
slot: 3,
|
||||
},
|
||||
{
|
||||
fieldName: 'columns',
|
||||
header: 'Columns',
|
||||
header: _t('importExport.columns', { defaultMessage: "Columns" }),
|
||||
slot: 2,
|
||||
},
|
||||
]}
|
||||
|
||||
@@ -73,19 +73,19 @@
|
||||
<div class="column">
|
||||
{#if direction == 'source'}
|
||||
<div class="title">
|
||||
<FontIcon icon="icon import" /> Source configuration
|
||||
<FontIcon icon="icon import" /> {_t('importExport.sourceConfiguration', { defaultMessage: 'Source configuration' })}
|
||||
</div>
|
||||
{/if}
|
||||
{#if direction == 'target'}
|
||||
<div class="title">
|
||||
<FontIcon icon="icon export" /> Target configuration
|
||||
<FontIcon icon="icon export" /> {_t('importExport.targetConfiguration', { defaultMessage: 'Target configuration' })}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="buttons">
|
||||
{#if $currentDatabase}
|
||||
<FormStyledButton
|
||||
value="Current DB"
|
||||
value={_t('importExport.currentDatabase', { defaultMessage: "Current DB" })}
|
||||
on:click={() => {
|
||||
values.update(x => ({
|
||||
...x,
|
||||
@@ -97,7 +97,7 @@
|
||||
/>
|
||||
{/if}
|
||||
<FormStyledButton
|
||||
value="Current archive"
|
||||
value={_t('importExport.currentArchive', { defaultMessage: "Current archive" })}
|
||||
data-testid={direction == 'source'
|
||||
? 'SourceTargetConfig_buttonCurrentArchive_source'
|
||||
: 'SourceTargetConfig_buttonCurrentArchive_target'}
|
||||
@@ -111,7 +111,7 @@
|
||||
/>
|
||||
{#if direction == 'target'}
|
||||
<FormStyledButton
|
||||
value="New archive"
|
||||
value={_t('importExport.newArchive', { defaultMessage: "New archive" })}
|
||||
on:click={() => {
|
||||
showModal(InputTextModal, {
|
||||
header: 'Archive',
|
||||
@@ -133,7 +133,7 @@
|
||||
<FormSelectField
|
||||
options={types.filter(x => x.directions.includes(direction))}
|
||||
name={storageTypeField}
|
||||
label="Storage type"
|
||||
label={_t('importExport.storageType', { defaultMessage: "Storage type" })}
|
||||
/>
|
||||
|
||||
{#if format && isProApp()}
|
||||
@@ -172,9 +172,9 @@
|
||||
{/if}
|
||||
|
||||
{#if storageType == 'database' || storageType == 'query'}
|
||||
<FormConnectionSelect name={connectionIdField} label="Server" {direction} />
|
||||
<FormConnectionSelect name={connectionIdField} label={_t('common.server', { defaultMessage: 'Server' })} {direction} />
|
||||
{#if !$connectionInfo?.singleDatabase}
|
||||
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} label="Database" />
|
||||
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} label={_t('common.database', { defaultMessage: 'Database' })} />
|
||||
{/if}
|
||||
{/if}
|
||||
{#if storageType == 'database'}
|
||||
@@ -210,7 +210,7 @@
|
||||
|
||||
{#if storageType == 'archive'}
|
||||
<FormArchiveFolderSelect
|
||||
label="Archive folder"
|
||||
label={_t('importExport.archiveFolder', { defaultMessage: "Archive folder" })}
|
||||
name={archiveFolderField}
|
||||
additionalFolders={_.compact([$values[archiveFolderField]])}
|
||||
allowCreateNew={direction == 'target'}
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
import { closeCurrentModal, showModal } from './modalTools';
|
||||
import FormCloudFolderSelect from '../forms/FormCloudFolderSelect.svelte';
|
||||
import FormCheckboxField from '../forms/FormCheckboxField.svelte';
|
||||
import { useConfig } from '../utility/metadataLoaders';
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
|
||||
export let data;
|
||||
export let name;
|
||||
@@ -24,26 +26,39 @@
|
||||
export let onSave = undefined;
|
||||
export let folid;
|
||||
export let skipLocal = false;
|
||||
export let defaultTeamFolder = false;
|
||||
// export let cntid;
|
||||
|
||||
const values = writable({ name, cloudFolder: folid ?? '__local' });
|
||||
const configValue = useConfig();
|
||||
|
||||
const values = writable({
|
||||
name,
|
||||
cloudFolder: folid ?? '__local',
|
||||
saveToTeamFolder: !!(getCurrentConfig()?.storageDatabase && defaultTeamFolder),
|
||||
});
|
||||
|
||||
const electron = getElectron();
|
||||
|
||||
const handleSubmit = async e => {
|
||||
const { name, cloudFolder } = e.detail;
|
||||
if ($values['saveToTeamFolder']) {
|
||||
const { teamFileId } = await apiCall('team-files/create-new', { fileType: folder, file: name, data });
|
||||
closeCurrentModal();
|
||||
if (onSave) {
|
||||
onSave(name, {
|
||||
savedFile: name,
|
||||
savedFolder: folder,
|
||||
savedFilePath: null,
|
||||
savedCloudFolderId: null,
|
||||
savedCloudContentId: null,
|
||||
savedTeamFileId: teamFileId,
|
||||
});
|
||||
const resp = await apiCall('team-files/create-new', { fileType: folder, file: name, data });
|
||||
if (resp?.apiErrorMessage) {
|
||||
showSnackbarError(resp.apiErrorMessage);
|
||||
} else if (resp?.teamFileId) {
|
||||
closeCurrentModal();
|
||||
if (onSave) {
|
||||
onSave(name, {
|
||||
savedFile: name,
|
||||
savedFolder: folder,
|
||||
savedFilePath: null,
|
||||
savedCloudFolderId: null,
|
||||
savedCloudContentId: null,
|
||||
savedTeamFileId: resp.teamFileId,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
showSnackbarError('Failed to save to team folder.');
|
||||
}
|
||||
} else if (cloudFolder === '__local') {
|
||||
await apiCall('files/save', { folder, file: name, data, format });
|
||||
@@ -124,7 +139,7 @@
|
||||
]}
|
||||
/>
|
||||
{/if}
|
||||
{#if getCurrentConfig().storageDatabase}
|
||||
{#if $configValue?.storageDatabase}
|
||||
<FormCheckboxField label="Save to team folder" name="saveToTeamFolder" />
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import WidgetsInnerContainer from '../widgets/WidgetsInnerContainer.svelte';
|
||||
import PluginsList from './PluginsList.svelte';
|
||||
import { filterName } from 'dbgate-tools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
let filter = '';
|
||||
// let search = '';
|
||||
@@ -20,7 +21,7 @@
|
||||
</script>
|
||||
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search extensions on web" {filter} bind:value={filter} />
|
||||
<SearchInput placeholder={_t('plugins.searchExtensionsOnWeb', { defaultMessage: 'Search extensions on web' })} {filter} bind:value={filter} />
|
||||
</SearchBoxWrapper>
|
||||
<WidgetsInnerContainer>
|
||||
{#if $plugins?.errorMessage}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
<script lang="ts">
|
||||
import FormCheckboxField from "../forms/FormCheckboxField.svelte";
|
||||
import { _t } from "../translations";
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import FormValues from "../forms/FormValues.svelte";
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<FormValues let:values>
|
||||
<div class="heading">{_t('settings.behaviour', { defaultMessage: 'Behaviour' })}</div>
|
||||
|
||||
<FormCheckboxField
|
||||
name="behaviour.useTabPreviewMode"
|
||||
label={_t('settings.behaviour.useTabPreviewMode', { defaultMessage: 'Use tab preview mode' })}
|
||||
defaultValue={true}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="behaviour.jsonPreviewWrap"
|
||||
label={_t('settings.behaviour.jsonPreviewWrap', { defaultMessage: 'Wrap JSON in preview' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<div class="tip">
|
||||
<FontIcon icon="img tip" />
|
||||
{_t('settings.behaviour.singleClickPreview', {
|
||||
defaultMessage:
|
||||
'When you single-click or select a file in the "Tables, Views, Functions" view, it is shown in a preview mode and reuses an existing tab (preview tab). This is useful if you are quickly browsing tables and don\'t want every visited table to have its own tab. When you start editing the table or use double-click to open the table from the "Tables" view, a new tab is dedicated to that table.',
|
||||
})}
|
||||
</div>
|
||||
|
||||
<FormCheckboxField
|
||||
name="behaviour.openDetailOnArrows"
|
||||
label={_t('settings.behaviour.openDetailOnArrows', {
|
||||
defaultMessage: 'Open detail on keyboard navigation',
|
||||
})}
|
||||
defaultValue={true}
|
||||
disabled={values['behaviour.useTabPreviewMode'] === false}
|
||||
/>
|
||||
|
||||
<div class="heading">{_t('settings.confirmations', { defaultMessage: 'Confirmations' })}</div>
|
||||
|
||||
<FormCheckboxField
|
||||
name="skipConfirm.tableDataSave"
|
||||
label={_t('settings.confirmations.skipConfirm.tableDataSave', {
|
||||
defaultMessage: 'Skip confirmation when saving table data (SQL)',
|
||||
})}
|
||||
/>
|
||||
<FormCheckboxField
|
||||
name="skipConfirm.collectionDataSave"
|
||||
label={_t('settings.confirmations.skipConfirm.collectionDataSave', {
|
||||
defaultMessage: 'Skip confirmation when saving collection data (NoSQL)',
|
||||
})}
|
||||
/>
|
||||
</FormValues>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.tip {
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,87 @@
|
||||
<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";
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<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)} />
|
||||
</FormFieldTemplateLarge>
|
||||
|
||||
<FormCheckboxField
|
||||
name="connection.autoRefresh"
|
||||
label={_t('settings.connection.autoRefresh', {
|
||||
defaultMessage: 'Automatic refresh of database model on background',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
<FormTextField
|
||||
name="connection.autoRefreshInterval"
|
||||
label={_t('settings.connection.autoRefreshInterval', {
|
||||
defaultMessage: 'Interval between automatic DB structure reloads in seconds',
|
||||
})}
|
||||
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={[
|
||||
{ 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', {
|
||||
defaultMessage: 'Automatic close query sessions after period without any activity',
|
||||
})}
|
||||
defaultValue={true}
|
||||
/>
|
||||
<FormTextField
|
||||
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}
|
||||
/>
|
||||
</FormValues>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,100 @@
|
||||
<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";
|
||||
|
||||
|
||||
</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}
|
||||
/>
|
||||
{/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',
|
||||
})}
|
||||
/>
|
||||
|
||||
<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}
|
||||
/>
|
||||
|
||||
<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' }) },
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="dataGrid.showAllColumnsWhenSearch"
|
||||
label={_t('settings.dataGrid.showAllColumnsWhenSearch', {
|
||||
defaultMessage: 'Show all columns when searching',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,103 @@
|
||||
<script lang="ts">
|
||||
import FormCheckboxField from "../forms/FormCheckboxField.svelte";
|
||||
import FormSelectField from "../forms/FormSelectField.svelte";
|
||||
import FormValues from "../forms/FormValues.svelte";
|
||||
import { _t } from "../translations";
|
||||
import FormDefaultActionField from "./FormDefaultActionField.svelte";
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<FormValues let:values>
|
||||
<div class="heading">{_t('settings.defaultActions', { defaultMessage: 'Default actions' })}</div>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.defaultActions.connectionClick', { defaultMessage: 'Connection click' })}
|
||||
name="defaultAction.connectionClick"
|
||||
isNative
|
||||
defaultValue="connect"
|
||||
options={[
|
||||
{
|
||||
value: 'openDetails',
|
||||
label: _t('settings.defaultActions.connectionClick.openDetails', {
|
||||
defaultMessage: 'Edit / open details',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: 'connect',
|
||||
label: _t('settings.defaultActions.connectionClick.connect', { defaultMessage: 'Connect' }),
|
||||
},
|
||||
{
|
||||
value: 'none',
|
||||
label: _t('settings.defaultActions.connectionClick.none', { defaultMessage: 'Do nothing' }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.defaultActions.databaseClick', { defaultMessage: 'Database click' })}
|
||||
name="defaultAction.databaseClick"
|
||||
isNative
|
||||
defaultValue="switch"
|
||||
options={[
|
||||
{
|
||||
value: 'switch',
|
||||
label: _t('settings.defaultActions.databaseClick.switch', { defaultMessage: 'Switch database' }),
|
||||
},
|
||||
{
|
||||
value: 'none',
|
||||
label: _t('settings.defaultActions.databaseClick.none', { defaultMessage: 'Do nothing' }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="defaultAction.useLastUsedAction"
|
||||
label={_t('settings.defaultActions.useLastUsedAction', { defaultMessage: 'Use last used action' })}
|
||||
defaultValue={true}
|
||||
/>
|
||||
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.tableClick', { defaultMessage: 'Table click' })}
|
||||
objectTypeField="tables"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.viewClick', { defaultMessage: 'View click' })}
|
||||
objectTypeField="views"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.materializedViewClick', { defaultMessage: 'Materialized view click' })}
|
||||
objectTypeField="matviews"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.procedureClick', { defaultMessage: 'Procedure click' })}
|
||||
objectTypeField="procedures"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.functionClick', { defaultMessage: 'Function click' })}
|
||||
objectTypeField="functions"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.collectionClick', { defaultMessage: 'NoSQL collection click' })}
|
||||
objectTypeField="collections"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
</FormValues>
|
||||
</div>
|
||||
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,50 @@
|
||||
<script lang="ts">
|
||||
import FormTextField from "../forms/FormTextField.svelte";
|
||||
import { _t } from "../translations";
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="heading">{_t('settings.externalTools', { defaultMessage: 'External tools' })}</div>
|
||||
<FormTextField
|
||||
name="externalTools.mysqldump"
|
||||
label={_t('settings.other.externalTools.mysqldump', {
|
||||
defaultMessage: 'mysqldump (backup MySQL database)',
|
||||
})}
|
||||
defaultValue="mysqldump"
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.mysql"
|
||||
label={_t('settings.other.externalTools.mysql', { defaultMessage: 'mysql (restore MySQL database)' })}
|
||||
defaultValue="mysql"
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.mysqlPlugins"
|
||||
label={_t('settings.other.externalTools.mysqlPlugins', {
|
||||
defaultMessage:
|
||||
'Folder with mysql plugins (for example for authentication). Set only in case of problems',
|
||||
})}
|
||||
defaultValue=""
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.pg_dump"
|
||||
label={_t('settings.other.externalTools.pg_dump', {
|
||||
defaultMessage: 'pg_dump (backup PostgreSQL database)',
|
||||
})}
|
||||
defaultValue="pg_dump"
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.psql"
|
||||
label={_t('settings.other.externalTools.psql', { defaultMessage: 'psql (restore PostgreSQL database)' })}
|
||||
defaultValue="psql"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,126 @@
|
||||
<script lang="ts">
|
||||
import { internalRedirectTo } from '../clientAuth';
|
||||
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 SelectField from '../forms/SelectField.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import { EDITOR_KEYBINDINGS_MODES } from '../query/AceEditor.svelte';
|
||||
import { currentEditorKeybindigMode, currentEditorWrapEnabled } from '../stores';
|
||||
import { _t, getSelectedLanguage, setSelectedLanguage } from '../translations';
|
||||
import { isMac } from '../utility/common';
|
||||
import getElectron from '../utility/getElectron';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||
|
||||
const electron = getElectron();
|
||||
let restartWarning = false;
|
||||
</script>
|
||||
<div class="wrapper">
|
||||
<div class="heading">{_t('settings.general', { defaultMessage: 'General' })}</div>
|
||||
{#if electron}
|
||||
<div class="heading">{_t('settings.appearance', { defaultMessage: 'Appearance' })}</div>
|
||||
<FormCheckboxField
|
||||
name="app.useNativeMenu"
|
||||
label={isMac()
|
||||
? _t('settings.useNativeWindowTitle', { defaultMessage: 'Use native window title' })
|
||||
: _t('settings.useSystemNativeMenu', { defaultMessage: 'Use system native menu' })}
|
||||
on:change={() => {
|
||||
restartWarning = true;
|
||||
}}
|
||||
/>
|
||||
{#if restartWarning}
|
||||
<div class="ml-5 mb-3">
|
||||
<FontIcon icon="img warn" />
|
||||
{_t('settings.nativeMenuRestartWarning', {
|
||||
defaultMessage: 'Native menu settings will be applied after app restart',
|
||||
})}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<FormCheckboxField
|
||||
name="tabGroup.showServerName"
|
||||
label={_t('settings.tabGroup.showServerName', {
|
||||
defaultMessage: 'Show server name alongside database name in title of the tab group',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.other.autoUpdateApplication', { defaultMessage: 'Auto update application' })}
|
||||
name="app.autoUpdateMode"
|
||||
isNative
|
||||
defaultValue=""
|
||||
options={[
|
||||
{
|
||||
value: 'skip',
|
||||
label: _t('settings.other.autoUpdateApplication.skip', {
|
||||
defaultMessage: 'Do not check for new versions',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: '',
|
||||
label: _t('settings.other.autoUpdateApplication.check', { defaultMessage: 'Check for new versions' }),
|
||||
},
|
||||
{
|
||||
value: 'download',
|
||||
label: _t('settings.other.autoUpdateApplication.download', {
|
||||
defaultMessage: 'Check and download new versions',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<div class="heading">{_t('settings.localization', { defaultMessage: 'Localization' })}</div>
|
||||
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.localization.language', { defaultMessage: 'Language' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
data-testid="SettingsModal_languageSelect"
|
||||
options={[
|
||||
{ value: 'cs', label: 'Čeština' },
|
||||
{ value: 'de', label: 'Deutsch' },
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'es', label: 'Español' },
|
||||
{ value: 'fr', label: 'Français' },
|
||||
{ value: 'it', label: 'Italiano' },
|
||||
{ value: 'pt', label: 'Português (Brasil)' },
|
||||
{ value: 'sk', label: 'Slovenčina' },
|
||||
{ value: 'ja', label: '日本語' },
|
||||
{ value: 'zh', label: '中文' },
|
||||
]}
|
||||
defaultValue={getSelectedLanguage()}
|
||||
value={getSelectedLanguage()}
|
||||
on:change={e => {
|
||||
setSelectedLanguage(e.detail);
|
||||
showModal(ConfirmModal, {
|
||||
message: _t('settings.localization.reloadWarning', {
|
||||
defaultMessage: 'Application will be reloaded to apply new language settings',
|
||||
}),
|
||||
onConfirm: () => {
|
||||
setTimeout(() => {
|
||||
internalRedirectTo(electron ? '/index.html' : '/');
|
||||
}, 100);
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,91 @@
|
||||
<script lang="ts">
|
||||
import { safeFormatDate } from "dbgate-tools";
|
||||
import FormStyledButton from "../buttons/FormStyledButton.svelte";
|
||||
import FormTextAreaField from "../forms/FormTextAreaField.svelte";
|
||||
import FontIcon from "../icons/FontIcon.svelte";
|
||||
import { _t } from "../translations";
|
||||
import { apiCall } from "../utility/api";
|
||||
import { useSettings } from "../utility/metadataLoaders";
|
||||
import { derived } from "svelte/store";
|
||||
|
||||
const settings = useSettings();
|
||||
const settingsValues = derived(settings, $settings => {
|
||||
if (!$settings) {
|
||||
return {};
|
||||
}
|
||||
return $settings;
|
||||
});
|
||||
let licenseKeyCheckResult = null;
|
||||
|
||||
$: licenseKey = $settingsValues['other.licenseKey'];
|
||||
|
||||
</script>
|
||||
|
||||
<div class="heading">{_t('settings.other.license', { defaultMessage: 'License' })}</div>
|
||||
<FormTextAreaField
|
||||
name="other.licenseKey"
|
||||
label={_t('settings.other.licenseKey', { defaultMessage: 'License key' })}
|
||||
rows={7}
|
||||
onChange={async value => {
|
||||
licenseKeyCheckResult = await apiCall('config/check-license', { licenseKey: value });
|
||||
}}
|
||||
/>
|
||||
{#if licenseKeyCheckResult}
|
||||
<div class="m-3 ml-5">
|
||||
{#if licenseKeyCheckResult.status == 'ok'}
|
||||
<div>
|
||||
<FontIcon icon="img ok" />
|
||||
{_t('settings.other.licenseKey.valid', { defaultMessage: 'License key is valid' })}
|
||||
</div>
|
||||
{#if licenseKeyCheckResult.validTo}
|
||||
<div>
|
||||
{_t('settings.other.licenseKey.validTo', { defaultMessage: 'License valid to:' })}
|
||||
{licenseKeyCheckResult.validTo}
|
||||
</div>
|
||||
{/if}
|
||||
{#if licenseKeyCheckResult.expiration}
|
||||
<div>
|
||||
{_t('settings.other.licenseKey.expiration', { defaultMessage: 'License key expiration:' })}
|
||||
<b>{safeFormatDate(licenseKeyCheckResult.expiration)}</b>
|
||||
</div>
|
||||
{/if}
|
||||
{:else if licenseKeyCheckResult.status == 'error'}
|
||||
<div>
|
||||
<FontIcon icon="img error" />
|
||||
{licenseKeyCheckResult.errorMessage ??
|
||||
_t('settings.other.licenseKey.invalid', { defaultMessage: 'License key is invalid' })}
|
||||
{#if licenseKeyCheckResult.expiration}
|
||||
<div>
|
||||
{_t('settings.other.licenseKey.expiration', { defaultMessage: 'License key expiration:' })}
|
||||
<b>{safeFormatDate(licenseKeyCheckResult.expiration)}</b>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if licenseKeyCheckResult.isExpired}
|
||||
<div class="mt-2">
|
||||
<FormStyledButton
|
||||
value={_t('settings.other.licenseKey.checkForNew', {
|
||||
defaultMessage: 'Check for new license key',
|
||||
})}
|
||||
skipWidth
|
||||
on:click={async () => {
|
||||
licenseKeyCheckResult = await apiCall('config/get-new-license', { oldLicenseKey: licenseKey });
|
||||
if (licenseKeyCheckResult.licenseKey) {
|
||||
apiCall('config/update-settings', { 'other.licenseKey': licenseKeyCheckResult.licenseKey });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,100 @@
|
||||
<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 SelectField from "../forms/SelectField.svelte";
|
||||
import { EDITOR_KEYBINDINGS_MODES } from "../query/AceEditor.svelte";
|
||||
import { currentEditorKeybindigMode, currentEditorWrapEnabled } from "../stores";
|
||||
import { _t } from "../translations";
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="heading">{_t('settings.sqlEditor', { defaultMessage: 'SQL editor' })}</div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="col-3">
|
||||
<FormSelectField
|
||||
label={_t('settings.sqlEditor.sqlCommandsCase', { defaultMessage: 'SQL commands case' })}
|
||||
name="sqlEditor.sqlCommandsCase"
|
||||
isNative
|
||||
defaultValue="upperCase"
|
||||
options={[
|
||||
{ value: 'upperCase', label: 'UPPER CASE' },
|
||||
{ value: 'lowerCase', label: 'lower case' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.editor.keybinds', { defaultMessage: 'Editor keybinds' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
defaultValue="default"
|
||||
options={EDITOR_KEYBINDINGS_MODES.map(mode => ({ label: mode.label, value: mode.value }))}
|
||||
value={$currentEditorKeybindigMode}
|
||||
on:change={e => ($currentEditorKeybindigMode = e.detail)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.editor.wordWrap', { defaultMessage: 'Enable word wrap' })}
|
||||
type="combo"
|
||||
>
|
||||
<CheckboxField
|
||||
checked={$currentEditorWrapEnabled}
|
||||
on:change={e => ($currentEditorWrapEnabled = e.target.checked)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormTextField
|
||||
name="sqlEditor.limitRows"
|
||||
label={_t('settings.sqlEditor.limitRows', { defaultMessage: 'Return only N rows from query' })}
|
||||
placeholder={_t('settings.sqlEditor.limitRowsPlaceholder', { defaultMessage: '(No rows limit)' })}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="sqlEditor.showTableAliasesInCodeCompletion"
|
||||
label={_t('settings.sqlEditor.showTableAliasesInCodeCompletion', {
|
||||
defaultMessage: 'Show table aliases in code completion',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="sqlEditor.disableSplitByEmptyLine"
|
||||
label={_t('settings.sqlEditor.disableSplitByEmptyLine', { defaultMessage: 'Disable split by empty line' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="sqlEditor.disableExecuteCurrentLine"
|
||||
label={_t('settings.sqlEditor.disableExecuteCurrentLine', {
|
||||
defaultMessage: 'Disable current line execution (Execute current)',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="sqlEditor.hideColumnsPanel"
|
||||
label={_t('settings.sqlEditor.hideColumnsPanel', { defaultMessage: 'Hide Columns/Filters panel by default' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
</style>
|
||||
@@ -1,842 +0,0 @@
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||
import Link from '../elements/Link.svelte';
|
||||
import TabControl from '../elements/TabControl.svelte';
|
||||
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 SelectField from '../forms/SelectField.svelte';
|
||||
import SettingsFormProvider from '../forms/SettingsFormProvider.svelte';
|
||||
import TextField from '../forms/TextField.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
|
||||
import ModalBase from '../modals/ModalBase.svelte';
|
||||
import { closeCurrentModal } from '../modals/modalTools';
|
||||
import { EDITOR_KEYBINDINGS_MODES, EDITOR_THEMES, FONT_SIZES } from '../query/AceEditor.svelte';
|
||||
import SqlEditor from '../query/SqlEditor.svelte';
|
||||
import {
|
||||
currentEditorFontSize,
|
||||
currentEditorWrapEnabled,
|
||||
currentEditorTheme,
|
||||
currentEditorKeybindigMode,
|
||||
extensions,
|
||||
selectedWidget,
|
||||
lockedDatabaseMode,
|
||||
visibleWidgetSideBar,
|
||||
currentTheme,
|
||||
getSystemTheme,
|
||||
} from '../stores';
|
||||
import { isMac } from '../utility/common';
|
||||
import getElectron from '../utility/getElectron';
|
||||
import ThemeSkeleton from './ThemeSkeleton.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import FormTextAreaField from '../forms/FormTextAreaField.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { useSettings } from '../utility/metadataLoaders';
|
||||
import { derived } from 'svelte/store';
|
||||
import { safeFormatDate } from 'dbgate-tools';
|
||||
import FormDefaultActionField from './FormDefaultActionField.svelte';
|
||||
import AiSettingsTab from './AiSettingsTab.svelte';
|
||||
import { _t, setSelectedLanguage } from '../translations';
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import { internalRedirectTo } from '../clientAuth';
|
||||
import { getSelectedLanguage } from '../translations';
|
||||
|
||||
const electron = getElectron();
|
||||
let restartWarning = false;
|
||||
let licenseKeyCheckResult = null;
|
||||
|
||||
export let selectedTab = 'general';
|
||||
|
||||
const sqlPreview = `-- example query
|
||||
SELECT
|
||||
MAX(Album.AlbumId) AS max_album,
|
||||
MAX(Album.Title) AS max_title,
|
||||
Artist.ArtistId,
|
||||
'album' AS test_string,
|
||||
123 AS test_number
|
||||
FROM
|
||||
Album
|
||||
INNER JOIN Artist ON Album.ArtistId = Artist.ArtistId
|
||||
GROUP BY
|
||||
Artist.ArtistId
|
||||
ORDER BY
|
||||
Artist.Name ASC
|
||||
`;
|
||||
|
||||
function openThemePlugins() {
|
||||
closeCurrentModal();
|
||||
$selectedWidget = 'plugins';
|
||||
$visibleWidgetSideBar = true;
|
||||
}
|
||||
|
||||
const settings = useSettings();
|
||||
const settingsValues = derived(settings, $settings => {
|
||||
if (!$settings) {
|
||||
return {};
|
||||
}
|
||||
return $settings;
|
||||
});
|
||||
|
||||
$: licenseKey = $settingsValues['other.licenseKey'];
|
||||
let checkedLicenseKey = false;
|
||||
$: if (licenseKey && !checkedLicenseKey) {
|
||||
checkedLicenseKey = true;
|
||||
apiCall('config/check-license', { licenseKey }).then(result => {
|
||||
licenseKeyCheckResult = result;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<SettingsFormProvider>
|
||||
<ModalBase {...$$restProps} noPadding fixedHeight>
|
||||
<div slot="header">{_t('settings.title', { defaultMessage: 'Settings' })}</div>
|
||||
|
||||
<FormValues let:values>
|
||||
<TabControl
|
||||
bind:value={selectedTab}
|
||||
isInline
|
||||
inlineTabs
|
||||
scrollableContentContainer
|
||||
containerMaxWidth="100%"
|
||||
containerMaxHeight="calc(100% - 34px)"
|
||||
maxHeight100
|
||||
flex1
|
||||
tabs={[
|
||||
hasPermission('settings/change') && {
|
||||
identifier: 'general',
|
||||
label: _t('settings.general', { defaultMessage: 'General' }),
|
||||
slot: 1,
|
||||
},
|
||||
isProApp() &&
|
||||
electron && {
|
||||
identifier: 'license',
|
||||
label: _t('settings.license', { defaultMessage: 'License' }),
|
||||
slot: 7,
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
identifier: 'connection',
|
||||
label: _t('settings.connection', { defaultMessage: 'Connection' }),
|
||||
slot: 2,
|
||||
},
|
||||
{ identifier: 'theme', label: _t('settings.theme', { defaultMessage: 'Themes' }), slot: 3 },
|
||||
hasPermission('settings/change') && {
|
||||
identifier: 'default-actions',
|
||||
label: _t('settings.defaultActions', { defaultMessage: 'Default Actions' }),
|
||||
slot: 4,
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
identifier: 'behaviour',
|
||||
label: _t('settings.behaviour', { defaultMessage: 'Behaviour' }),
|
||||
slot: 5,
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
identifier: 'external-tools',
|
||||
label: _t('settings.externalTools', { defaultMessage: 'External tools' }),
|
||||
slot: 8,
|
||||
},
|
||||
hasPermission('settings/change') && {
|
||||
identifier: 'other',
|
||||
label: _t('settings.other', { defaultMessage: 'Other' }),
|
||||
slot: 6,
|
||||
},
|
||||
isProApp() && hasPermission('settings/change') && { identifier: 'ai', label: 'AI', slot: 9 },
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="1">
|
||||
{#if electron}
|
||||
<div class="heading">{_t('settings.appearance', { defaultMessage: 'Appearance' })}</div>
|
||||
<FormCheckboxField
|
||||
name="app.useNativeMenu"
|
||||
label={isMac()
|
||||
? _t('settings.useNativeWindowTitle', { defaultMessage: 'Use native window title' })
|
||||
: _t('settings.useSystemNativeMenu', { defaultMessage: 'Use system native menu' })}
|
||||
on:change={() => {
|
||||
restartWarning = true;
|
||||
}}
|
||||
/>
|
||||
{#if restartWarning}
|
||||
<div class="ml-5 mb-3">
|
||||
<FontIcon icon="img warn" />
|
||||
{_t('settings.nativeMenuRestartWarning', {
|
||||
defaultMessage: 'Native menu settings will be applied after app restart',
|
||||
})}
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<FormCheckboxField
|
||||
name="tabGroup.showServerName"
|
||||
label={_t('settings.tabGroup.showServerName', {
|
||||
defaultMessage: 'Show server name alongside database name in title of the tab group',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
<div class="heading">{_t('settings.localization', { defaultMessage: 'Localization' })}</div>
|
||||
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.localization.language', { defaultMessage: 'Language' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
data-testid="SettingsModal_languageSelect"
|
||||
options={[
|
||||
{ value: 'cs', label: 'Čeština' },
|
||||
{ value: 'de', label: 'Deutsch' },
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'es', label: 'Español' },
|
||||
{ value: 'fr', label: 'Français' },
|
||||
{ value: 'it', label: 'Italiano' },
|
||||
{ value: 'pt', label: 'Português (Brasil)' },
|
||||
{ value: 'sk', label: 'Slovenčina' },
|
||||
{ value: 'zh', label: '中文' },
|
||||
]}
|
||||
defaultValue={getSelectedLanguage()}
|
||||
value={getSelectedLanguage()}
|
||||
on:change={e => {
|
||||
setSelectedLanguage(e.detail);
|
||||
showModal(ConfirmModal, {
|
||||
message: _t('settings.localization.reloadWarning', {
|
||||
defaultMessage: 'Application will be reloaded to apply new language settings',
|
||||
}),
|
||||
onConfirm: () => {
|
||||
setTimeout(() => {
|
||||
internalRedirectTo(electron ? '/index.html' : '/');
|
||||
}, 100);
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
|
||||
<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}
|
||||
/>
|
||||
{/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',
|
||||
})}
|
||||
/>
|
||||
|
||||
<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}
|
||||
/>
|
||||
|
||||
<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' }) },
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="dataGrid.showAllColumnsWhenSearch"
|
||||
label={_t('settings.dataGrid.showAllColumnsWhenSearch', {
|
||||
defaultMessage: 'Show all columns when searching',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<div class="heading">{_t('settings.sqlEditor', { defaultMessage: 'SQL editor' })}</div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="col-3">
|
||||
<FormSelectField
|
||||
label={_t('settings.sqlEditor.sqlCommandsCase', { defaultMessage: 'SQL commands case' })}
|
||||
name="sqlEditor.sqlCommandsCase"
|
||||
isNative
|
||||
defaultValue="upperCase"
|
||||
options={[
|
||||
{ value: 'upperCase', label: 'UPPER CASE' },
|
||||
{ value: 'lowerCase', label: 'lower case' },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.editor.keybinds', { defaultMessage: 'Editor keybinds' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
defaultValue="default"
|
||||
options={EDITOR_KEYBINDINGS_MODES.map(mode => ({ label: mode.label, value: mode.value }))}
|
||||
value={$currentEditorKeybindigMode}
|
||||
on:change={e => ($currentEditorKeybindigMode = e.detail)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.editor.wordWrap', { defaultMessage: 'Enable word wrap' })}
|
||||
type="combo"
|
||||
>
|
||||
<CheckboxField
|
||||
checked={$currentEditorWrapEnabled}
|
||||
on:change={e => ($currentEditorWrapEnabled = e.target.checked)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<FormTextField
|
||||
name="sqlEditor.limitRows"
|
||||
label={_t('settings.sqlEditor.limitRows', { defaultMessage: 'Return only N rows from query' })}
|
||||
placeholder={_t('settings.sqlEditor.limitRowsPlaceholder', { defaultMessage: '(No rows limit)' })}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="sqlEditor.showTableAliasesInCodeCompletion"
|
||||
label={_t('settings.sqlEditor.showTableAliasesInCodeCompletion', {
|
||||
defaultMessage: 'Show table aliases in code completion',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="sqlEditor.disableSplitByEmptyLine"
|
||||
label={_t('settings.sqlEditor.disableSplitByEmptyLine', { defaultMessage: 'Disable split by empty line' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="sqlEditor.disableExecuteCurrentLine"
|
||||
label={_t('settings.sqlEditor.disableExecuteCurrentLine', {
|
||||
defaultMessage: 'Disable current line execution (Execute current)',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="2">
|
||||
<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)} />
|
||||
</FormFieldTemplateLarge>
|
||||
|
||||
<FormCheckboxField
|
||||
name="connection.autoRefresh"
|
||||
label={_t('settings.connection.autoRefresh', {
|
||||
defaultMessage: 'Automatic refresh of database model on background',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
<FormTextField
|
||||
name="connection.autoRefreshInterval"
|
||||
label={_t('settings.connection.autoRefreshInterval', {
|
||||
defaultMessage: 'Interval between automatic DB structure reloads in seconds',
|
||||
})}
|
||||
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={[
|
||||
{ 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', {
|
||||
defaultMessage: 'Automatic close query sessions after period without any activity',
|
||||
})}
|
||||
defaultValue={true}
|
||||
/>
|
||||
<FormTextField
|
||||
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}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="3">
|
||||
<div class="heading">{_t('settings.appearance', { defaultMessage: 'Application theme' })}</div>
|
||||
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.useSystemTheme', { defaultMessage: 'Use system theme' })}
|
||||
type="checkbox"
|
||||
labelProps={{
|
||||
onClick: () => {
|
||||
if ($currentTheme) {
|
||||
$currentTheme = null;
|
||||
} else {
|
||||
$currentTheme = getSystemTheme();
|
||||
}
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CheckboxField
|
||||
checked={!$currentTheme}
|
||||
on:change={e => {
|
||||
if (e.target['checked']) {
|
||||
$currentTheme = null;
|
||||
} else {
|
||||
$currentTheme = getSystemTheme();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
|
||||
<div class="themes">
|
||||
{#each $extensions.themes as theme}
|
||||
<ThemeSkeleton {theme} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="m-5">
|
||||
{_t('settings.appearance.moreThemes', { defaultMessage: 'More themes are available as' })}
|
||||
<Link onClick={openThemePlugins}>plugins</Link>
|
||||
<br />
|
||||
{_t('settings.appearance.afterInstalling', {
|
||||
defaultMessage:
|
||||
'After installing theme plugin (try search "theme" in available extensions) new themes will be available here.',
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div class="heading">{_t('settings.appearance.editorTheme', { defaultMessage: 'Editor theme' })}</div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.editorTheme', { defaultMessage: 'Theme' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
notSelected={_t('settings.appearance.editorTheme.default', { defaultMessage: '(use theme default)' })}
|
||||
options={EDITOR_THEMES.map(theme => ({ label: theme, value: theme }))}
|
||||
value={$currentEditorTheme}
|
||||
on:change={e => ($currentEditorTheme = e.detail)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.fontSize', { defaultMessage: 'Font size' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
notSelected="(default)"
|
||||
options={FONT_SIZES}
|
||||
value={FONT_SIZES.find(x => x.value == $currentEditorFontSize) ? $currentEditorFontSize : 'custom'}
|
||||
on:change={e => ($currentEditorFontSize = e.detail)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.customSize', { defaultMessage: 'Custom size' })}
|
||||
type="text"
|
||||
>
|
||||
<TextField
|
||||
value={$currentEditorFontSize == 'custom' ? '' : $currentEditorFontSize}
|
||||
on:change={e => ($currentEditorFontSize = e.target['value'])}
|
||||
disabled={!!FONT_SIZES.find(x => x.value == $currentEditorFontSize) &&
|
||||
$currentEditorFontSize != 'custom'}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<FormTextField
|
||||
name="editor.fontFamily"
|
||||
label={_t('settings.appearance.fontFamily', { defaultMessage: 'Editor font family' })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor">
|
||||
<SqlEditor value={sqlPreview} readOnly />
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="4">
|
||||
<div class="heading">{_t('settings.defaultActions', { defaultMessage: 'Default actions' })}</div>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.defaultActions.connectionClick', { defaultMessage: 'Connection click' })}
|
||||
name="defaultAction.connectionClick"
|
||||
isNative
|
||||
defaultValue="connect"
|
||||
options={[
|
||||
{
|
||||
value: 'openDetails',
|
||||
label: _t('settings.defaultActions.connectionClick.openDetails', {
|
||||
defaultMessage: 'Edit / open details',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: 'connect',
|
||||
label: _t('settings.defaultActions.connectionClick.connect', { defaultMessage: 'Connect' }),
|
||||
},
|
||||
{
|
||||
value: 'none',
|
||||
label: _t('settings.defaultActions.connectionClick.none', { defaultMessage: 'Do nothing' }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.defaultActions.databaseClick', { defaultMessage: 'Database click' })}
|
||||
name="defaultAction.databaseClick"
|
||||
isNative
|
||||
defaultValue="switch"
|
||||
options={[
|
||||
{
|
||||
value: 'switch',
|
||||
label: _t('settings.defaultActions.databaseClick.switch', { defaultMessage: 'Switch database' }),
|
||||
},
|
||||
{
|
||||
value: 'none',
|
||||
label: _t('settings.defaultActions.databaseClick.none', { defaultMessage: 'Do nothing' }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="defaultAction.useLastUsedAction"
|
||||
label={_t('settings.defaultActions.useLastUsedAction', { defaultMessage: 'Use last used action' })}
|
||||
defaultValue={true}
|
||||
/>
|
||||
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.tableClick', { defaultMessage: 'Table click' })}
|
||||
objectTypeField="tables"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.viewClick', { defaultMessage: 'View click' })}
|
||||
objectTypeField="views"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.materializedViewClick', { defaultMessage: 'Materialized view click' })}
|
||||
objectTypeField="matviews"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.procedureClick', { defaultMessage: 'Procedure click' })}
|
||||
objectTypeField="procedures"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.functionClick', { defaultMessage: 'Function click' })}
|
||||
objectTypeField="functions"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
<FormDefaultActionField
|
||||
label={_t('settings.defaultActions.collectionClick', { defaultMessage: 'NoSQL collection click' })}
|
||||
objectTypeField="collections"
|
||||
disabled={values['defaultAction.useLastUsedAction'] !== false}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="5">
|
||||
<div class="heading">{_t('settings.behaviour', { defaultMessage: 'Behaviour' })}</div>
|
||||
|
||||
<FormCheckboxField
|
||||
name="behaviour.useTabPreviewMode"
|
||||
label={_t('settings.behaviour.useTabPreviewMode', { defaultMessage: 'Use tab preview mode' })}
|
||||
defaultValue={true}
|
||||
/>
|
||||
|
||||
<FormCheckboxField
|
||||
name="behaviour.jsonPreviewWrap"
|
||||
label={_t('settings.behaviour.jsonPreviewWrap', { defaultMessage: 'Wrap JSON in preview' })}
|
||||
defaultValue={false}
|
||||
/>
|
||||
|
||||
<div class="tip">
|
||||
<FontIcon icon="img tip" />
|
||||
{_t('settings.behaviour.singleClickPreview', {
|
||||
defaultMessage:
|
||||
'When you single-click or select a file in the "Tables, Views, Functions" view, it is shown in a preview mode and reuses an existing tab (preview tab). This is useful if you are quickly browsing tables and don\'t want every visited table to have its own tab. When you start editing the table or use double-click to open the table from the "Tables" view, a new tab is dedicated to that table.',
|
||||
})}
|
||||
</div>
|
||||
|
||||
<FormCheckboxField
|
||||
name="behaviour.openDetailOnArrows"
|
||||
label={_t('settings.behaviour.openDetailOnArrows', {
|
||||
defaultMessage: 'Open detail on keyboard navigation',
|
||||
})}
|
||||
defaultValue={true}
|
||||
disabled={values['behaviour.useTabPreviewMode'] === false}
|
||||
/>
|
||||
|
||||
<div class="heading">{_t('settings.confirmations', { defaultMessage: 'Confirmations' })}</div>
|
||||
|
||||
<FormCheckboxField
|
||||
name="skipConfirm.tableDataSave"
|
||||
label={_t('settings.confirmations.skipConfirm.tableDataSave', {
|
||||
defaultMessage: 'Skip confirmation when saving table data (SQL)',
|
||||
})}
|
||||
/>
|
||||
<FormCheckboxField
|
||||
name="skipConfirm.collectionDataSave"
|
||||
label={_t('settings.confirmations.skipConfirm.collectionDataSave', {
|
||||
defaultMessage: 'Skip confirmation when saving collection data (NoSQL)',
|
||||
})}
|
||||
/>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="6">
|
||||
<div class="heading">{_t('settings.other', { defaultMessage: 'Other' })}</div>
|
||||
|
||||
<FormTextField
|
||||
name="other.gistCreateToken"
|
||||
label={_t('settings.other.gistCreateToken', { defaultMessage: 'API token for creating error gists' })}
|
||||
defaultValue=""
|
||||
/>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.other.autoUpdateApplication', { defaultMessage: 'Auto update application' })}
|
||||
name="app.autoUpdateMode"
|
||||
isNative
|
||||
defaultValue=""
|
||||
options={[
|
||||
{
|
||||
value: 'skip',
|
||||
label: _t('settings.other.autoUpdateApplication.skip', {
|
||||
defaultMessage: 'Do not check for new versions',
|
||||
}),
|
||||
},
|
||||
{
|
||||
value: '',
|
||||
label: _t('settings.other.autoUpdateApplication.check', { defaultMessage: 'Check for new versions' }),
|
||||
},
|
||||
{
|
||||
value: 'download',
|
||||
label: _t('settings.other.autoUpdateApplication.download', {
|
||||
defaultMessage: 'Check and download new versions',
|
||||
}),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
{#if isProApp()}
|
||||
<FormCheckboxField
|
||||
name="ai.allowSendModels"
|
||||
label={_t('settings.other.ai.allowSendModels', {
|
||||
defaultMessage: 'Allow to send DB models and query snippets to AI service',
|
||||
})}
|
||||
defaultValue={false}
|
||||
/>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="7">
|
||||
<div class="heading">{_t('settings.other.license', { defaultMessage: 'License' })}</div>
|
||||
<FormTextAreaField
|
||||
name="other.licenseKey"
|
||||
label={_t('settings.other.licenseKey', { defaultMessage: 'License key' })}
|
||||
rows={7}
|
||||
onChange={async value => {
|
||||
licenseKeyCheckResult = await apiCall('config/check-license', { licenseKey: value });
|
||||
}}
|
||||
/>
|
||||
{#if licenseKeyCheckResult}
|
||||
<div class="m-3 ml-5">
|
||||
{#if licenseKeyCheckResult.status == 'ok'}
|
||||
<div>
|
||||
<FontIcon icon="img ok" />
|
||||
{_t('settings.other.licenseKey.valid', { defaultMessage: 'License key is valid' })}
|
||||
</div>
|
||||
{#if licenseKeyCheckResult.validTo}
|
||||
<div>
|
||||
{_t('settings.other.licenseKey.validTo', { defaultMessage: 'License valid to:' })}
|
||||
{licenseKeyCheckResult.validTo}
|
||||
</div>
|
||||
{/if}
|
||||
{#if licenseKeyCheckResult.expiration}
|
||||
<div>
|
||||
{_t('settings.other.licenseKey.expiration', { defaultMessage: 'License key expiration:' })}
|
||||
<b>{safeFormatDate(licenseKeyCheckResult.expiration)}</b>
|
||||
</div>
|
||||
{/if}
|
||||
{:else if licenseKeyCheckResult.status == 'error'}
|
||||
<div>
|
||||
<FontIcon icon="img error" />
|
||||
{licenseKeyCheckResult.errorMessage ??
|
||||
_t('settings.other.licenseKey.invalid', { defaultMessage: 'License key is invalid' })}
|
||||
{#if licenseKeyCheckResult.expiration}
|
||||
<div>
|
||||
{_t('settings.other.licenseKey.expiration', { defaultMessage: 'License key expiration:' })}
|
||||
<b>{safeFormatDate(licenseKeyCheckResult.expiration)}</b>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if licenseKeyCheckResult.isExpired}
|
||||
<div class="mt-2">
|
||||
<FormStyledButton
|
||||
value={_t('settings.other.licenseKey.checkForNew', {
|
||||
defaultMessage: 'Check for new license key',
|
||||
})}
|
||||
skipWidth
|
||||
on:click={async () => {
|
||||
licenseKeyCheckResult = await apiCall('config/get-new-license', { oldLicenseKey: licenseKey });
|
||||
if (licenseKeyCheckResult.licenseKey) {
|
||||
apiCall('config/update-settings', { 'other.licenseKey': licenseKeyCheckResult.licenseKey });
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="8">
|
||||
<div class="heading">{_t('settings.externalTools', { defaultMessage: 'External tools' })}</div>
|
||||
<FormTextField
|
||||
name="externalTools.mysqldump"
|
||||
label={_t('settings.other.externalTools.mysqldump', {
|
||||
defaultMessage: 'mysqldump (backup MySQL database)',
|
||||
})}
|
||||
defaultValue="mysqldump"
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.mysql"
|
||||
label={_t('settings.other.externalTools.mysql', { defaultMessage: 'mysql (restore MySQL database)' })}
|
||||
defaultValue="mysql"
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.mysqlPlugins"
|
||||
label={_t('settings.other.externalTools.mysqlPlugins', {
|
||||
defaultMessage:
|
||||
'Folder with mysql plugins (for example for authentication). Set only in case of problems',
|
||||
})}
|
||||
defaultValue=""
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.pg_dump"
|
||||
label={_t('settings.other.externalTools.pg_dump', {
|
||||
defaultMessage: 'pg_dump (backup PostgreSQL database)',
|
||||
})}
|
||||
defaultValue="pg_dump"
|
||||
/>
|
||||
<FormTextField
|
||||
name="externalTools.psql"
|
||||
label={_t('settings.other.externalTools.psql', { defaultMessage: 'psql (restore PostgreSQL database)' })}
|
||||
defaultValue="psql"
|
||||
/>
|
||||
</svelte:fragment>
|
||||
|
||||
<svelte:fragment slot="9">
|
||||
<AiSettingsTab {values} />
|
||||
</svelte:fragment>
|
||||
</TabControl>
|
||||
</FormValues>
|
||||
|
||||
<div slot="footer">
|
||||
<!-- <FormSubmit value="OK" on:click={handleOk} /> -->
|
||||
<FormStyledButton value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</div>
|
||||
</ModalBase>
|
||||
</SettingsFormProvider>
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.tip {
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.themes {
|
||||
overflow-x: scroll;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.editor {
|
||||
position: relative;
|
||||
height: 200px;
|
||||
width: 400px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,164 @@
|
||||
<script lang="ts">
|
||||
import Link from "../elements/Link.svelte";
|
||||
import CheckboxField from "../forms/CheckboxField.svelte";
|
||||
import FormFieldTemplateLarge from "../forms/FormFieldTemplateLarge.svelte";
|
||||
import SelectField from "../forms/SelectField.svelte";
|
||||
import { currentEditorFontSize, currentEditorTheme, currentTheme, extensions, getSystemTheme, selectedWidget, visibleWidgetSideBar } from "../stores";
|
||||
import { _t } from "../translations";
|
||||
import ThemeSkeleton from "./ThemeSkeleton.svelte";
|
||||
import { EDITOR_THEMES, FONT_SIZES } from '../query/AceEditor.svelte';
|
||||
import { closeCurrentModal } from "../modals/modalTools";
|
||||
import TextField from "../forms/TextField.svelte";
|
||||
import FormTextField from "../forms/FormTextField.svelte";
|
||||
import SqlEditor from "../query/SqlEditor.svelte";
|
||||
|
||||
function openThemePlugins() {
|
||||
closeCurrentModal();
|
||||
$selectedWidget = 'plugins';
|
||||
$visibleWidgetSideBar = true;
|
||||
}
|
||||
|
||||
const sqlPreview = `-- example query
|
||||
SELECT
|
||||
MAX(Album.AlbumId) AS max_album,
|
||||
MAX(Album.Title) AS max_title,
|
||||
Artist.ArtistId,
|
||||
'album' AS test_string,
|
||||
123 AS test_number
|
||||
FROM
|
||||
Album
|
||||
INNER JOIN Artist ON Album.ArtistId = Artist.ArtistId
|
||||
GROUP BY
|
||||
Artist.ArtistId
|
||||
ORDER BY
|
||||
Artist.Name ASC
|
||||
`;
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="heading">{_t('settings.appearance', { defaultMessage: 'Application theme' })}</div>
|
||||
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.useSystemTheme', { defaultMessage: 'Use system theme' })}
|
||||
type="checkbox"
|
||||
labelProps={{
|
||||
onClick: () => {
|
||||
if ($currentTheme) {
|
||||
$currentTheme = null;
|
||||
} else {
|
||||
$currentTheme = getSystemTheme();
|
||||
}
|
||||
},
|
||||
}}
|
||||
>
|
||||
<CheckboxField
|
||||
checked={!$currentTheme}
|
||||
on:change={e => {
|
||||
if (e.target['checked']) {
|
||||
$currentTheme = null;
|
||||
} else {
|
||||
$currentTheme = getSystemTheme();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
|
||||
<div class="themes">
|
||||
{#each $extensions.themes as theme}
|
||||
<ThemeSkeleton {theme} />
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="m-5">
|
||||
{_t('settings.appearance.moreThemes', { defaultMessage: 'More themes are available as' })}
|
||||
<Link onClick={openThemePlugins}>plugins</Link>
|
||||
<br />
|
||||
{_t('settings.appearance.afterInstalling', {
|
||||
defaultMessage:
|
||||
'After installing theme plugin (try search "theme" in available extensions) new themes will be available here.',
|
||||
})}
|
||||
</div>
|
||||
|
||||
<div class="heading">{_t('settings.appearance.editorTheme', { defaultMessage: 'Editor theme' })}</div>
|
||||
|
||||
<div class="flex">
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.editorTheme', { defaultMessage: 'Theme' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
notSelected={_t('settings.appearance.editorTheme.default', { defaultMessage: '(use theme default)' })}
|
||||
options={EDITOR_THEMES.map(theme => ({ label: theme, value: theme }))}
|
||||
value={$currentEditorTheme}
|
||||
on:change={e => ($currentEditorTheme = e.detail)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.fontSize', { defaultMessage: 'Font size' })}
|
||||
type="combo"
|
||||
>
|
||||
<SelectField
|
||||
isNative
|
||||
notSelected="(default)"
|
||||
options={FONT_SIZES}
|
||||
value={FONT_SIZES.find(x => x.value == $currentEditorFontSize) ? $currentEditorFontSize : 'custom'}
|
||||
on:change={e => ($currentEditorFontSize = e.detail)}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<FormFieldTemplateLarge
|
||||
label={_t('settings.appearance.customSize', { defaultMessage: 'Custom size' })}
|
||||
type="text"
|
||||
>
|
||||
<TextField
|
||||
value={$currentEditorFontSize == 'custom' ? '' : $currentEditorFontSize}
|
||||
on:change={e => ($currentEditorFontSize = e.target['value'])}
|
||||
disabled={!!FONT_SIZES.find(x => x.value == $currentEditorFontSize) &&
|
||||
$currentEditorFontSize != 'custom'}
|
||||
/>
|
||||
</FormFieldTemplateLarge>
|
||||
</div>
|
||||
|
||||
<div class="col-3">
|
||||
<FormTextField
|
||||
name="editor.fontFamily"
|
||||
label={_t('settings.appearance.fontFamily', { defaultMessage: 'Editor font family' })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="editor">
|
||||
<SqlEditor value={sqlPreview} readOnly />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.heading {
|
||||
font-size: 20px;
|
||||
margin: 5px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.themes {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
}
|
||||
|
||||
.editor {
|
||||
position: relative;
|
||||
height: 250px;
|
||||
width: 400px;
|
||||
margin-left: var(--dim-large-form-margin);
|
||||
margin-top: var(--dim-large-form-margin);
|
||||
margin-bottom: var(--dim-large-form-margin);
|
||||
}
|
||||
</style>
|
||||
@@ -60,7 +60,11 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">{constraintInfo ? _t('foreignKeyEditor.editForeignKey', { defaultMessage: 'Edit foreign key' }) : _t('foreignKeyEditor.addForeignKey', { defaultMessage: 'Add foreign key' })}</svelte:fragment>
|
||||
<svelte:fragment slot="header"
|
||||
>{constraintInfo
|
||||
? _t('foreignKeyEditor.editForeignKey', { defaultMessage: 'Edit foreign key' })
|
||||
: _t('foreignKeyEditor.addForeignKey', { defaultMessage: 'Add foreign key' })}</svelte:fragment
|
||||
>
|
||||
|
||||
<div class="largeFormMarker">
|
||||
<div class="row">
|
||||
@@ -92,6 +96,19 @@
|
||||
const name = fullNameFromString(e.detail);
|
||||
refTableName = name.pureName;
|
||||
refSchemaName = name.schemaName;
|
||||
|
||||
if (!columns?.find(x => x.columnName)) {
|
||||
const refTable = dbInfo?.tables?.find(
|
||||
x => x.pureName == refTableName && x.schemaName == refSchemaName
|
||||
);
|
||||
if (refTable?.primaryKey) {
|
||||
columns = refTable.primaryKey.columns.map(col => ({
|
||||
refColumnName: col.columnName,
|
||||
}));
|
||||
} else {
|
||||
columns = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
@@ -135,7 +152,8 @@
|
||||
{_t('foreignKeyEditor.baseColumn', { defaultMessage: 'Base column - ' })}{tableInfo.pureName}
|
||||
</div>
|
||||
<div class="col-5 ml-1">
|
||||
{_t('foreignKeyEditor.refColumn', { defaultMessage: 'Ref column - ' })}{refTableName || _t('foreignKeyEditor.tableNotSet', { defaultMessage: '(table not set)' })}
|
||||
{_t('foreignKeyEditor.refColumn', { defaultMessage: 'Ref column - ' })}{refTableName ||
|
||||
_t('foreignKeyEditor.tableNotSet', { defaultMessage: '(table not set)' })}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -217,7 +235,11 @@
|
||||
}}
|
||||
/>
|
||||
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value={_t('common.close', { defaultMessage: 'Close' })}
|
||||
on:click={closeCurrentModal}
|
||||
/>
|
||||
{#if constraintInfo}
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tableEditor.addColumn',
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor'}),
|
||||
name: __t('tableEditor.addColumn', { defaultMessage: 'Add column'}),
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor' }),
|
||||
name: __t('tableEditor.addColumn', { defaultMessage: 'Add column' }),
|
||||
icon: 'icon add-column',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -14,8 +14,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tableEditor.addPrimaryKey',
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor'}),
|
||||
name: __t('tableEditor.addPrimaryKey', { defaultMessage: 'Add primary key'}),
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor' }),
|
||||
name: __t('tableEditor.addPrimaryKey', { defaultMessage: 'Add primary key' }),
|
||||
icon: 'icon add-key',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tableEditor.addForeignKey',
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor'}),
|
||||
name: __t('tableEditor.addForeignKey', { defaultMessage: 'Add foreign key'}),
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor' }),
|
||||
name: __t('tableEditor.addForeignKey', { defaultMessage: 'Add foreign key' }),
|
||||
icon: 'icon add-key',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -36,8 +36,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tableEditor.addIndex',
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor'}),
|
||||
name: __t('tableEditor.addIndex', { defaultMessage: 'Add index'}),
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor' }),
|
||||
name: __t('tableEditor.addIndex', { defaultMessage: 'Add index' }),
|
||||
icon: 'icon add-key',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -47,8 +47,8 @@
|
||||
|
||||
registerCommand({
|
||||
id: 'tableEditor.addUnique',
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor'}),
|
||||
name: __t('tableEditor.addUnique', { defaultMessage: 'Add unique'}),
|
||||
category: __t('tableEditor', { defaultMessage: 'Table editor' }),
|
||||
name: __t('tableEditor.addUnique', { defaultMessage: 'Add unique' }),
|
||||
icon: 'icon add-key',
|
||||
toolbar: true,
|
||||
isRelatedToTab: true,
|
||||
@@ -188,7 +188,10 @@
|
||||
|
||||
<ObjectListControl
|
||||
collection={columns?.map((x, index) => ({ ...x, ordinal: index + 1 }))}
|
||||
title={_t('tableEditor.columns', { defaultMessage: 'Columns ({columnCount})', values: { columnCount: columns?.length || 0 } })}
|
||||
title={_t('tableEditor.columns', {
|
||||
defaultMessage: 'Columns ({columnCount})',
|
||||
values: { columnCount: columns?.length || 0 },
|
||||
})}
|
||||
emptyMessage={_t('tableEditor.nocolumnsdefined', { defaultMessage: 'No columns defined' })}
|
||||
clickable
|
||||
on:clickrow={e => showModal(ColumnEditorModal, { columnInfo: e.detail, tableInfo, setTableInfo, driver })}
|
||||
@@ -217,9 +220,7 @@
|
||||
text: _t('tableEditor.copydefinitions', { defaultMessage: 'Copy definitions' }),
|
||||
icon: 'icon copy',
|
||||
onClick: selected => {
|
||||
const names = selected
|
||||
.map(x => `${x.columnName} ${x.dataType}${x.notNull ? ' NOT NULL' : ''}`)
|
||||
.join(',\n');
|
||||
const names = selected.map(x => `${x.columnName} ${x.dataType}${x.notNull ? ' NOT NULL' : ''}`).join(',\n');
|
||||
navigator.clipboard.writeText(names);
|
||||
},
|
||||
},
|
||||
@@ -288,9 +289,21 @@
|
||||
: null,
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="0" let:row>{row?.notNull ? _t('tableEditor.notnull', { defaultMessage: 'NOT NULL' }) : _t('tableEditor.null', { defaultMessage: 'NULL' })}</svelte:fragment>
|
||||
<svelte:fragment slot="1" let:row>{row?.isSparse ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment>
|
||||
<svelte:fragment slot="2" let:row>{row?.isPersisted ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment>
|
||||
<svelte:fragment slot="0" let:row
|
||||
>{row?.notNull
|
||||
? _t('tableEditor.notnull', { defaultMessage: 'NOT NULL' })
|
||||
: _t('tableEditor.null', { defaultMessage: 'NULL' })}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="1" let:row
|
||||
>{row?.isSparse
|
||||
? _t('tableEditor.yes', { defaultMessage: 'YES' })
|
||||
: _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="2" let:row
|
||||
>{row?.isPersisted
|
||||
? _t('tableEditor.yes', { defaultMessage: 'YES' })
|
||||
: _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="3" let:row
|
||||
><Link
|
||||
onClick={e => {
|
||||
@@ -299,8 +312,16 @@
|
||||
}}>{_t('tableEditor.remove', { defaultMessage: 'Remove' })}</Link
|
||||
></svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="4" let:row>{row?.isUnsigned ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment>
|
||||
<svelte:fragment slot="5" let:row>{row?.isZerofill ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment>
|
||||
<svelte:fragment slot="4" let:row
|
||||
>{row?.isUnsigned
|
||||
? _t('tableEditor.yes', { defaultMessage: 'YES' })
|
||||
: _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="5" let:row
|
||||
>{row?.isZerofill
|
||||
? _t('tableEditor.yes', { defaultMessage: 'YES' })
|
||||
: _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="name" let:row><ColumnLabel {...row} forceIcon /></svelte:fragment>
|
||||
</ObjectListControl>
|
||||
|
||||
@@ -321,7 +342,10 @@
|
||||
<ObjectListControl
|
||||
collection={indexes}
|
||||
onAddNew={isWritable && columns?.length > 0 ? addIndex : null}
|
||||
title={_t('tableEditor.indexes', { defaultMessage: 'Indexes ({indexCount})', values: { indexCount: indexes?.length || 0 } })}
|
||||
title={_t('tableEditor.indexes', {
|
||||
defaultMessage: 'Indexes ({indexCount})',
|
||||
values: { indexCount: indexes?.length || 0 },
|
||||
})}
|
||||
emptyMessage={isWritable ? _t('tableEditor.noindexdefined', { defaultMessage: 'No index defined' }) : null}
|
||||
clickable
|
||||
on:clickrow={e => showModal(IndexEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo, driver })}
|
||||
@@ -348,7 +372,11 @@
|
||||
>
|
||||
<svelte:fragment slot="name" let:row><ConstraintLabel {...row} /></svelte:fragment>
|
||||
<svelte:fragment slot="0" let:row>{row?.columns.map(x => x.columnName).join(', ')}</svelte:fragment>
|
||||
<svelte:fragment slot="1" let:row>{row?.isUnique ? _t('tableEditor.yes', { defaultMessage: 'YES' }) : _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment>
|
||||
<svelte:fragment slot="1" let:row
|
||||
>{row?.isUnique
|
||||
? _t('tableEditor.yes', { defaultMessage: 'YES' })
|
||||
: _t('tableEditor.no', { defaultMessage: 'NO' })}</svelte:fragment
|
||||
>
|
||||
<svelte:fragment slot="2" let:row
|
||||
><Link
|
||||
onClick={e => {
|
||||
@@ -364,7 +392,10 @@
|
||||
<ObjectListControl
|
||||
collection={uniques}
|
||||
onAddNew={isWritable && columns?.length > 0 ? addUnique : null}
|
||||
title={_t('tableEditor.uniqueConstraints', { defaultMessage: 'Unique constraints ({constraintCount})', values: { constraintCount: uniques?.length || 0 } })}
|
||||
title={_t('tableEditor.uniqueConstraints', {
|
||||
defaultMessage: 'Unique constraints ({constraintCount})',
|
||||
values: { constraintCount: uniques?.length || 0 },
|
||||
})}
|
||||
emptyMessage={isWritable ? _t('tableEditor.nouniquedefined', { defaultMessage: 'No unique defined' }) : null}
|
||||
clickable
|
||||
on:clickrow={e => showModal(UniqueEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo })}
|
||||
@@ -401,13 +432,21 @@
|
||||
<ForeignKeyObjectListControl
|
||||
collection={foreignKeys}
|
||||
onAddNew={isWritable && columns?.length > 0 ? addForeignKey : null}
|
||||
title={_t('tableEditor.foreignKeys', { defaultMessage: 'Foreign keys ({foreignKeyCount})', values: { foreignKeyCount: foreignKeys?.length || 0 } })}
|
||||
emptyMessage={isWritable ? _t('tableEditor.noforeignkeydefined', { defaultMessage: 'No foreign key defined' }) : null}
|
||||
title={_t('tableEditor.foreignKeys', {
|
||||
defaultMessage: 'Foreign keys ({foreignKeyCount})',
|
||||
values: { foreignKeyCount: foreignKeys?.length || 0 },
|
||||
})}
|
||||
emptyMessage={isWritable
|
||||
? _t('tableEditor.noforeignkeydefined', { defaultMessage: 'No foreign key defined' })
|
||||
: null}
|
||||
clickable
|
||||
onRemove={row => setTableInfo(tbl => editorDeleteConstraint(tbl, row))}
|
||||
on:clickrow={e => showModal(ForeignKeyEditorModal, { constraintInfo: e.detail, tableInfo, setTableInfo, dbInfo })}
|
||||
/>
|
||||
<ForeignKeyObjectListControl collection={dependencies} title={_t('tableEditor.dependencies', { defaultMessage: 'Dependencies' })} />
|
||||
<ForeignKeyObjectListControl
|
||||
collection={dependencies}
|
||||
title={_t('tableEditor.dependencies', { defaultMessage: 'Dependencies' })}
|
||||
/>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -758,7 +758,7 @@
|
||||
title="Upgrade to Premium"
|
||||
data-testid="TabsPanel_buttonUpgrade"
|
||||
>
|
||||
<FontIcon icon="icon premium" padRight /> Upgrade
|
||||
<FontIcon icon="icon premium" /> Upgrade
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -803,6 +803,9 @@
|
||||
cursor: pointer;
|
||||
font-size: 10pt;
|
||||
padding: 5px;
|
||||
margin-top: 3px;
|
||||
margin-right: 3px;
|
||||
font-size: 8pt;
|
||||
}
|
||||
.upgrade-button:hover {
|
||||
background: linear-gradient(135deg, #0f5a85, #5c1870);
|
||||
@@ -822,7 +825,7 @@
|
||||
}
|
||||
|
||||
.tabs-upgrade-button {
|
||||
right: 120px;
|
||||
right: 110px;
|
||||
}
|
||||
.tabs.can-split {
|
||||
right: 60px;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
createQuickExportHandlerRef,
|
||||
registerQuickExportHandler,
|
||||
} from '../buttons/ToolStripExportButton.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
let loadedRows = [];
|
||||
let loadedAll = false;
|
||||
@@ -191,8 +192,8 @@
|
||||
<SelectField
|
||||
isNative
|
||||
options={[
|
||||
{ label: 'Recent logs', value: 'recent' },
|
||||
{ label: 'Choose date', value: 'date' },
|
||||
{ label: _t('logs.recentLogs', { defaultMessage: 'Recent logs' }), value: 'recent' },
|
||||
{ label: _t('logs.chooseDate', { defaultMessage: 'Choose date' }), value: 'date' },
|
||||
]}
|
||||
value={mode}
|
||||
on:change={e => {
|
||||
@@ -202,7 +203,7 @@
|
||||
/>
|
||||
|
||||
{#if mode === 'recent'}
|
||||
<div class="filter-label ml-2">Auto-scroll</div>
|
||||
<div class="filter-label ml-2">{_t('logs.autoScroll', { defaultMessage: 'Auto-scroll' })}</div>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={autoScroll}
|
||||
@@ -213,7 +214,7 @@
|
||||
{/if}
|
||||
|
||||
{#if mode === 'date'}
|
||||
<div class="filter-label">Date:</div>
|
||||
<div class="filter-label">{_t('logs.date', { defaultMessage: 'Date:' })}</div>
|
||||
<DateRangeSelector
|
||||
onChange={value => {
|
||||
dateFilter = value;
|
||||
@@ -225,12 +226,12 @@
|
||||
data-testid="AdminAuditLogTab_addFilter"
|
||||
icon="icon filter"
|
||||
menu={[
|
||||
{ text: 'Connection ID', onClick: () => filterBy('conid') },
|
||||
{ text: 'Database', onClick: () => filterBy('database') },
|
||||
{ text: 'Engine', onClick: () => filterBy('engine') },
|
||||
{ text: 'Message code', onClick: () => filterBy('msgcode') },
|
||||
{ text: 'Caller', onClick: () => filterBy('caller') },
|
||||
{ text: 'Name', onClick: () => filterBy('name') },
|
||||
{ text: _t('logs.connectionId', { defaultMessage: 'Connection ID' }), onClick: () => filterBy('conid') },
|
||||
{ text: _t('logs.database', { defaultMessage: 'Database' }), onClick: () => filterBy('database') },
|
||||
{ text: _t('logs.engine', { defaultMessage: 'Engine' }), onClick: () => filterBy('engine') },
|
||||
{ text: _t('logs.messageCode', { defaultMessage: 'Message code' }), onClick: () => filterBy('msgcode') },
|
||||
{ text: _t('logs.caller', { defaultMessage: 'Caller' }), onClick: () => filterBy('caller') },
|
||||
{ text: _t('logs.name', { defaultMessage: 'Name' }), onClick: () => filterBy('name') },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
@@ -259,15 +260,15 @@
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width:80px">Date</th>
|
||||
<th>Time</th>
|
||||
<th>Code</th>
|
||||
<th>Message</th>
|
||||
<th>Connection</th>
|
||||
<th>Database</th>
|
||||
<th>Engine</th>
|
||||
<th>Caller</th>
|
||||
<th>Name</th>
|
||||
<th style="width:80px">{_t('logs.dateTab', { defaultMessage: 'Date' })}</th>
|
||||
<th>{_t('logs.timeTab', { defaultMessage: 'Time' })}</th>
|
||||
<th>{_t('logs.codeTab', { defaultMessage: 'Code' })}</th>
|
||||
<th>{_t('logs.messageTab', { defaultMessage: 'Message' })}</th>
|
||||
<th>{_t('logs.connectionTab', { defaultMessage: 'Connection' })}</th>
|
||||
<th>{_t('logs.databaseTab', { defaultMessage: 'Database' })}</th>
|
||||
<th>{_t('logs.engineTab', { defaultMessage: 'Engine' })}</th>
|
||||
<th>{_t('logs.callerTab', { defaultMessage: 'Caller' })}</th>
|
||||
<th>{_t('logs.nameTab', { defaultMessage: 'Name' })}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -299,14 +300,14 @@
|
||||
<TabControl
|
||||
isInline
|
||||
tabs={_.compact([
|
||||
{ label: 'Details', slot: 1 },
|
||||
{ label: _t('logs.details', { defaultMessage: 'Details' }), slot: 1 },
|
||||
{ label: 'JSON', slot: 2 },
|
||||
])}
|
||||
>
|
||||
<svelte:fragment slot="1">
|
||||
<div class="details-wrap">
|
||||
<div class="row">
|
||||
<div>Message code:</div>
|
||||
<div>{_t('logs.messageCode', { defaultMessage: 'Message code:' })}</div>
|
||||
{#if mode == 'date'}
|
||||
<Link onClick={() => doSetFilter('msgcode', [row.msgcode])}>{row.msgcode || 'N/A'}</Link>
|
||||
{:else}
|
||||
@@ -314,15 +315,15 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Message:</div>
|
||||
<div>{_t('logs.message', { defaultMessage: 'Message:' })}</div>
|
||||
{row.msg}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Time:</div>
|
||||
<div>{_t('logs.time', { defaultMessage: 'Time:' })}</div>
|
||||
<b>{row.time ? format(new Date(parseInt(row.time)), 'yyyy-MM-dd HH:mm:ss') : ''}</b>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Caller:</div>
|
||||
<div>{_t('logs.caller', { defaultMessage: 'Caller:' })}</div>
|
||||
{#if mode == 'date'}
|
||||
<Link onClick={() => doSetFilter('caller', [row.caller])}>{row.caller || 'N/A'}</Link>
|
||||
{:else}
|
||||
@@ -330,7 +331,7 @@
|
||||
{/if}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div>Name:</div>
|
||||
<div>{_t('logs.name', { defaultMessage: 'Name:' })}</div>
|
||||
{#if mode == 'date'}
|
||||
<Link onClick={() => doSetFilter('name', [row.name])}>{row.name || 'N/A'}</Link>
|
||||
{:else}
|
||||
@@ -339,7 +340,7 @@
|
||||
</div>
|
||||
{#if row.conid}
|
||||
<div class="row">
|
||||
<div>Connection ID:</div>
|
||||
<div>{_t('logs.connectionId', { defaultMessage: 'Connection ID:' })}</div>
|
||||
{#if mode == 'date'}
|
||||
<Link onClick={() => doSetFilter('conid', [row.conid])}
|
||||
>{formatPossibleUuid(row.conid)}</Link
|
||||
@@ -351,7 +352,7 @@
|
||||
{/if}
|
||||
{#if row.database}
|
||||
<div class="row">
|
||||
<div>Database:</div>
|
||||
<div>{_t('logs.database', { defaultMessage: 'Database:' })}</div>
|
||||
{#if mode == 'date'}
|
||||
<Link onClick={() => doSetFilter('database', [row.database])}>{row.database}</Link>
|
||||
{:else}
|
||||
@@ -361,7 +362,7 @@
|
||||
{/if}
|
||||
{#if row.engine}
|
||||
<div class="row">
|
||||
<div>Engine:</div>
|
||||
<div>{_t('logs.engine', { defaultMessage: 'Engine:' })}</div>
|
||||
{#if mode == 'date'}
|
||||
<Link onClick={() => doSetFilter('engine', [row.engine])}>{row.engine}</Link>
|
||||
{:else}
|
||||
@@ -381,13 +382,13 @@
|
||||
{/each}
|
||||
{#if !loadedRows?.length && mode === 'date'}
|
||||
<tr>
|
||||
<td colspan="6">No data for selected date</td>
|
||||
<td colspan="6">{_t('logs.noDataForSelectedDate', { defaultMessage: "No data for selected date" })}</td>
|
||||
</tr>
|
||||
{/if}
|
||||
{#if !loadedAll && mode === 'date'}
|
||||
{#key loadedRows}
|
||||
<tr>
|
||||
<td colspan="6" bind:this={domLoadNext}>Loading next rows... </td>
|
||||
<td colspan="6" bind:this={domLoadNext}>{_t('logs.loadingNextRows', { defaultMessage: "Loading next rows..." })}</td>
|
||||
</tr>
|
||||
{/key}
|
||||
{/if}
|
||||
@@ -402,7 +403,7 @@
|
||||
data-testid="AdminAuditLogTab_refreshButton"
|
||||
on:click={() => {
|
||||
reloadData();
|
||||
}}>Refresh</ToolStripButton
|
||||
}}>{_t('logs.refresh', { defaultMessage: 'Refresh' })}</ToolStripButton
|
||||
>
|
||||
<ToolStripExportButton {quickExportHandlerRef} />
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import CommandModal from '../modals/CommandModal.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import { commandsCustomized } from '../stores';
|
||||
import { _tval } from '../translations';
|
||||
|
||||
$: commandList = _.sortBy(_.values($commandsCustomized), ['category', 'name']);
|
||||
let filter;
|
||||
@@ -27,7 +28,9 @@
|
||||
<div class="table-wrapper">
|
||||
<TableControl
|
||||
clickable
|
||||
rows={commandList.filter(cmd => filterName(filter, cmd['category'], cmd['name'], cmd['keyText'], cmd['id']))}
|
||||
rows={commandList.filter(cmd =>
|
||||
filterName(filter, _tval(cmd['category']), _tval(cmd['name']), _tval(cmd['keyText']), cmd['id'])
|
||||
)}
|
||||
columns={[
|
||||
{ header: 'Category', fieldName: 'category' },
|
||||
{ header: 'Name', fieldName: 'name' },
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
folder: 'diagrams',
|
||||
format: 'json',
|
||||
fileExtension: 'diagram',
|
||||
defaultTeamFolder: true,
|
||||
|
||||
undoRedo: true,
|
||||
});
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
fileExtension: 'impexp',
|
||||
|
||||
// undoRedo: true,
|
||||
defaultTeamFolder: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -53,6 +54,7 @@
|
||||
import uuidv1 from 'uuid/v1';
|
||||
import { tick } from 'svelte';
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
import { _t } from '../translations';
|
||||
|
||||
let busy = false;
|
||||
let executeNumber = 0;
|
||||
@@ -288,21 +290,21 @@
|
||||
/>
|
||||
|
||||
{#if busy}
|
||||
<LoadingInfo wrapper message="Processing import/export ..." />
|
||||
<LoadingInfo wrapper message={_t('importExport.processingImportExport', { defaultMessage: "Processing import/export ..." })} />
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="2">
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem
|
||||
title="Output files"
|
||||
title={_t('importExport.outputFiles', { defaultMessage: "Output files" })}
|
||||
name="output"
|
||||
height="20%"
|
||||
data-testid="ImportExportTab_outputFiles"
|
||||
>
|
||||
<RunnerOutputFiles {runnerId} {executeNumber} />
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title="Messages" name="messages">
|
||||
<WidgetColumnBarItem title={_t('importExport.messages', { defaultMessage: "Messages" })} name="messages">
|
||||
<SocketMessageView
|
||||
eventName={runnerId ? `runner-info-${runnerId}` : null}
|
||||
{executeNumber}
|
||||
@@ -311,16 +313,16 @@
|
||||
/>
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem
|
||||
title="Preview"
|
||||
title={_t('importExport.preview', { defaultMessage: "Preview" })}
|
||||
name="preview"
|
||||
skip={!$previewReaderStore}
|
||||
data-testid="ImportExportTab_preview"
|
||||
>
|
||||
<PreviewDataGrid reader={$previewReaderStore} />
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title="Advanced configuration" name="config" collapsed>
|
||||
<FormTextField label="Schedule" name="schedule" />
|
||||
<FormTextField label="Start variable index" name="startVariableIndex" />
|
||||
<WidgetColumnBarItem title={_t('importExport.advancedConfiguration', { defaultMessage: "Advanced configuration" })} name="config" collapsed>
|
||||
<FormTextField label={_t('importExport.schedule', { defaultMessage: "Schedule" })} name="schedule" />
|
||||
<FormTextField label={_t('importExport.startVariableIndex', { defaultMessage: "Start variable index" })} name="startVariableIndex" />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
</svelte:fragment>
|
||||
@@ -329,15 +331,15 @@
|
||||
<svelte:fragment slot="toolstrip">
|
||||
{#if busy}
|
||||
<ToolStripButton icon="icon stop" on:click={handleCancel} data-testid="ImportExportTab_stopButton"
|
||||
>Stop</ToolStripButton
|
||||
>{_t('importExport.stop', { defaultMessage: "Stop" })}</ToolStripButton
|
||||
>
|
||||
{:else}
|
||||
<ToolStripButton on:click={handleExecute} icon="icon run" data-testid="ImportExportTab_executeButton"
|
||||
>Run</ToolStripButton
|
||||
>{_t('importExport.run', { defaultMessage: "Run" })}</ToolStripButton
|
||||
>
|
||||
{/if}
|
||||
<ToolStripButton icon="img shell" on:click={handleGenerateScript} data-testid="ImportExportTab_generateScriptButton"
|
||||
>Generate script</ToolStripButton
|
||||
>{_t('importExport.generateScript', { defaultMessage: "Generate script" })}</ToolStripButton
|
||||
>
|
||||
<ToolStripSaveButton idPrefix="impexp" />
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -52,6 +52,7 @@
|
||||
findReplace: true,
|
||||
executeAdditionalCondition: () => getCurrentEditor()?.hasConnection() && hasPermission('dbops/query'),
|
||||
copyPaste: true,
|
||||
defaultTeamFolder: true,
|
||||
});
|
||||
registerCommand({
|
||||
id: 'query.executeCurrent',
|
||||
@@ -123,8 +124,9 @@
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { getContext, onDestroy, onMount, tick } from 'svelte';
|
||||
import { getContext, onDestroy, onMount, setContext, tick } from 'svelte';
|
||||
import sqlFormatter from 'sql-formatter';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
import VerticalSplitter from '../elements/VerticalSplitter.svelte';
|
||||
import SqlEditor from '../query/SqlEditor.svelte';
|
||||
@@ -166,6 +168,7 @@
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
import QueryAiAssistant from '../ai/QueryAiAssistant.svelte';
|
||||
import { getCurrentSettings } from '../stores';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
@@ -175,6 +178,9 @@
|
||||
|
||||
export const activator = createActivator('QueryTab', false);
|
||||
|
||||
const collapsedLeftColumnStore = writable(getCurrentSettings()['sqlEditor.hideColumnsPanel'] ?? false);
|
||||
setContext('collapsedLeftColumnStore', collapsedLeftColumnStore);
|
||||
|
||||
const QUERY_PARAMETER_STYLES = [
|
||||
{
|
||||
value: '',
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
<script lang="ts" context="module">
|
||||
export const matchingProps = [];
|
||||
</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";
|
||||
|
||||
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',
|
||||
},
|
||||
];
|
||||
</script>
|
||||
|
||||
<SettingsFormProvider>
|
||||
<SettingsMenuControl
|
||||
items={menuItems}
|
||||
bind:value={selectedItem}
|
||||
flex1={true}
|
||||
flexColContainer={true}
|
||||
scrollableContentContainer={true}
|
||||
/>
|
||||
</SettingsFormProvider>
|
||||
@@ -12,6 +12,7 @@
|
||||
execute: true,
|
||||
toggleComment: true,
|
||||
findReplace: true,
|
||||
defaultTeamFolder: true,
|
||||
executeAdditionalCondition: () => getCurrentConfig().allowShellScripting,
|
||||
});
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import * as ServerSummaryTab from './ServerSummaryTab.svelte';
|
||||
import * as ImportExportTab from './ImportExportTab.svelte';
|
||||
import * as SqlObjectTab from './SqlObjectTab.svelte';
|
||||
import * as AppLogTab from './AppLogTab.svelte';
|
||||
import * as SettingsTab from './SettingsTab.svelte';
|
||||
|
||||
import protabs from './index-pro';
|
||||
|
||||
@@ -56,5 +57,6 @@ export default {
|
||||
ImportExportTab,
|
||||
SqlObjectTab,
|
||||
AppLogTab,
|
||||
SettingsTab,
|
||||
...protabs,
|
||||
};
|
||||
|
||||
@@ -6,6 +6,7 @@ import es from '../../../translations/es.json';
|
||||
import zh from '../../../translations/zh.json';
|
||||
import pt from '../../../translations/pt.json';
|
||||
import it from '../../../translations/it.json';
|
||||
import ja from '../../../translations/ja.json';
|
||||
|
||||
import MessageFormat, { MessageFunction } from '@messageformat/core';
|
||||
import { getStringSettingsValue } from './settings/settingsTools';
|
||||
@@ -22,6 +23,7 @@ const translations = {
|
||||
es,
|
||||
pt,
|
||||
it,
|
||||
ja,
|
||||
};
|
||||
const supportedLanguages = Object.keys(translations);
|
||||
|
||||
@@ -31,13 +33,16 @@ const defaultLanguage = 'en';
|
||||
|
||||
let selectedLanguageCache: string | null = null;
|
||||
|
||||
export function getSelectedLanguage(): string {
|
||||
export function getSelectedLanguage(preferrendLanguage?: string): string {
|
||||
if (selectedLanguageCache) return selectedLanguageCache;
|
||||
|
||||
// const browserLanguage = getBrowserLanguage();
|
||||
if (preferrendLanguage == 'auto') {
|
||||
preferrendLanguage = getBrowserLanguage();
|
||||
}
|
||||
|
||||
const selectedLanguage = getElectron()
|
||||
? getStringSettingsValue('localization.language', null)
|
||||
: localStorage.getItem('selectedLanguage');
|
||||
? getStringSettingsValue('localization.language', preferrendLanguage)
|
||||
: localStorage.getItem('selectedLanguage') ?? preferrendLanguage;
|
||||
|
||||
if (!selectedLanguage || !supportedLanguages.includes(selectedLanguage)) return defaultLanguage;
|
||||
return selectedLanguage;
|
||||
@@ -51,8 +56,8 @@ export async function setSelectedLanguage(language: string) {
|
||||
}
|
||||
}
|
||||
|
||||
export function saveSelectedLanguageToCache() {
|
||||
selectedLanguageCache = getSelectedLanguage();
|
||||
export function saveSelectedLanguageToCache(preferrendLanguage?: string) {
|
||||
selectedLanguageCache = getSelectedLanguage(preferrendLanguage);
|
||||
}
|
||||
|
||||
export function getBrowserLanguage(): string {
|
||||
|
||||
@@ -4,6 +4,8 @@ import _ from 'lodash';
|
||||
import { getSchemaList } from './metadataLoaders';
|
||||
import { showSnackbarError } from './snackbar';
|
||||
import { _t } from '../translations';
|
||||
import { apiCall } from './api';
|
||||
import getElectron from './getElectron';
|
||||
|
||||
export class LoadingToken {
|
||||
isCanceled = false;
|
||||
@@ -63,7 +65,8 @@ export function getObjectTypeFieldLabel(objectTypeField, driver?) {
|
||||
if (objectTypeField == 'procedures') return _t('dbObject.procedures', { defaultMessage: 'Procedures' });
|
||||
if (objectTypeField == 'functions') return _t('dbObject.functions', { defaultMessage: 'Functions' });
|
||||
if (objectTypeField == 'triggers') return _t('dbObject.triggers', { defaultMessage: 'Triggers' });
|
||||
if (objectTypeField == 'schedulerEvents') return _t('dbObject.schedulerEvents', { defaultMessage: 'Scheduler Events' });
|
||||
if (objectTypeField == 'schedulerEvents')
|
||||
return _t('dbObject.schedulerEvents', { defaultMessage: 'Scheduler Events' });
|
||||
if (objectTypeField == 'matviews') return _t('dbObject.matviews', { defaultMessage: 'Materialized Views' });
|
||||
if (objectTypeField == 'collections') return _t('dbObject.collections', { defaultMessage: 'Collections/Containers' });
|
||||
return _.startCase(objectTypeField);
|
||||
@@ -151,3 +154,40 @@ export function getKeyTextFromEvent(e) {
|
||||
keyText += e.key;
|
||||
return keyText;
|
||||
}
|
||||
|
||||
export function getDatabasStatusMenu(dbid) {
|
||||
function callSchemalListChanged() {
|
||||
apiCall('database-connections/dispatch-database-changed-event', { event: 'schema-list-changed', ...dbid });
|
||||
}
|
||||
return [
|
||||
{
|
||||
text: _t('command.database.refreshIncremental', { defaultMessage: 'Refresh DB structure (incremental)' }),
|
||||
onClick: () => {
|
||||
apiCall('database-connections/sync-model', dbid);
|
||||
callSchemalListChanged();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: _t('command.database.refreshFull', { defaultMessage: 'Refresh DB structure (full)' }),
|
||||
onClick: () => {
|
||||
apiCall('database-connections/sync-model', { ...dbid, isFullRefresh: true });
|
||||
callSchemalListChanged();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: _t('command.database.reopenConnection', { defaultMessage: 'Reopen connection' }),
|
||||
onClick: () => {
|
||||
apiCall('database-connections/refresh', dbid);
|
||||
callSchemalListChanged();
|
||||
},
|
||||
},
|
||||
{
|
||||
text: _t('command.database.disconnect', { defaultMessage: 'Disconnect' }),
|
||||
onClick: () => {
|
||||
const electron = getElectron();
|
||||
if (electron) apiCall('database-connections/disconnect', dbid);
|
||||
switchCurrentDatabase(null);
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import getElectron from './getElectron';
|
||||
// return derived(editorStore, editor => editor != null);
|
||||
// }
|
||||
|
||||
export default async function saveTabFile(editor, saveMode, folder, format, fileExtension) {
|
||||
export default async function saveTabFile(editor, saveMode, folder, format, fileExtension, defaultTeamFolder) {
|
||||
const tabs = get(openedTabs);
|
||||
const tabid = editor.activator.tabid;
|
||||
const data = editor.getData();
|
||||
@@ -94,6 +94,7 @@ export default async function saveTabFile(editor, saveMode, folder, format, file
|
||||
filePath: savedFilePath,
|
||||
onSave,
|
||||
folid: savedCloudFolderId,
|
||||
defaultTeamFolder,
|
||||
// cntid: savedCloudContentId,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
import _ from 'lodash';
|
||||
import { Condition, dumpSqlInsert, dumpSqlUpdate, Insert, Update, Delete, dumpSqlDelete } from 'dbgate-sqltree';
|
||||
import { TableInfo, SqlDumper } from 'dbgate-types';
|
||||
|
||||
export function createTableRestoreScript(backupTable: TableInfo, originalTable: TableInfo, dmp: SqlDumper) {
|
||||
const bothColumns = _.intersection(
|
||||
backupTable.columns.map(x => x.columnName),
|
||||
originalTable.columns.map(x => x.columnName)
|
||||
);
|
||||
const keyColumns = _.intersection(
|
||||
originalTable.primaryKey?.columns?.map(x => x.columnName) || [],
|
||||
backupTable.columns.map(x => x.columnName)
|
||||
);
|
||||
const valueColumns = _.difference(bothColumns, keyColumns);
|
||||
|
||||
function makeColumnCond(colName: string, operator: '=' | '<>' | '<' | '>' | '<=' | '>=' = '='): Condition {
|
||||
return {
|
||||
conditionType: 'binary',
|
||||
operator,
|
||||
left: {
|
||||
exprType: 'column',
|
||||
columnName: colName,
|
||||
source: { name: originalTable },
|
||||
},
|
||||
right: {
|
||||
exprType: 'column',
|
||||
columnName: colName,
|
||||
source: { alias: 'bak' },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function putTitle(title: string) {
|
||||
dmp.putRaw('\n\n');
|
||||
dmp.comment(`******************** ${title} ********************`);
|
||||
dmp.putRaw('\n');
|
||||
}
|
||||
|
||||
dmp.comment(`Restoring data into table ${originalTable.pureName} from backup table ${backupTable.pureName}`);
|
||||
dmp.putRaw('\n');
|
||||
dmp.comment(`Key columns: ${keyColumns.join(', ')}`);
|
||||
dmp.putRaw('\n');
|
||||
dmp.comment(`Value columns: ${valueColumns.join(', ')}`);
|
||||
dmp.putRaw('\n');
|
||||
dmp.comment(`Follows UPDATE, DELETE, INSERT statements to restore data`);
|
||||
dmp.putRaw('\n');
|
||||
|
||||
const update: Update = {
|
||||
commandType: 'update',
|
||||
from: { name: originalTable },
|
||||
fields: valueColumns.map(colName => ({
|
||||
exprType: 'select',
|
||||
select: {
|
||||
commandType: 'select',
|
||||
from: { name: backupTable, alias: 'bak' },
|
||||
columns: [
|
||||
{
|
||||
exprType: 'column',
|
||||
columnName: colName,
|
||||
source: { alias: 'bak' },
|
||||
},
|
||||
],
|
||||
where: {
|
||||
conditionType: 'and',
|
||||
conditions: keyColumns.map(colName => makeColumnCond(colName)),
|
||||
},
|
||||
},
|
||||
targetColumn: colName,
|
||||
})),
|
||||
where: {
|
||||
conditionType: 'exists',
|
||||
subQuery: {
|
||||
commandType: 'select',
|
||||
from: { name: backupTable, alias: 'bak' },
|
||||
selectAll: true,
|
||||
where: {
|
||||
conditionType: 'and',
|
||||
conditions: [
|
||||
...keyColumns.map(keyColName => makeColumnCond(keyColName)),
|
||||
{
|
||||
conditionType: 'or',
|
||||
conditions: valueColumns.map(colName => makeColumnCond(colName, '<>')),
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
putTitle('UPDATE');
|
||||
dumpSqlUpdate(dmp, update);
|
||||
dmp.endCommand();
|
||||
|
||||
const delcmd: Delete = {
|
||||
commandType: 'delete',
|
||||
from: { name: originalTable },
|
||||
where: {
|
||||
conditionType: 'notExists',
|
||||
subQuery: {
|
||||
commandType: 'select',
|
||||
from: { name: backupTable, alias: 'bak' },
|
||||
selectAll: true,
|
||||
where: {
|
||||
conditionType: 'and',
|
||||
conditions: keyColumns.map(colName => makeColumnCond(colName)),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
putTitle('DELETE');
|
||||
dumpSqlDelete(dmp, delcmd);
|
||||
dmp.endCommand();
|
||||
|
||||
const insert: Insert = {
|
||||
commandType: 'insert',
|
||||
targetTable: originalTable,
|
||||
fields: bothColumns.map(colName => ({
|
||||
targetColumn: colName,
|
||||
exprType: 'column',
|
||||
columnName: colName,
|
||||
source: { alias: 'bak' },
|
||||
})),
|
||||
whereNotExistsSource: { name: backupTable, alias: 'bak' },
|
||||
insertWhereNotExistsCondition: {
|
||||
conditionType: 'and',
|
||||
conditions: keyColumns.map(colName => makeColumnCond(colName)),
|
||||
},
|
||||
};
|
||||
|
||||
putTitle('INSERT');
|
||||
dumpSqlInsert(dmp, insert);
|
||||
dmp.endCommand();
|
||||
}
|
||||
@@ -101,6 +101,7 @@
|
||||
import WidgetTitle from './WidgetTitle.svelte';
|
||||
import JsonExpandedCellView from '../celldata/JsonExpandedCellView.svelte';
|
||||
import XmlCellView from '../celldata/XmlCellView.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
let selectedFormatType = 'autodetect';
|
||||
|
||||
@@ -116,7 +117,7 @@
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<WidgetTitle>Cell data view</WidgetTitle>
|
||||
<WidgetTitle>{_t('cellDataWidget.title', { defaultMessage: "Cell data view" })}</WidgetTitle>
|
||||
<div class="main">
|
||||
<div class="toolbar">
|
||||
Format:<span> </span>
|
||||
@@ -126,18 +127,18 @@
|
||||
on:change={e => (selectedFormatType = e.detail)}
|
||||
data-testid="CellDataWidget_selectFormat"
|
||||
options={[
|
||||
{ value: 'autodetect', label: `Autodetect - ${autodetectFormat.title}` },
|
||||
{ value: 'autodetect', label: _t('cellDataWidget.autodetect', { defaultMessage: "Autodetect - {autoDetectTitle}", values : { autoDetectTitle: autodetectFormat.title } }) },
|
||||
...formats.map(fmt => ({ label: fmt.title, value: fmt.type })),
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
<div class="data">
|
||||
{#if usedFormat.single && selection?.length != 1}
|
||||
<ErrorInfo message="Must be selected one cell" alignTop />
|
||||
<ErrorInfo message={_t('cellDataWidget.mustSelectOneCell', { defaultMessage: "Must be selected one cell" })} alignTop />
|
||||
{:else if usedFormat == null}
|
||||
<ErrorInfo message="Format not selected" alignTop />
|
||||
<ErrorInfo message={_t('cellDataWidget.formatNotSelected', { defaultMessage: "Format not selected" })} alignTop />
|
||||
{:else if !selection || selection.length == 0}
|
||||
<ErrorInfo message="No data selected" alignTop />
|
||||
<ErrorInfo message={_t('cellDataWidget.noDataSelected', { defaultMessage: "No data selected" })} alignTop />
|
||||
{:else}
|
||||
<svelte:component this={usedFormat?.component} {selection} />
|
||||
{/if}
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Saved files" name="files" height="70%" storageName="savedFilesWidget">
|
||||
<WidgetColumnBarItem title={_t('files.savedFiles', { defaultMessage: "Saved files" })} name="files" height="70%" storageName="savedFilesWidget">
|
||||
<SavedFilesList />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
{#if hasPermission('files/favorites/read')}
|
||||
<WidgetColumnBarItem title="Favorites" name="favorites" storageName="favoritesWidget">
|
||||
<WidgetColumnBarItem title={_t('files.favorites', { defaultMessage: "Favorites" })} name="favorites" storageName="favoritesWidget">
|
||||
<WidgetsInnerContainer>
|
||||
<AppObjectList list={$favorites || []} module={favoriteFileAppObject} />
|
||||
</WidgetsInnerContainer>
|
||||
|
||||
@@ -13,13 +13,14 @@
|
||||
import WidgetColumnBar from './WidgetColumnBar.svelte';
|
||||
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
$: favorites = useFavorites();
|
||||
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Recently closed tabs" name="closedTabs" storageName='closedTabsWidget'>
|
||||
<WidgetColumnBarItem title={_t('history.recentlyClosedTabs', { defaultMessage: "Recently closed tabs" })} name="closedTabs" storageName='closedTabsWidget'>
|
||||
<WidgetsInnerContainer>
|
||||
<AppObjectList
|
||||
list={_.sortBy(
|
||||
@@ -30,7 +31,7 @@
|
||||
/>
|
||||
</WidgetsInnerContainer>
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title="Query history" name="queryHistory" storageName='queryHistoryWidget'>
|
||||
<WidgetColumnBarItem title={_t('history.queryHistory', { defaultMessage: "Query history" })} name="queryHistory" storageName='queryHistoryWidget'>
|
||||
<QueryHistoryList />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
|
||||
@@ -4,13 +4,15 @@
|
||||
|
||||
import WidgetColumnBar from './WidgetColumnBar.svelte';
|
||||
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
|
||||
|
||||
import { _t } from '../translations';
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Installed extensions" name="installed" height="50%" storageName='installedPluginsWidget'>
|
||||
<WidgetColumnBarItem title={_t('widgets.installedExtensions', { defaultMessage: 'Installed extensions' })} name="installed" height="50%" storageName='installedPluginsWidget'>
|
||||
<InstalledPluginsList />
|
||||
</WidgetColumnBarItem>
|
||||
<WidgetColumnBarItem title="Available extensions" name="all" storageName='allPluginsWidget'>
|
||||
<WidgetColumnBarItem title={_t('widgets.availableExtensions', { defaultMessage: 'Available extensions' })} name="all" storageName='allPluginsWidget'>
|
||||
<AvailablePluginsList />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
|
||||
@@ -30,11 +30,11 @@
|
||||
<WidgetColumnBarItem title="Public Knowledge Base" name="publicCloud" storageName="publicCloudItems">
|
||||
<WidgetsInnerContainer>
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search public files" bind:value={filter} />
|
||||
<SearchInput placeholder={_t('publicCloudWidget.searchPublicFiles', { defaultMessage: "Search public files" })} bind:value={filter} />
|
||||
<CloseSearchButton bind:filter />
|
||||
<InlineButton
|
||||
on:click={handleRefreshPublic}
|
||||
title="Refresh files"
|
||||
title={_t('publicCloudWidget.refreshFiles', { defaultMessage: "Refresh files" })}
|
||||
data-testid="CloudItemsWidget_buttonRefreshPublic"
|
||||
>
|
||||
<FontIcon icon="icon refresh" />
|
||||
@@ -52,9 +52,9 @@
|
||||
<ErrorInfo message="No files found for your configuration" />
|
||||
<div class="error-info">
|
||||
<div class="m-1">
|
||||
Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first.
|
||||
{_t('publicCloudWidget.onlyRelevantFilesListed', { defaultMessage: "Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first." })}
|
||||
</div>
|
||||
<FormStyledButton value={`Refresh list`} skipWidth on:click={handleRefreshPublic} />
|
||||
<FormStyledButton value={_t('publicCloudWidget.refreshList', { defaultMessage: "Refresh list" })} skipWidth on:click={handleRefreshPublic} />
|
||||
</div>
|
||||
{/if}
|
||||
</WidgetsInnerContainer>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
|
||||
import { apiCall, apiOff, apiOn } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
let filter = '';
|
||||
let search = '';
|
||||
@@ -38,7 +39,7 @@
|
||||
</script>
|
||||
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search query history" {filter} bind:value={filter} />
|
||||
<SearchInput placeholder={_t('history.searchQueryHistory', { defaultMessage: "Search query history" })} {filter} bind:value={filter} />
|
||||
<CloseSearchButton
|
||||
bind:filter
|
||||
on:click={() => {
|
||||
@@ -54,7 +55,7 @@
|
||||
on:click={() => {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Query #',
|
||||
title: _t('database.queryDesigner', { defaultMessage: "Query #" }),
|
||||
icon: 'icon sql-file',
|
||||
tabComponent: 'QueryTab',
|
||||
focused: true,
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import InlineUploadButton from '../buttons/InlineUploadButton.svelte';
|
||||
import { DATA_FOLDER_NAMES } from 'dbgate-tools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
let filter = '';
|
||||
|
||||
@@ -65,19 +66,19 @@
|
||||
</script>
|
||||
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search saved files" bind:value={filter} />
|
||||
<SearchInput placeholder={_t('files.searchSavedFiles', { defaultMessage: "Search saved files" })} bind:value={filter} />
|
||||
<CloseSearchButton bind:filter />
|
||||
<InlineUploadButton
|
||||
filters={[
|
||||
{
|
||||
name: `All supported files`,
|
||||
name: _t('files.allSupportedFiles', { defaultMessage: "All supported files" }),
|
||||
extensions: ['sql'],
|
||||
},
|
||||
{ name: `SQL files`, extensions: ['sql'] },
|
||||
{ name: _t('files.sqlFiles', { defaultMessage: "SQL files" }), extensions: ['sql'] },
|
||||
]}
|
||||
onProcessFile={handleUploadedFile}
|
||||
/>
|
||||
<InlineButton on:click={handleRefreshFiles} title="Refresh files" data-testid="SavedFileList_buttonRefresh">
|
||||
<InlineButton on:click={handleRefreshFiles} title={_t('files.refreshFiles', { defaultMessage: "Refresh files" })} data-testid="SavedFileList_buttonRefresh">
|
||||
<FontIcon icon="icon refresh" />
|
||||
</InlineButton>
|
||||
</SearchBoxWrapper>
|
||||
@@ -86,7 +87,7 @@
|
||||
<AppObjectList
|
||||
list={files}
|
||||
module={savedFileAppObject}
|
||||
groupFunc={data => (data.teamFileId ? 'Team files' : dataFolderTitle(data.folder))}
|
||||
groupFunc={data => (data.teamFileId ? _t('files.teamFiles', { defaultMessage: "Team files" }) : dataFolderTitle(data.folder))}
|
||||
{filter}
|
||||
/>
|
||||
</WidgetsInnerContainer>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
import { chevronExpandIcon } from '../icons/expandIcons';
|
||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||
import LoadingInfo from '../elements/LoadingInfo.svelte';
|
||||
import { getObjectTypeFieldLabel } from '../utility/common';
|
||||
import { getDatabasStatusMenu, getObjectTypeFieldLabel } from '../utility/common';
|
||||
import DropDownButton from '../buttons/DropDownButton.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
|
||||
@@ -120,11 +120,6 @@
|
||||
// setInterval(() => (generateIndex += 1), 2000);
|
||||
// $: objectList = generateObjectList(generateIndex);
|
||||
|
||||
const handleRefreshDatabase = () => {
|
||||
apiCall('database-connections/refresh', { conid, database });
|
||||
apiCall('database-connections/dispatch-database-changed-event', { event: 'schema-list-changed', conid, database });
|
||||
};
|
||||
|
||||
function createAddMenu() {
|
||||
const res = [];
|
||||
if (driver?.databaseEngineTypes?.includes('document')) {
|
||||
@@ -147,6 +142,15 @@
|
||||
return res;
|
||||
}
|
||||
|
||||
function createRefreshDatabaseMenu() {
|
||||
return getDatabasStatusMenu({ conid, database });
|
||||
}
|
||||
|
||||
function handleFullRefreshDatabase() {
|
||||
apiCall('database-connections/sync-model', { conid, database, isFullRefresh: true });
|
||||
apiCall('database-connections/dispatch-database-changed-event', { event: 'schema-list-changed', conid, database });
|
||||
}
|
||||
|
||||
function createSearchMenu() {
|
||||
const res = [];
|
||||
res.push({ label: _t('sqlObject.searchBy', { defaultMessage: 'Search by:' }), isBold: true, disabled: true });
|
||||
@@ -228,6 +232,15 @@
|
||||
$focusedConnectionOrDatabase?.database != extractDbNameFromComposite(database)));
|
||||
|
||||
// $: console.log('STATUS', $status);
|
||||
|
||||
function getAppObjectGroup(data) {
|
||||
if (data.objectTypeField == 'tables') {
|
||||
if (data.pureName.match(databaseObjectAppObject.TABLE_BACKUP_REGEX)) {
|
||||
return _t('dbObject.tableBackups', { defaultMessage: 'Table Backups' });
|
||||
}
|
||||
}
|
||||
return getObjectTypeFieldLabel(data.objectTypeField, driver);
|
||||
}
|
||||
</script>
|
||||
|
||||
{#if $status && $status.name == 'error'}
|
||||
@@ -237,7 +250,18 @@
|
||||
|
||||
<WidgetsInnerContainer hideContent={differentFocusedDb}>
|
||||
<ErrorInfo message={$status.message} icon="img error" />
|
||||
<InlineButton on:click={handleRefreshDatabase}>{_t('common.refresh', { defaultMessage: 'Refresh' })}</InlineButton>
|
||||
<InlineButton on:click={handleFullRefreshDatabase}
|
||||
>{_t('common.refresh', { defaultMessage: 'Refresh' })}</InlineButton
|
||||
>
|
||||
|
||||
<DropDownButton
|
||||
menu={createRefreshDatabaseMenu}
|
||||
title={_t('sqlObjectList.refreshDatabase', { defaultMessage: 'Refresh database connection and object list' })}
|
||||
square
|
||||
narrow={false}
|
||||
data-testid="SqlObjectList_refreshButton"
|
||||
icon="icon dots-vertical"
|
||||
/>
|
||||
</WidgetsInnerContainer>
|
||||
{:else if objectList.length == 0 && $status && $status.name != 'pending' && $status.name != 'checkStructure' && $status.name != 'loadStructure' && $objects}
|
||||
<SchemaSelector
|
||||
@@ -262,7 +286,7 @@
|
||||
icon="img alert"
|
||||
/>
|
||||
<div class="m-1" />
|
||||
<InlineButton on:click={handleRefreshDatabase}>{_t('common.refresh', { defaultMessage: 'Refresh' })}</InlineButton>
|
||||
<InlineButton on:click={handleFullRefreshDatabase}>{_t('common.refresh', { defaultMessage: 'Refresh' })}</InlineButton>
|
||||
{#if driver?.databaseEngineTypes?.includes('sql')}
|
||||
<div class="m-1" />
|
||||
<InlineButton on:click={() => runCommand('new.table')}
|
||||
@@ -298,14 +322,14 @@
|
||||
{#if !filter}
|
||||
<DropDownButton icon="icon plus-thick" menu={createAddMenu} />
|
||||
{/if}
|
||||
<InlineButton
|
||||
on:click={handleRefreshDatabase}
|
||||
<DropDownButton
|
||||
menu={createRefreshDatabaseMenu}
|
||||
title={_t('sqlObjectList.refreshDatabase', { defaultMessage: 'Refresh database connection and object list' })}
|
||||
square
|
||||
narrow={false}
|
||||
data-testid="SqlObjectList_refreshButton"
|
||||
>
|
||||
<FontIcon icon="icon refresh" />
|
||||
</InlineButton>
|
||||
icon="icon dots-vertical"
|
||||
/>
|
||||
</SearchBoxWrapper>
|
||||
<SchemaSelector
|
||||
schemaList={_.isArray($schemaList) ? $schemaList : null}
|
||||
@@ -356,7 +380,7 @@
|
||||
.filter(x => x.schemaName == null || ($appliedCurrentSchema ? x.schemaName == $appliedCurrentSchema : true))
|
||||
.map(x => ({ ...x, conid, database }))}
|
||||
module={databaseObjectAppObject}
|
||||
groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField, driver)}
|
||||
groupFunc={getAppObjectGroup}
|
||||
subItemsComponent={(data, { isExpandedBySearch }) =>
|
||||
data.objectTypeField == 'procedures' || data.objectTypeField == 'functions'
|
||||
? isExpandedBySearch
|
||||
|
||||
@@ -35,16 +35,16 @@
|
||||
getCurrentConfig().storageDatabase && {
|
||||
icon: 'icon admin',
|
||||
name: 'admin',
|
||||
title: 'Administration',
|
||||
title: _t('widgets.administration', { defaultMessage: 'Administration' }),
|
||||
},
|
||||
{
|
||||
icon: 'icon database',
|
||||
name: 'database',
|
||||
title: 'Database connections',
|
||||
title: _t('widgets.databaseConnections', { defaultMessage: 'Database connections' }),
|
||||
},
|
||||
getCurrentConfig().allowPrivateCloud && {
|
||||
name: 'cloud-private',
|
||||
title: 'DbGate Cloud',
|
||||
title: _t('widgets.dbgateCloud', { defaultMessage: 'DbGate Cloud' }),
|
||||
icon: 'icon cloud-private',
|
||||
},
|
||||
|
||||
@@ -55,17 +55,17 @@
|
||||
{
|
||||
icon: 'icon file',
|
||||
name: 'file',
|
||||
title: 'Favorites & Saved files',
|
||||
title: _t('widgets.favoritesAndSavedFiles', { defaultMessage: 'Favorites & Saved files' }),
|
||||
},
|
||||
{
|
||||
icon: 'icon history',
|
||||
name: 'history',
|
||||
title: 'Query history & Closed tabs',
|
||||
title: _t('widgets.queryHistoryAndClosedTabs', { defaultMessage: 'Query history & Closed tabs' }),
|
||||
},
|
||||
isProApp() && {
|
||||
icon: 'icon archive',
|
||||
name: 'archive',
|
||||
title: 'Archive (saved tabular data)',
|
||||
title: _t('widgets.archive', { defaultMessage: 'Archive (saved tabular data)' }),
|
||||
},
|
||||
// {
|
||||
// icon: 'icon plugin',
|
||||
@@ -75,17 +75,17 @@
|
||||
{
|
||||
icon: 'icon cell-data',
|
||||
name: 'cell-data',
|
||||
title: 'Selected cell data detail view',
|
||||
title: _t('widgets.selectedCellDataDetailView', { defaultMessage: 'Selected cell data detail view' }),
|
||||
},
|
||||
{
|
||||
name: 'cloud-public',
|
||||
title: 'DbGate Cloud',
|
||||
title: _t('widgets.dbgateCloud', { defaultMessage: 'DbGate Cloud' }),
|
||||
icon: 'icon cloud-public',
|
||||
},
|
||||
{
|
||||
icon: 'icon premium',
|
||||
name: 'premium',
|
||||
title: 'Premium promo',
|
||||
title: _t('widgets.premiumPromo', { defaultMessage: 'Premium promo' }),
|
||||
isPremiumPromo: true,
|
||||
},
|
||||
// {
|
||||
@@ -113,32 +113,12 @@
|
||||
//const handleChangeWidget= e => (selectedWidget.set(item.name))
|
||||
|
||||
function handleSettingsMenu() {
|
||||
const rect = domSettings.getBoundingClientRect();
|
||||
const left = rect.right;
|
||||
const top = rect.bottom;
|
||||
const items = [
|
||||
hasPermission('settings/change') && { command: 'settings.show' },
|
||||
{ command: 'theme.changeTheme' },
|
||||
hasPermission('settings/change') && { command: 'settings.commands' },
|
||||
hasPermission('widgets/plugins') && {
|
||||
text: _t('widgets.managePlugins', { defaultMessage: 'Manage plugins' }),
|
||||
onClick: () => {
|
||||
$selectedWidget = 'plugins';
|
||||
$visibleWidgetSideBar = true;
|
||||
},
|
||||
},
|
||||
hasPermission('application-log') && {
|
||||
text: _t('widgets.viewApplicationLogs', { defaultMessage: 'View application logs' }),
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'Application log',
|
||||
icon: 'img applog',
|
||||
tabComponent: 'AppLogTab',
|
||||
});
|
||||
},
|
||||
},
|
||||
];
|
||||
currentDropDownMenu.set({ left, top, items });
|
||||
openNewTab({
|
||||
title: 'Settings',
|
||||
icon: 'icon settings',
|
||||
tabComponent: 'SettingsTab',
|
||||
props: {},
|
||||
});
|
||||
}
|
||||
|
||||
function handleCloudAccountMenu() {
|
||||
@@ -213,7 +193,7 @@
|
||||
class="wrapper"
|
||||
on:click={() => showModal(NewObjectModal)}
|
||||
data-testid="WidgetIconPanel_addButton"
|
||||
title="Add New"
|
||||
title={_t('widgets.addNew', { defaultMessage: 'Add New' })}
|
||||
>
|
||||
<FontIcon icon="icon add" />
|
||||
</div>
|
||||
|
||||
@@ -84,9 +84,7 @@ class Analyser extends DatabaseAnalyser {
|
||||
|
||||
async _runAnalysis() {
|
||||
this.feedback({ analysingMessage: 'DBGM-00241 Loading tables' });
|
||||
const tables = await this.analyserQuery(this.driver.dialect.stringAgg ? 'tableModifications' : 'tableList', [
|
||||
'tables',
|
||||
]);
|
||||
const tables = await this.analyserQuery('tableList', ['tables']);
|
||||
|
||||
this.feedback({ analysingMessage: 'DBGM-00242 Loading columns' });
|
||||
const columns = await this.analyserQuery('columns', ['tables', 'views']);
|
||||
@@ -396,9 +394,6 @@ class Analyser extends DatabaseAnalyser {
|
||||
}
|
||||
|
||||
async _getFastSnapshot() {
|
||||
const tableModificationsQueryData = this.driver.dialect.stringAgg
|
||||
? await this.analyserQuery('tableModifications')
|
||||
: null;
|
||||
const viewModificationsQueryData = await this.analyserQuery('viewModifications');
|
||||
const matviewModificationsQueryData = this.driver.dialect.materializedViews
|
||||
? await this.analyserQuery('matviewModifications')
|
||||
@@ -406,15 +401,7 @@ class Analyser extends DatabaseAnalyser {
|
||||
const routineModificationsQueryData = await this.analyserQuery('routineModifications');
|
||||
|
||||
return {
|
||||
tables: tableModificationsQueryData
|
||||
? tableModificationsQueryData.rows.map(x => ({
|
||||
objectId: `tables:${x.schema_name}.${x.pure_name}`,
|
||||
pureName: x.pure_name,
|
||||
schemaName: x.schema_name,
|
||||
sizeBytes: x.size_bytes,
|
||||
contentHash: `${x.hash_code_columns}-${x.hash_code_constraints}`,
|
||||
}))
|
||||
: null,
|
||||
tables: null,
|
||||
views: viewModificationsQueryData.rows.map(x => ({
|
||||
objectId: `views:${x.schema_name}.${x.pure_name}`,
|
||||
pureName: x.pure_name,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
const columns = require('./columns');
|
||||
const tableModifications = require('./tableModifications');
|
||||
const tableList = require('./tableList');
|
||||
const viewModifications = require('./viewModifications');
|
||||
const matviewModifications = require('./matviewModifications');
|
||||
@@ -25,7 +24,6 @@ const fk_keyColumnUsage = require('./fk_key_column_usage');
|
||||
|
||||
module.exports = {
|
||||
columns,
|
||||
tableModifications,
|
||||
tableList,
|
||||
viewModifications,
|
||||
primaryKeys,
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
module.exports = `
|
||||
select
|
||||
table_constraints.constraint_schema as "constraint_schema",
|
||||
table_constraints.constraint_name as "constraint_name",
|
||||
table_constraints.table_schema as "schema_name",
|
||||
table_constraints.table_name as "pure_name",
|
||||
key_column_usage.column_name as "column_name"
|
||||
from information_schema.table_constraints
|
||||
inner join information_schema.key_column_usage on table_constraints.table_name = key_column_usage.table_name and table_constraints.constraint_name = key_column_usage.constraint_name
|
||||
and table_constraints.table_schema = key_column_usage.table_schema
|
||||
where
|
||||
table_constraints.table_schema !~ '^_timescaledb_'
|
||||
and table_constraints.constraint_type = 'PRIMARY KEY'
|
||||
and ('tables:' || table_constraints.table_schema || '.' || table_constraints.table_name) =OBJECT_ID_CONDITION
|
||||
and table_constraints.table_schema =SCHEMA_NAME_CONDITION
|
||||
order by key_column_usage.ordinal_position
|
||||
SELECT
|
||||
n.nspname AS "constraint_schema",
|
||||
c.conname AS "constraint_name",
|
||||
n.nspname AS "schema_name",
|
||||
t.relname AS "pure_name",
|
||||
a.attname AS "column_name"
|
||||
FROM pg_catalog.pg_constraint AS c
|
||||
JOIN pg_catalog.pg_class AS t
|
||||
ON t.oid = c.conrelid
|
||||
JOIN pg_catalog.pg_namespace AS n
|
||||
ON n.oid = t.relnamespace
|
||||
JOIN LATERAL unnest(c.conkey) WITH ORDINALITY AS cols(attnum, ordinal_position)
|
||||
ON TRUE
|
||||
JOIN pg_catalog.pg_attribute AS a
|
||||
ON a.attrelid = t.oid
|
||||
AND a.attnum = cols.attnum
|
||||
WHERE
|
||||
c.contype = 'p' -- PRIMARY KEY
|
||||
AND n.nspname !~ '^_timescaledb_'
|
||||
AND ('tables:' || n.nspname || '.' || t.relname) =OBJECT_ID_CONDITION
|
||||
AND n.nspname =SCHEMA_NAME_CONDITION
|
||||
ORDER BY cols.ordinal_position
|
||||
`;
|
||||
|
||||
@@ -5,6 +5,6 @@ from information_schema.tables infoTables
|
||||
where infoTables.table_type not like '%VIEW%'
|
||||
and ('tables:' || infoTables.table_schema || '.' || infoTables.table_name) =OBJECT_ID_CONDITION
|
||||
and infoTables.table_schema <> 'pg_internal'
|
||||
and infoTables.table_schema !~ '^_timescaledb_'
|
||||
and infoTables.table_schema !~ '^_timescaledb_'
|
||||
and infoTables.table_schema =SCHEMA_NAME_CONDITION
|
||||
`;
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
module.exports = `
|
||||
select infoTables.table_schema as "schema_name", infoTables.table_name as "pure_name",
|
||||
(
|
||||
select $md5Function(string_agg(
|
||||
infoColumns.column_name || '|' || infoColumns.data_type || '|' || infoColumns.is_nullable::varchar(255) || '|' || coalesce(infoColumns.character_maximum_length, -1)::varchar(255)
|
||||
|| '|' || coalesce(infoColumns.numeric_precision, -1)::varchar(255) ,
|
||||
',' order by infoColumns.ordinal_position
|
||||
)) as "hash_code_columns"
|
||||
from information_schema.columns infoColumns
|
||||
where infoColumns.table_schema = infoTables.table_schema and infoColumns.table_name = infoTables.table_name
|
||||
),
|
||||
(
|
||||
select $md5Function(string_agg(
|
||||
infoConstraints.constraint_name || '|' || infoConstraints.constraint_type ,
|
||||
',' order by infoConstraints.constraint_name
|
||||
)) as "hash_code_constraints"
|
||||
from information_schema.table_constraints infoConstraints
|
||||
where infoConstraints.table_schema = infoTables.table_schema and infoConstraints.table_name = infoTables.table_name
|
||||
),
|
||||
pg_relation_size('"'||infoTables.table_schema||'"."'||infoTables.table_name||'"') as "size_bytes"
|
||||
|
||||
from information_schema.tables infoTables
|
||||
where infoTables.table_type not like '%VIEW%'
|
||||
and ('tables:' || infoTables.table_schema || '.' || infoTables.table_name) =OBJECT_ID_CONDITION
|
||||
and infoTables.table_schema <> 'pg_internal'
|
||||
and infoTables.table_schema !~ '^_timescaledb_'
|
||||
and infoTables.table_schema =SCHEMA_NAME_CONDITION
|
||||
`;
|
||||
+102
-1
@@ -3,6 +3,11 @@
|
||||
"app.loading_plugin": "Načítám plugin {plugin} ...",
|
||||
"app.preparingPlugins": "Příprava pluginů...",
|
||||
"app.starting": "Spouštění DbGate",
|
||||
"cellDataWidget.autodetect": "Autodetekce - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Formát není vybrán",
|
||||
"cellDataWidget.mustSelectOneCell": "Musí být vybrána jedna buňka",
|
||||
"cellDataWidget.noDataSelected": "Nejsou vybrána žádná data",
|
||||
"cellDataWidget.title": "Zobrazení dat buňky",
|
||||
"chart.detect": "Rozpoznat graf",
|
||||
"chart.open": "Otevřít graf",
|
||||
"clipboard.SQLInsert": "SQL INSERT příkazy",
|
||||
@@ -40,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Řídký",
|
||||
"columnEditor.isUnsigned": "Bez znaménka",
|
||||
"columnEditor.isZerofill": "Doplňování nul",
|
||||
"columnLine.addReference": "Přidat referenci",
|
||||
"columnLine.sortAscending": "Seřadit vzestupně",
|
||||
"columnLine.sortDescending": "Seřadit sestupně",
|
||||
"columnLine.unsort": "Zrušit řazení",
|
||||
"columnsConstraintEditor.addNewColumn": "Přidat nový sloupec",
|
||||
"columnsConstraintEditor.chooseColumn": "Vybrat sloupec",
|
||||
"columnsConstraintEditor.selectColumn": "Vybrat sloupec",
|
||||
@@ -289,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Zadejte požadovanou kombinaci kláves a stiskněte ENTER",
|
||||
"common.addNew": "Přidat nový",
|
||||
"common.advanced": "Pokročilé",
|
||||
"common.allFields": "Všechny {field}",
|
||||
"common.archive": "Archiv (JSONL)",
|
||||
"common.cancel": "Zrušit",
|
||||
"common.close": "Zavřít",
|
||||
@@ -315,6 +325,7 @@
|
||||
"common.kill": "Ukončit",
|
||||
"common.loadingData": "Načítání dat",
|
||||
"common.name": "Název",
|
||||
"common.newConnection": "Nové připojení",
|
||||
"common.notSelectedOptional": "(nezvoleno - volitelné)",
|
||||
"common.parameters": "Parametry",
|
||||
"common.passwordEncrypted": "Heslo je zašifrované",
|
||||
@@ -324,6 +335,7 @@
|
||||
"common.queryEditor": "Editor SQL dotazů",
|
||||
"common.refresh": "Obnovit",
|
||||
"common.remove": "Odstranit",
|
||||
"common.removeAll": "Odstranit vše",
|
||||
"common.reset": "Resetovat",
|
||||
"common.save": "Uložit",
|
||||
"common.saveAndNext": "Uložit a další",
|
||||
@@ -331,6 +343,7 @@
|
||||
"common.schema": "Schéma",
|
||||
"common.search": "Hledat",
|
||||
"common.searchBy": "Hledat podle:",
|
||||
"common.server": "Server",
|
||||
"common.sqlGenerator": "SQL Generátor",
|
||||
"common.table": "Tabulka",
|
||||
"common.testingConnection": "Testování připojení",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Triggery",
|
||||
"dbObject.truncateTable": "Vyprázdnit tabulku",
|
||||
"dbObject.views": "Pohledy",
|
||||
"designerTable.addReferences": "Přidat reference",
|
||||
"designerTable.changeColor": "Změnit barvu",
|
||||
"designerTable.defineVirtualForeignKey": "Definovat virtuální cizí klíč",
|
||||
"designerTable.newAlias": "Nový alias",
|
||||
"designerTable.removeTableAlias": "Odstranit alias tabulky",
|
||||
"designerTable.setTableAlias": "Nastavit alias tabulky",
|
||||
"error.driverNotFound": "Neplatné připojení k databázi, ovladač nebyl nalezen",
|
||||
"error.selectedCloudConnection": "Vybrané připojení je z DbGate cloudu",
|
||||
"error.selectedNotCloudConnection": "Vybrané připojení není z DbGate cloudu",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "Soubory návrháře dotazů",
|
||||
"file.sqlFiles": "Soubory SQL",
|
||||
"file.sqliteDatabase": "Databáze SQLite",
|
||||
"files.allSupportedFiles": "Všechny podporované soubory",
|
||||
"files.favorites": "Oblíbené",
|
||||
"files.openFile": "Otevřít soubor",
|
||||
"files.refreshFiles": "Obnovit soubory",
|
||||
"files.savedFiles": "Uložené soubory",
|
||||
"files.searchSavedFiles": "Hledat v uložených souborech",
|
||||
"files.sqlFiles": "Soubory SQL",
|
||||
"files.teamFiles": "Týmové soubory",
|
||||
"files.uploadFile": "Nahrát soubor",
|
||||
"filter.after": "Po...",
|
||||
"filter.and": "A",
|
||||
"filter.arrayIsEmpty": "Pole je prázdné",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Referenční sloupec - ",
|
||||
"foreignKeyEditor.referencedTable": "Odkazovaná tabulka",
|
||||
"foreignKeyEditor.tableNotSet": "(tabulka není nastavena)",
|
||||
"history.queryHistory": "Historie dotazů",
|
||||
"history.recentlyClosedTabs": "Nedávno zavřené karty",
|
||||
"history.searchQueryHistory": "Hledat v historii dotazů",
|
||||
"importExport.action": "Akce",
|
||||
"importExport.addWebUrl": "Přidat webovou URL",
|
||||
"importExport.advancedConfiguration": "Pokročilá konfigurace",
|
||||
"importExport.archiveFolder": "Složka archivu",
|
||||
"importExport.columns": "Sloupce",
|
||||
"importExport.createZipFileInArchive": "Vytvořit ZIP soubor v archivu",
|
||||
"importExport.currentArchive": "Aktuální archiv",
|
||||
"importExport.currentDatabase": "Aktuální DB",
|
||||
"importExport.dragDropImportedFilesHere": "Přetáhněte sem importované soubory",
|
||||
"importExport.exportToZipArchive": "Exportovat do ZIP archivu",
|
||||
"importExport.exportToZipFile": "Exportovat do ZIP souboru",
|
||||
"importExport.generateScript": "Vygenerovat skript",
|
||||
"importExport.importFromZipArchive": "Importovat z ZIP archivu",
|
||||
"importExport.importFromZipFile": "Importovat z ZIP souboru (v archivní složce)",
|
||||
"importExport.mapSourceTablesFiles": "Mapovat zdrojové tabulky/soubory",
|
||||
"importExport.messages": "Zprávy",
|
||||
"importExport.newArchive": "Nový archiv",
|
||||
"importExport.outputFiles": "Výstupní soubory",
|
||||
"importExport.preview": "Náhled",
|
||||
"importExport.processingImportExport": "Zpracovávání importu/exportu ...",
|
||||
"importExport.run": "Spustit",
|
||||
"importExport.schedule": "Plán",
|
||||
"importExport.source": "Zdroj",
|
||||
"importExport.sourceConfiguration": "Konfigurace zdroje",
|
||||
"importExport.sourceFiles": "Zdrojové soubory",
|
||||
"importExport.startVariableIndex": "Počáteční index proměnné",
|
||||
"importExport.status": "Stav",
|
||||
"importExport.stop": "Zastavit",
|
||||
"importExport.storageType": "Typ úložiště",
|
||||
"importExport.tablesViewsCollections": "Tabulky / pohledy / kolekce",
|
||||
"importExport.target": "Cíl",
|
||||
"importExport.targetConfiguration": "Konfigurace cíle",
|
||||
"indexEditor.filteredIndexCondition": "Podmínka filtrovaného indexu",
|
||||
"indexEditor.indexName": "Název indexu",
|
||||
"indexEditor.isUnique": "Je jedinečný index",
|
||||
"logs.autoScroll": "Automatické posouvání",
|
||||
"logs.caller": "Volající:",
|
||||
"logs.callerTab": "Volající",
|
||||
"logs.chooseDate": "Vyberte datum",
|
||||
"logs.codeTab": "Kód",
|
||||
"logs.connectionId": "ID připojení:",
|
||||
"logs.connectionTab": "Připojení",
|
||||
"logs.database": "Databáze:",
|
||||
"logs.databaseTab": "Databáze",
|
||||
"logs.date": "Datum:",
|
||||
"logs.dateTab": "Datum",
|
||||
"logs.details": "Detaily",
|
||||
"logs.engine": "Engine:",
|
||||
"logs.engineTab": "Engine",
|
||||
"logs.loadingNextRows": "Načítání dalších řádků...",
|
||||
"logs.message": "Zpráva:",
|
||||
"logs.messageCode": "Kód zprávy:",
|
||||
"logs.messageTab": "Zpráva",
|
||||
"logs.name": "Název:",
|
||||
"logs.nameTab": "Název",
|
||||
"logs.noDataForSelectedDate": "Pro vybrané datum nejsou k dispozici žádná data",
|
||||
"logs.recentLogs": "Nedávné logy",
|
||||
"logs.refresh": "Obnovit",
|
||||
"logs.time": "Čas:",
|
||||
"logs.timeTab": "Čas",
|
||||
"menu.edit": "Upravit",
|
||||
"menu.file": "Soubor",
|
||||
"menu.help": "Nápověda",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "SQL generátor není pro aktuální databázi k dispozici",
|
||||
"newObject.tableDescription": "Vytvořit tabulku v aktuální databázi",
|
||||
"newObject.tableDisabled": "Vytvoření tabulky není pro aktuální databázi k dispozici",
|
||||
"plugins.searchExtensionsOnWeb": "Hledat rozšíření na webu",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Jsou zobrazeny pouze soubory relevantní pro vaše připojení, platformu a edici DbGate. Nejprve prosím definujte připojení.",
|
||||
"publicCloudWidget.refreshFiles": "Obnovit soubory",
|
||||
"publicCloudWidget.refreshList": "Obnovit seznam",
|
||||
"publicCloudWidget.searchPublicFiles": "Hledat veřejné soubory",
|
||||
"query.limitRows": "Omezit na {queryRowsLimit} řádků",
|
||||
"query.named": ":proměnná",
|
||||
"query.noParameters": "(žádné parametry)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Název sloupce",
|
||||
"sqlObject.databaseEmpty": "Databáze {database} je prázdná nebo struktura není načtena, stiskněte tlačítko Obnovit pro znovunačtení struktury",
|
||||
"sqlObject.loadingStructure": "Načítání struktury databáze",
|
||||
"sqlObject.name": "Název",
|
||||
"sqlObject.newCollection": "Nová kolekce/kontejner",
|
||||
"sqlObject.rowCount": "Počet řádků",
|
||||
"sqlObject.schemaName": "Schéma",
|
||||
"sqlObject.search.placeholder": "Hledat v tabulkách, pohledech, procedurách",
|
||||
"sqlObject.searchBy": "Hledat podle:",
|
||||
"sqlObject.sizeBytes": "Velikost (bajty)",
|
||||
"sqlObject.sortBy": "Seřadit podle:",
|
||||
"sqlObject.tableComment": "Komentář tabulky",
|
||||
"sqlObject.tableEngine": "Engine tabulky",
|
||||
"sqlObject.tableViewProcedureName": "Název tabulky/pohledu/procedury",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Klíče",
|
||||
"widget.pinned": "Připnuté",
|
||||
"widget.tablesViewsFunctions": "Tabulky, pohledy, funkce",
|
||||
"widgets.addNew": "Přidat nový",
|
||||
"widgets.administration": "Administrace",
|
||||
"widgets.archive": "Archiv (uložená tabulková data)",
|
||||
"widgets.availableExtensions": "Dostupná rozšíření",
|
||||
"widgets.databaseConnections": "Databázová připojení",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Oblíbené a uložené soubory",
|
||||
"widgets.installedExtensions": "Nainstalovaná rozšíření",
|
||||
"widgets.managePlugins": "Spravovat pluginy",
|
||||
"widgets.premiumPromo": "Premium promo",
|
||||
"widgets.queryHistoryAndClosedTabs": "Historie dotazů a zavřené karty",
|
||||
"widgets.selectedCellDataDetailView": "Detailní zobrazení dat vybrané buňky",
|
||||
"widgets.viewApplicationLogs": "Zobrazit aplikační logy"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
"app.loading_plugin": "Lade Plugin {plugin} ...",
|
||||
"app.preparingPlugins": "Plugins werden vorbereitet...",
|
||||
"app.starting": "Starte DbGate",
|
||||
"cellDataWidget.autodetect": "Automatisch erkennen - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Format nicht ausgewählt",
|
||||
"cellDataWidget.mustSelectOneCell": "Es muss eine Zelle ausgewählt sein",
|
||||
"cellDataWidget.noDataSelected": "Keine Daten ausgewählt",
|
||||
"cellDataWidget.title": "Zell-Datenansicht",
|
||||
"chart.detect": "Diagramm erkennen",
|
||||
"chart.open": "Diagramm öffnen",
|
||||
"clipboard.SQLInsert": "SQL INSERTs",
|
||||
@@ -40,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Sparse",
|
||||
"columnEditor.isUnsigned": "Vorzeichenlos",
|
||||
"columnEditor.isZerofill": "Mit Nullen auffüllen",
|
||||
"columnLine.addReference": "Referenz hinzufügen",
|
||||
"columnLine.sortAscending": "Aufsteigend sortieren",
|
||||
"columnLine.sortDescending": "Absteigend sortieren",
|
||||
"columnLine.unsort": "Sortierung aufheben",
|
||||
"columnsConstraintEditor.addNewColumn": "Neue Spalte hinzufügen",
|
||||
"columnsConstraintEditor.chooseColumn": "Spalte auswählen",
|
||||
"columnsConstraintEditor.selectColumn": "Spalte auswählen",
|
||||
@@ -289,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Gewünschte Tastenkombination eingeben und ENTER drücken",
|
||||
"common.addNew": "Neu hinzufügen",
|
||||
"common.advanced": "Erweitert",
|
||||
"common.allFields": "Alle {field}",
|
||||
"common.archive": "Archiv (JSONL)",
|
||||
"common.cancel": "Abbrechen",
|
||||
"common.close": "Schließen",
|
||||
@@ -315,6 +325,7 @@
|
||||
"common.kill": "Beenden",
|
||||
"common.loadingData": "Lade Daten",
|
||||
"common.name": "Name",
|
||||
"common.newConnection": "Neue Verbindung",
|
||||
"common.notSelectedOptional": "(nicht ausgewählt - optional)",
|
||||
"common.parameters": "Parameter",
|
||||
"common.passwordEncrypted": "Passwort ist verschlüsselt",
|
||||
@@ -324,6 +335,7 @@
|
||||
"common.queryEditor": "SQL-Abfrage-Editor",
|
||||
"common.refresh": "Aktualisieren",
|
||||
"common.remove": "Entfernen",
|
||||
"common.removeAll": "Alle entfernen",
|
||||
"common.reset": "Zurücksetzen",
|
||||
"common.save": "Speichern",
|
||||
"common.saveAndNext": "Speichern und weiter",
|
||||
@@ -331,6 +343,7 @@
|
||||
"common.schema": "Schema",
|
||||
"common.search": "Suchen",
|
||||
"common.searchBy": "Suchen nach:",
|
||||
"common.server": "Server",
|
||||
"common.sqlGenerator": "SQL-Generator",
|
||||
"common.table": "Tabelle",
|
||||
"common.testingConnection": "Verbindung wird getestet",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Trigger",
|
||||
"dbObject.truncateTable": "Tabelle leeren",
|
||||
"dbObject.views": "Sichten",
|
||||
"designerTable.addReferences": "Referenzen hinzufügen",
|
||||
"designerTable.changeColor": "Farbe ändern",
|
||||
"designerTable.defineVirtualForeignKey": "Virtuellen Fremdschlüssel definieren",
|
||||
"designerTable.newAlias": "Neuer Alias",
|
||||
"designerTable.removeTableAlias": "Tabellenalias entfernen",
|
||||
"designerTable.setTableAlias": "Tabellenalias setzen",
|
||||
"error.driverNotFound": "Ungültige Datenbankverbindung, Treiber nicht gefunden",
|
||||
"error.selectedCloudConnection": "Ausgewählte Verbindung ist von DbGate Cloud",
|
||||
"error.selectedNotCloudConnection": "Ausgewählte Verbindung ist nicht von DbGate Cloud",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "Abfrage-Designer-Dateien",
|
||||
"file.sqlFiles": "SQL-Dateien",
|
||||
"file.sqliteDatabase": "SQLite-Datenbank",
|
||||
"files.allSupportedFiles": "Alle unterstützten Dateien",
|
||||
"files.favorites": "Favoriten",
|
||||
"files.openFile": "Datei öffnen",
|
||||
"files.refreshFiles": "Dateien aktualisieren",
|
||||
"files.savedFiles": "Gespeicherte Dateien",
|
||||
"files.searchSavedFiles": "Gespeicherte Dateien suchen",
|
||||
"files.sqlFiles": "SQL-Dateien",
|
||||
"files.teamFiles": "Team-Dateien",
|
||||
"files.uploadFile": "Datei hochladen",
|
||||
"filter.after": "Nach...",
|
||||
"filter.and": "Und",
|
||||
"filter.arrayIsEmpty": "Array ist leer",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Ref-Spalte - ",
|
||||
"foreignKeyEditor.referencedTable": "Referenzierte Tabelle",
|
||||
"foreignKeyEditor.tableNotSet": "(Tabelle nicht festgelegt)",
|
||||
"history.queryHistory": "Abfrageverlauf",
|
||||
"history.recentlyClosedTabs": "Kürzlich geschlossene Tabs",
|
||||
"history.searchQueryHistory": "Abfrageverlauf durchsuchen",
|
||||
"importExport.action": "Aktion",
|
||||
"importExport.addWebUrl": "Web-URL hinzufügen",
|
||||
"importExport.advancedConfiguration": "Erweiterte Konfiguration",
|
||||
"importExport.archiveFolder": "Archivordner",
|
||||
"importExport.columns": "Spalten",
|
||||
"importExport.createZipFileInArchive": "ZIP-Datei im Archiv erstellen",
|
||||
"importExport.currentArchive": "Aktuelles Archiv",
|
||||
"importExport.currentDatabase": "Aktuelle DB",
|
||||
"importExport.dragDropImportedFilesHere": "Importierte Dateien hierher ziehen und ablegen",
|
||||
"importExport.exportToZipArchive": "In ZIP-Archiv exportieren",
|
||||
"importExport.exportToZipFile": "In ZIP-Datei exportieren",
|
||||
"importExport.generateScript": "Skript generieren",
|
||||
"importExport.importFromZipArchive": "Aus ZIP-Archiv importieren",
|
||||
"importExport.importFromZipFile": "Aus ZIP-Datei importieren (im Archivordner)",
|
||||
"importExport.mapSourceTablesFiles": "Quelltabellen/-dateien zuordnen",
|
||||
"importExport.messages": "Meldungen",
|
||||
"importExport.newArchive": "Neues Archiv",
|
||||
"importExport.outputFiles": "Ausgabedateien",
|
||||
"importExport.preview": "Vorschau",
|
||||
"importExport.processingImportExport": "Import/Export wird verarbeitet ...",
|
||||
"importExport.run": "Ausführen",
|
||||
"importExport.schedule": "Zeitplan",
|
||||
"importExport.source": "Quelle",
|
||||
"importExport.sourceConfiguration": "Quellenkonfiguration",
|
||||
"importExport.sourceFiles": "Quelldateien",
|
||||
"importExport.startVariableIndex": "Startvariablenindex",
|
||||
"importExport.status": "Status",
|
||||
"importExport.stop": "Stopp",
|
||||
"importExport.storageType": "Speichertyp",
|
||||
"importExport.tablesViewsCollections": "Tabellen / Sichten / Sammlungen",
|
||||
"importExport.target": "Ziel",
|
||||
"importExport.targetConfiguration": "Zielkonfiguration",
|
||||
"indexEditor.filteredIndexCondition": "Gefilterte Index-Bedingung",
|
||||
"indexEditor.indexName": "Index-Name",
|
||||
"indexEditor.isUnique": "Ist eindeutiger Index",
|
||||
"logs.autoScroll": "Automatisches Scrollen",
|
||||
"logs.caller": "Aufrufer:",
|
||||
"logs.callerTab": "Aufrufer",
|
||||
"logs.chooseDate": "Datum auswählen",
|
||||
"logs.codeTab": "Code",
|
||||
"logs.connectionId": "Verbindungs-ID:",
|
||||
"logs.connectionTab": "Verbindung",
|
||||
"logs.database": "Datenbank:",
|
||||
"logs.databaseTab": "Datenbank",
|
||||
"logs.date": "Datum:",
|
||||
"logs.dateTab": "Datum",
|
||||
"logs.details": "Details",
|
||||
"logs.engine": "Engine:",
|
||||
"logs.engineTab": "Engine",
|
||||
"logs.loadingNextRows": "Lade nächste Zeilen...",
|
||||
"logs.message": "Nachricht:",
|
||||
"logs.messageCode": "Nachrichtencode:",
|
||||
"logs.messageTab": "Nachricht",
|
||||
"logs.name": "Name:",
|
||||
"logs.nameTab": "Name",
|
||||
"logs.noDataForSelectedDate": "Keine Daten für ausgewähltes Datum",
|
||||
"logs.recentLogs": "Letzte Protokolle",
|
||||
"logs.refresh": "Aktualisieren",
|
||||
"logs.time": "Zeit:",
|
||||
"logs.timeTab": "Zeit",
|
||||
"menu.edit": "Bearbeiten",
|
||||
"menu.file": "Datei",
|
||||
"menu.help": "Hilfe",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "SQL-Generator ist für aktuelle Datenbank nicht verfügbar",
|
||||
"newObject.tableDescription": "Tabelle in der aktuellen Datenbank erstellen",
|
||||
"newObject.tableDisabled": "Tabellenerstellung ist für aktuelle Datenbank nicht verfügbar",
|
||||
"plugins.searchExtensionsOnWeb": "Erweiterungen im Web suchen",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Es werden nur Dateien aufgelistet, die für Ihre Verbindungen, Plattform und DbGate-Edition relevant sind. Bitte definieren Sie zuerst Verbindungen.",
|
||||
"publicCloudWidget.refreshFiles": "Dateien aktualisieren",
|
||||
"publicCloudWidget.refreshList": "Liste aktualisieren",
|
||||
"publicCloudWidget.searchPublicFiles": "Öffentliche Dateien suchen",
|
||||
"query.limitRows": "Auf {queryRowsLimit} Zeilen begrenzen",
|
||||
"query.named": ":Variable",
|
||||
"query.noParameters": "(keine Parameter)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Spaltenname",
|
||||
"sqlObject.databaseEmpty": "Datenbank {database} ist leer oder Struktur ist nicht geladen, drücken Sie die Schaltfläche Aktualisieren, um die Struktur neu zu laden",
|
||||
"sqlObject.loadingStructure": "Lade Datenbankstruktur",
|
||||
"sqlObject.name": "Name",
|
||||
"sqlObject.newCollection": "Neue Sammlung/Container",
|
||||
"sqlObject.rowCount": "Zeilenanzahl",
|
||||
"sqlObject.schemaName": "Schema",
|
||||
"sqlObject.search.placeholder": "In Tabellen, Ansichten, Prozeduren suchen",
|
||||
"sqlObject.searchBy": "Suchen nach:",
|
||||
"sqlObject.sizeBytes": "Größe (Bytes)",
|
||||
"sqlObject.sortBy": "Sortieren nach:",
|
||||
"sqlObject.tableComment": "Tabellenkommentar",
|
||||
"sqlObject.tableEngine": "Tabellen-Engine",
|
||||
"sqlObject.tableViewProcedureName": "Name von Tabelle/Ansicht/Prozedur",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Schlüssel",
|
||||
"widget.pinned": "Angeheftet",
|
||||
"widget.tablesViewsFunctions": "Tabellen, Ansichten, Funktionen",
|
||||
"widgets.addNew": "Neu hinzufügen",
|
||||
"widgets.administration": "Administration",
|
||||
"widgets.archive": "Archiv (gespeicherte tabellarische Daten)",
|
||||
"widgets.availableExtensions": "Verfügbare Erweiterungen",
|
||||
"widgets.databaseConnections": "Datenbankverbindungen",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Favoriten & gespeicherte Dateien",
|
||||
"widgets.installedExtensions": "Installierte Erweiterungen",
|
||||
"widgets.managePlugins": "Plugins verwalten",
|
||||
"widgets.premiumPromo": "Premium-Werbung",
|
||||
"widgets.queryHistoryAndClosedTabs": "Abfrageverlauf & geschlossene Tabs",
|
||||
"widgets.selectedCellDataDetailView": "Detailansicht der ausgewählten Zelldaten",
|
||||
"widgets.viewApplicationLogs": "Anwendungsprotokolle anzeigen"
|
||||
}
|
||||
|
||||
+102
-1
@@ -3,7 +3,11 @@
|
||||
"app.loading_plugin": "Loading plugin {plugin} ...",
|
||||
"app.preparingPlugins": "Preparing plugins ...",
|
||||
"app.starting": "Starting DbGate",
|
||||
"connection.authToken": "Auth token",
|
||||
"cellDataWidget.autodetect": "Autodetect - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Format not selected",
|
||||
"cellDataWidget.mustSelectOneCell": "Must be selected one cell",
|
||||
"cellDataWidget.noDataSelected": "No data selected",
|
||||
"cellDataWidget.title": "Cell data view",
|
||||
"chart.detect": "Detect chart",
|
||||
"chart.open": "Open chart",
|
||||
"clipboard.SQLInsert": "SQL INSERTs",
|
||||
@@ -41,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Sparse",
|
||||
"columnEditor.isUnsigned": "Unsigned",
|
||||
"columnEditor.isZerofill": "Zero fill",
|
||||
"columnLine.addReference": "Add reference",
|
||||
"columnLine.sortAscending": "Sort ascending",
|
||||
"columnLine.sortDescending": "Sort descending",
|
||||
"columnLine.unsort": "Unsort",
|
||||
"columnsConstraintEditor.addNewColumn": "Add new column",
|
||||
"columnsConstraintEditor.chooseColumn": "Choose column",
|
||||
"columnsConstraintEditor.selectColumn": "Select column",
|
||||
@@ -290,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Show desired key combination and press ENTER",
|
||||
"common.addNew": "Add new",
|
||||
"common.advanced": "Advanced",
|
||||
"common.allFields": "All {field}",
|
||||
"common.archive": "Archive (JSONL)",
|
||||
"common.cancel": "Cancel",
|
||||
"common.close": "Close",
|
||||
@@ -316,6 +325,7 @@
|
||||
"common.kill": "Kill",
|
||||
"common.loadingData": "Loading data",
|
||||
"common.name": "Name",
|
||||
"common.newConnection": "New Connection",
|
||||
"common.notSelectedOptional": "(not selected - optional)",
|
||||
"common.parameters": "Parameters",
|
||||
"common.passwordEncrypted": "Password is encrypted",
|
||||
@@ -325,6 +335,7 @@
|
||||
"common.queryEditor": "SQL query editor",
|
||||
"common.refresh": "Refresh",
|
||||
"common.remove": "Remove",
|
||||
"common.removeAll": "Remove all",
|
||||
"common.reset": "Reset",
|
||||
"common.save": "Save",
|
||||
"common.saveAndNext": "Save and next",
|
||||
@@ -332,6 +343,7 @@
|
||||
"common.schema": "Schema",
|
||||
"common.search": "Search",
|
||||
"common.searchBy": "Search by:",
|
||||
"common.server": "Server",
|
||||
"common.sqlGenerator": "SQL Generator",
|
||||
"common.table": "Table",
|
||||
"common.testingConnection": "Testing connection",
|
||||
@@ -340,6 +352,7 @@
|
||||
"connection.allowedDatabasesRegex": "Allowed databases regular expression",
|
||||
"connection.askPassword": "Don't save, ask for password",
|
||||
"connection.askUser": "Don't save, ask for login and password",
|
||||
"connection.authToken": "Auth token",
|
||||
"connection.authentication": "Authentication",
|
||||
"connection.autoDetectNatMap": "Auto detect NAT map (use for Redis Cluster in Docker network)",
|
||||
"connection.chooseType": "Choose type",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Triggers",
|
||||
"dbObject.truncateTable": "Truncate table",
|
||||
"dbObject.views": "Views",
|
||||
"designerTable.addReferences": "Add references",
|
||||
"designerTable.changeColor": "Change color",
|
||||
"designerTable.defineVirtualForeignKey": "Define virtual foreign key",
|
||||
"designerTable.newAlias": "New alias",
|
||||
"designerTable.removeTableAlias": "Remove table alias",
|
||||
"designerTable.setTableAlias": "Set table alias",
|
||||
"error.driverNotFound": "Invalid database connection, driver not found",
|
||||
"error.selectedCloudConnection": "Selected connection is from DbGate cloud",
|
||||
"error.selectedNotCloudConnection": "Selected connection is not from DbGate cloud",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "Query designer files",
|
||||
"file.sqlFiles": "SQL files",
|
||||
"file.sqliteDatabase": "SQLite database",
|
||||
"files.allSupportedFiles": "All supported files",
|
||||
"files.favorites": "Favorites",
|
||||
"files.openFile": "Open file",
|
||||
"files.refreshFiles": "Refresh files",
|
||||
"files.savedFiles": "Saved files",
|
||||
"files.searchSavedFiles": "Search saved files",
|
||||
"files.sqlFiles": "SQL files",
|
||||
"files.teamFiles": "Team files",
|
||||
"files.uploadFile": "Upload file",
|
||||
"filter.after": "After...",
|
||||
"filter.and": "And",
|
||||
"filter.arrayIsEmpty": "Array is empty",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Ref column - ",
|
||||
"foreignKeyEditor.referencedTable": "Referenced table",
|
||||
"foreignKeyEditor.tableNotSet": "(table not set)",
|
||||
"history.queryHistory": "Query history",
|
||||
"history.recentlyClosedTabs": "Recently closed tabs",
|
||||
"history.searchQueryHistory": "Search query history",
|
||||
"importExport.action": "Action",
|
||||
"importExport.addWebUrl": "Add web URL",
|
||||
"importExport.advancedConfiguration": "Advanced configuration",
|
||||
"importExport.archiveFolder": "Archive folder",
|
||||
"importExport.columns": "Columns",
|
||||
"importExport.createZipFileInArchive": "Create ZIP file in archive",
|
||||
"importExport.currentArchive": "Current archive",
|
||||
"importExport.currentDatabase": "Current DB",
|
||||
"importExport.dragDropImportedFilesHere": "Drag & drop imported files here",
|
||||
"importExport.exportToZipArchive": "Output ZIP archive",
|
||||
"importExport.exportToZipFile": "Export to ZIP file",
|
||||
"importExport.generateScript": "Generate script",
|
||||
"importExport.importFromZipArchive": "Input ZIP archive",
|
||||
"importExport.importFromZipFile": "Import from ZIP file (in archive folder)",
|
||||
"importExport.mapSourceTablesFiles": "Map source tables/files",
|
||||
"importExport.messages": "Messages",
|
||||
"importExport.newArchive": "New archive",
|
||||
"importExport.outputFiles": "Output files",
|
||||
"importExport.preview": "Preview",
|
||||
"importExport.processingImportExport": "Processing import/export ...",
|
||||
"importExport.run": "Run",
|
||||
"importExport.schedule": "Schedule",
|
||||
"importExport.source": "Source",
|
||||
"importExport.sourceConfiguration": "Source configuration",
|
||||
"importExport.sourceFiles": "Source files",
|
||||
"importExport.startVariableIndex": "Start variable index",
|
||||
"importExport.status": "Status",
|
||||
"importExport.stop": "Stop",
|
||||
"importExport.storageType": "Storage type",
|
||||
"importExport.tablesViewsCollections": "Tables / views / collections",
|
||||
"importExport.target": "Target",
|
||||
"importExport.targetConfiguration": "Target configuration",
|
||||
"indexEditor.filteredIndexCondition": "Filtered index condition",
|
||||
"indexEditor.indexName": "Index name",
|
||||
"indexEditor.isUnique": "Is unique index",
|
||||
"logs.autoScroll": "Auto-scroll",
|
||||
"logs.caller": "Caller:",
|
||||
"logs.callerTab": "Caller",
|
||||
"logs.chooseDate": "Choose date",
|
||||
"logs.codeTab": "Code",
|
||||
"logs.connectionId": "Connection ID:",
|
||||
"logs.connectionTab": "Connection",
|
||||
"logs.database": "Database:",
|
||||
"logs.databaseTab": "Database",
|
||||
"logs.date": "Date:",
|
||||
"logs.dateTab": "Date",
|
||||
"logs.details": "Details",
|
||||
"logs.engine": "Engine:",
|
||||
"logs.engineTab": "Engine",
|
||||
"logs.loadingNextRows": "Loading next rows...",
|
||||
"logs.message": "Message:",
|
||||
"logs.messageCode": "Message code:",
|
||||
"logs.messageTab": "Message",
|
||||
"logs.name": "Name:",
|
||||
"logs.nameTab": "Name",
|
||||
"logs.noDataForSelectedDate": "No data for selected date",
|
||||
"logs.recentLogs": "Recent logs",
|
||||
"logs.refresh": "Refresh",
|
||||
"logs.time": "Time:",
|
||||
"logs.timeTab": "Time",
|
||||
"menu.edit": "Edit",
|
||||
"menu.file": "File",
|
||||
"menu.help": "Help",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "SQL Generator is not available for current database",
|
||||
"newObject.tableDescription": "Create table in the current database",
|
||||
"newObject.tableDisabled": "Table creation is not available for current database",
|
||||
"plugins.searchExtensionsOnWeb": "Search extensions on web",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first.",
|
||||
"publicCloudWidget.refreshFiles": "Refresh files",
|
||||
"publicCloudWidget.refreshList": "Refresh list",
|
||||
"publicCloudWidget.searchPublicFiles": "Search public files",
|
||||
"query.limitRows": "Limit {queryRowsLimit} rows",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(no parameters)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Column name",
|
||||
"sqlObject.databaseEmpty": "Database {database} is empty or structure is not loaded, press Refresh button to reload structure",
|
||||
"sqlObject.loadingStructure": "Loading database structure",
|
||||
"sqlObject.name": "Name",
|
||||
"sqlObject.newCollection": "New collection/container",
|
||||
"sqlObject.rowCount": "Row count",
|
||||
"sqlObject.schemaName": "Schema",
|
||||
"sqlObject.search.placeholder": "Search in tables, views, procedures",
|
||||
"sqlObject.searchBy": "Search by:",
|
||||
"sqlObject.sizeBytes": "Size (bytes)",
|
||||
"sqlObject.sortBy": "Sort by:",
|
||||
"sqlObject.tableComment": "Table comment",
|
||||
"sqlObject.tableEngine": "Table engine",
|
||||
"sqlObject.tableViewProcedureName": "Table/view/procedure name",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Keys",
|
||||
"widget.pinned": "Pinned",
|
||||
"widget.tablesViewsFunctions": "Tables, views, functions",
|
||||
"widgets.addNew": "Add New",
|
||||
"widgets.administration": "Administration",
|
||||
"widgets.archive": "Archive (saved tabular data)",
|
||||
"widgets.availableExtensions": "Available extensions",
|
||||
"widgets.databaseConnections": "Database connections",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Favorites & Saved files",
|
||||
"widgets.installedExtensions": "Installed extensions",
|
||||
"widgets.managePlugins": "Manage plugins",
|
||||
"widgets.premiumPromo": "Premium promo",
|
||||
"widgets.queryHistoryAndClosedTabs": "Query history & Closed tabs",
|
||||
"widgets.selectedCellDataDetailView": "Selected cell data detail view",
|
||||
"widgets.viewApplicationLogs": "View application logs"
|
||||
}
|
||||
@@ -3,6 +3,11 @@
|
||||
"app.loading_plugin": "Cargando plugin {plugin} ...",
|
||||
"app.preparingPlugins": "Preparando plugins ...",
|
||||
"app.starting": "Iniciando DbGate",
|
||||
"cellDataWidget.autodetect": "Detección automática - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Formato no seleccionado",
|
||||
"cellDataWidget.mustSelectOneCell": "Debe seleccionarse una celda",
|
||||
"cellDataWidget.noDataSelected": "No hay datos seleccionados",
|
||||
"cellDataWidget.title": "Vista de datos de celda",
|
||||
"chart.detect": "Detectar gráfico",
|
||||
"chart.open": "Abrir gráfico",
|
||||
"clipboard.SQLInsert": "SQL INSERTs",
|
||||
@@ -40,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Dispersa",
|
||||
"columnEditor.isUnsigned": "Sin signo",
|
||||
"columnEditor.isZerofill": "Relleno con ceros",
|
||||
"columnLine.addReference": "Agregar referencia",
|
||||
"columnLine.sortAscending": "Ordenar ascendente",
|
||||
"columnLine.sortDescending": "Ordenar descendente",
|
||||
"columnLine.unsort": "Quitar orden",
|
||||
"columnsConstraintEditor.addNewColumn": "Agregar nueva columna",
|
||||
"columnsConstraintEditor.chooseColumn": "Elegir columna",
|
||||
"columnsConstraintEditor.selectColumn": "Seleccionar columna",
|
||||
@@ -289,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Muestre la combinación de teclas deseada y presione ENTER",
|
||||
"common.addNew": "Agregar nuevo",
|
||||
"common.advanced": "Avanzado",
|
||||
"common.allFields": "Todos {field}",
|
||||
"common.archive": "Archivo (JSONL)",
|
||||
"common.cancel": "Cancelar",
|
||||
"common.close": "Cerrar",
|
||||
@@ -315,6 +325,7 @@
|
||||
"common.kill": "Terminar",
|
||||
"common.loadingData": "Cargando datos",
|
||||
"common.name": "Nombre",
|
||||
"common.newConnection": "Nueva conexión",
|
||||
"common.notSelectedOptional": "(no seleccionado - opcional)",
|
||||
"common.parameters": "Parámetros",
|
||||
"common.passwordEncrypted": "La contraseña está encriptada",
|
||||
@@ -324,6 +335,7 @@
|
||||
"common.queryEditor": "Editor de consultas SQL",
|
||||
"common.refresh": "Refrescar",
|
||||
"common.remove": "Eliminar",
|
||||
"common.removeAll": "Eliminar todo",
|
||||
"common.reset": "Restablecer",
|
||||
"common.save": "Guardar",
|
||||
"common.saveAndNext": "Guardar y siguiente",
|
||||
@@ -331,6 +343,7 @@
|
||||
"common.schema": "Esquema",
|
||||
"common.search": "Buscar",
|
||||
"common.searchBy": "Buscar por:",
|
||||
"common.server": "Servidor",
|
||||
"common.sqlGenerator": "Generador SQL",
|
||||
"common.table": "Tabla",
|
||||
"common.testingConnection": "Probando conexión",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Disparadores",
|
||||
"dbObject.truncateTable": "Truncar tabla",
|
||||
"dbObject.views": "Vistas",
|
||||
"designerTable.addReferences": "Agregar referencias",
|
||||
"designerTable.changeColor": "Cambiar color",
|
||||
"designerTable.defineVirtualForeignKey": "Definir clave foránea virtual",
|
||||
"designerTable.newAlias": "Nuevo alias",
|
||||
"designerTable.removeTableAlias": "Eliminar alias de tabla",
|
||||
"designerTable.setTableAlias": "Establecer alias de tabla",
|
||||
"error.driverNotFound": "Conexión de base de datos inválida, controlador no encontrado",
|
||||
"error.selectedCloudConnection": "La conexión seleccionada es de la nube de DbGate",
|
||||
"error.selectedNotCloudConnection": "La conexión seleccionada no es de la nube de DbGate",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "Archivos de diseñador de consultas",
|
||||
"file.sqlFiles": "Archivos SQL",
|
||||
"file.sqliteDatabase": "Base de datos SQLite",
|
||||
"files.allSupportedFiles": "Todos los archivos soportados",
|
||||
"files.favorites": "Favoritos",
|
||||
"files.openFile": "Abrir archivo",
|
||||
"files.refreshFiles": "Refrescar archivos",
|
||||
"files.savedFiles": "Archivos guardados",
|
||||
"files.searchSavedFiles": "Buscar archivos guardados",
|
||||
"files.sqlFiles": "Archivos SQL",
|
||||
"files.teamFiles": "Archivos de equipo",
|
||||
"files.uploadFile": "Subir archivo",
|
||||
"filter.after": "Después de...",
|
||||
"filter.and": "Y",
|
||||
"filter.arrayIsEmpty": "El arreglo está vacío",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Columna ref - ",
|
||||
"foreignKeyEditor.referencedTable": "Tabla referenciada",
|
||||
"foreignKeyEditor.tableNotSet": "(tabla no establecida)",
|
||||
"history.queryHistory": "Historial de consultas",
|
||||
"history.recentlyClosedTabs": "Pestañas cerradas recientemente",
|
||||
"history.searchQueryHistory": "Buscar en historial de consultas",
|
||||
"importExport.action": "Acción",
|
||||
"importExport.addWebUrl": "Agregar URL web",
|
||||
"importExport.advancedConfiguration": "Configuración avanzada",
|
||||
"importExport.archiveFolder": "Carpeta de archivo",
|
||||
"importExport.columns": "Columnas",
|
||||
"importExport.createZipFileInArchive": "Crear archivo ZIP en el archivo",
|
||||
"importExport.currentArchive": "Archivo actual",
|
||||
"importExport.currentDatabase": "BD actual",
|
||||
"importExport.dragDropImportedFilesHere": "Arrastre y suelte aquí los archivos importados",
|
||||
"importExport.exportToZipArchive": "Archivo ZIP de salida",
|
||||
"importExport.exportToZipFile": "Exportar a archivo ZIP",
|
||||
"importExport.generateScript": "Generar script",
|
||||
"importExport.importFromZipArchive": "Archivo ZIP de entrada",
|
||||
"importExport.importFromZipFile": "Importar desde archivo ZIP (en carpeta de archivo)",
|
||||
"importExport.mapSourceTablesFiles": "Mapear tablas/archivos de origen",
|
||||
"importExport.messages": "Mensajes",
|
||||
"importExport.newArchive": "Nuevo archivo",
|
||||
"importExport.outputFiles": "Archivos de salida",
|
||||
"importExport.preview": "Vista previa",
|
||||
"importExport.processingImportExport": "Procesando importación/exportación ...",
|
||||
"importExport.run": "Ejecutar",
|
||||
"importExport.schedule": "Programar",
|
||||
"importExport.source": "Origen",
|
||||
"importExport.sourceConfiguration": "Configuración de origen",
|
||||
"importExport.sourceFiles": "Archivos de origen",
|
||||
"importExport.startVariableIndex": "Índice inicial de variable",
|
||||
"importExport.status": "Estado",
|
||||
"importExport.stop": "Detener",
|
||||
"importExport.storageType": "Tipo de almacenamiento",
|
||||
"importExport.tablesViewsCollections": "Tablas / vistas / colecciones",
|
||||
"importExport.target": "Destino",
|
||||
"importExport.targetConfiguration": "Configuración de destino",
|
||||
"indexEditor.filteredIndexCondition": "Condición de índice filtrado",
|
||||
"indexEditor.indexName": "Nombre de índice",
|
||||
"indexEditor.isUnique": "Es índice único",
|
||||
"logs.autoScroll": "Desplazamiento automático",
|
||||
"logs.caller": "Llamador:",
|
||||
"logs.callerTab": "Llamador",
|
||||
"logs.chooseDate": "Elegir fecha",
|
||||
"logs.codeTab": "Código",
|
||||
"logs.connectionId": "ID de conexión:",
|
||||
"logs.connectionTab": "Conexión",
|
||||
"logs.database": "Base de datos:",
|
||||
"logs.databaseTab": "Base de datos",
|
||||
"logs.date": "Fecha:",
|
||||
"logs.dateTab": "Fecha",
|
||||
"logs.details": "Detalles",
|
||||
"logs.engine": "Motor:",
|
||||
"logs.engineTab": "Motor",
|
||||
"logs.loadingNextRows": "Cargando siguientes filas...",
|
||||
"logs.message": "Mensaje:",
|
||||
"logs.messageCode": "Código de mensaje:",
|
||||
"logs.messageTab": "Mensaje",
|
||||
"logs.name": "Nombre:",
|
||||
"logs.nameTab": "Nombre",
|
||||
"logs.noDataForSelectedDate": "No hay datos para la fecha seleccionada",
|
||||
"logs.recentLogs": "Registros recientes",
|
||||
"logs.refresh": "Refrescar",
|
||||
"logs.time": "Hora:",
|
||||
"logs.timeTab": "Hora",
|
||||
"menu.edit": "Editar",
|
||||
"menu.file": "Archivo",
|
||||
"menu.help": "Ayuda",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "El generador SQL no está disponible para la base de datos actual",
|
||||
"newObject.tableDescription": "Crear tabla en la base de datos actual",
|
||||
"newObject.tableDisabled": "La creación de tablas no está disponible para la base de datos actual",
|
||||
"plugins.searchExtensionsOnWeb": "Buscar extensiones en la web",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Solo se listan archivos relevantes para sus conexiones, plataforma y edición de DbGate. Defina primero las conexiones.",
|
||||
"publicCloudWidget.refreshFiles": "Refrescar archivos",
|
||||
"publicCloudWidget.refreshList": "Refrescar lista",
|
||||
"publicCloudWidget.searchPublicFiles": "Buscar archivos públicos",
|
||||
"query.limitRows": "Limitar {queryRowsLimit} filas",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(sin parámetros)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Nombre de columna",
|
||||
"sqlObject.databaseEmpty": "La base de datos {database} está vacía o la estructura no está cargada, presione el botón Refrescar para recargar la estructura",
|
||||
"sqlObject.loadingStructure": "Cargando estructura de base de datos",
|
||||
"sqlObject.name": "Nombre",
|
||||
"sqlObject.newCollection": "Nueva colección/contenedor",
|
||||
"sqlObject.rowCount": "Recuento de filas",
|
||||
"sqlObject.schemaName": "Esquema",
|
||||
"sqlObject.search.placeholder": "Buscar en tablas, vistas, procedimientos",
|
||||
"sqlObject.searchBy": "Buscar por:",
|
||||
"sqlObject.sizeBytes": "Tamaño (bytes)",
|
||||
"sqlObject.sortBy": "Ordenar por:",
|
||||
"sqlObject.tableComment": "Comentario de tabla",
|
||||
"sqlObject.tableEngine": "Motor de tabla",
|
||||
"sqlObject.tableViewProcedureName": "Nombre de tabla/vista/procedimiento",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Claves",
|
||||
"widget.pinned": "Anclado",
|
||||
"widget.tablesViewsFunctions": "Tablas, vistas, funciones",
|
||||
"widgets.addNew": "Agregar nuevo",
|
||||
"widgets.administration": "Administración",
|
||||
"widgets.archive": "Archivo (datos tabulares guardados)",
|
||||
"widgets.availableExtensions": "Extensiones disponibles",
|
||||
"widgets.databaseConnections": "Conexiones de base de datos",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Favoritos y archivos guardados",
|
||||
"widgets.installedExtensions": "Extensiones instaladas",
|
||||
"widgets.managePlugins": "Administrar plugins",
|
||||
"widgets.premiumPromo": "Promoción Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Historial de consultas y pestañas cerradas",
|
||||
"widgets.selectedCellDataDetailView": "Vista detallada de datos de celda seleccionada",
|
||||
"widgets.viewApplicationLogs": "Ver registros de la aplicación"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
"app.loading_plugin": "Chargement du plugin {plugin}...",
|
||||
"app.preparingPlugins": "Préparation des plugins...",
|
||||
"app.starting": "Démarrage de DbGate",
|
||||
"cellDataWidget.autodetect": "Détection automatique - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Format non sélectionné",
|
||||
"cellDataWidget.mustSelectOneCell": "Une seule cellule doit être sélectionnée",
|
||||
"cellDataWidget.noDataSelected": "Aucune donnée sélectionnée",
|
||||
"cellDataWidget.title": "Vue des données de cellule",
|
||||
"chart.detect": "Détecter le graphique",
|
||||
"chart.open": "Ouvrir le graphique",
|
||||
"clipboard.SQLInsert": "INSERT SQL",
|
||||
@@ -40,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Sparse",
|
||||
"columnEditor.isUnsigned": "Non signé",
|
||||
"columnEditor.isZerofill": "Remplissage de zéros",
|
||||
"columnLine.addReference": "Ajouter une référence",
|
||||
"columnLine.sortAscending": "Trier par ordre croissant",
|
||||
"columnLine.sortDescending": "Trier par ordre décroissant",
|
||||
"columnLine.unsort": "Annuler le tri",
|
||||
"columnsConstraintEditor.addNewColumn": "Ajouter une nouvelle colonne",
|
||||
"columnsConstraintEditor.chooseColumn": "Choisir une colonne",
|
||||
"columnsConstraintEditor.selectColumn": "Sélectionner une colonne",
|
||||
@@ -289,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Afficher la combinaison de touches souhaitée et appuyez sur ENTRÉE",
|
||||
"common.addNew": "Ajouter un nouvel élément",
|
||||
"common.advanced": "Avancé",
|
||||
"common.allFields": "Tous les {field}",
|
||||
"common.archive": "Archive (JSONL)",
|
||||
"common.cancel": "Annuler",
|
||||
"common.close": "Fermer",
|
||||
@@ -315,6 +325,7 @@
|
||||
"common.kill": "Tuer",
|
||||
"common.loadingData": "Chargement des données",
|
||||
"common.name": "Nom",
|
||||
"common.newConnection": "Nouvelle connexion",
|
||||
"common.notSelectedOptional": "(non sélectionné - optionnel)",
|
||||
"common.parameters": "Paramètres",
|
||||
"common.passwordEncrypted": "Le mot de passe est chiffré",
|
||||
@@ -324,6 +335,7 @@
|
||||
"common.queryEditor": "Éditeur de requêtes SQL",
|
||||
"common.refresh": "Rafraîchir",
|
||||
"common.remove": "Supprimer",
|
||||
"common.removeAll": "Tout supprimer",
|
||||
"common.reset": "Réinitialiser",
|
||||
"common.save": "Enregistrer",
|
||||
"common.saveAndNext": "Enregistrer et passer au suivant",
|
||||
@@ -331,6 +343,7 @@
|
||||
"common.schema": "Schéma",
|
||||
"common.search": "Rechercher",
|
||||
"common.searchBy": "Rechercher par :",
|
||||
"common.server": "Serveur",
|
||||
"common.sqlGenerator": "Générateur SQL",
|
||||
"common.table": "Table",
|
||||
"common.testingConnection": "Test de connexion",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Déclencheurs",
|
||||
"dbObject.truncateTable": "Tronquer la table",
|
||||
"dbObject.views": "Vues",
|
||||
"designerTable.addReferences": "Ajouter des références",
|
||||
"designerTable.changeColor": "Changer la couleur",
|
||||
"designerTable.defineVirtualForeignKey": "Définir une clé étrangère virtuelle",
|
||||
"designerTable.newAlias": "Nouvel alias",
|
||||
"designerTable.removeTableAlias": "Supprimer l'alias de table",
|
||||
"designerTable.setTableAlias": "Définir l'alias de table",
|
||||
"error.driverNotFound": "Connexion de base de données non valide, pilote introuvable",
|
||||
"error.selectedCloudConnection": "La connexion sélectionnée provient du cloud DbGate",
|
||||
"error.selectedNotCloudConnection": "La connexion sélectionnée ne provient pas du cloud DbGate",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "Fichiers du concepteur de requêtes",
|
||||
"file.sqlFiles": "Fichiers SQL",
|
||||
"file.sqliteDatabase": "Base de données SQLite",
|
||||
"files.allSupportedFiles": "Tous les fichiers pris en charge",
|
||||
"files.favorites": "Favoris",
|
||||
"files.openFile": "Ouvrir le fichier",
|
||||
"files.refreshFiles": "Rafraîchir les fichiers",
|
||||
"files.savedFiles": "Fichiers enregistrés",
|
||||
"files.searchSavedFiles": "Rechercher dans les fichiers enregistrés",
|
||||
"files.sqlFiles": "Fichiers SQL",
|
||||
"files.teamFiles": "Fichiers d'équipe",
|
||||
"files.uploadFile": "Téléverser un fichier",
|
||||
"filter.after": "Après...",
|
||||
"filter.and": "Et",
|
||||
"filter.arrayIsEmpty": "Le tableau est vide",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Colonne réf. - ",
|
||||
"foreignKeyEditor.referencedTable": "Table référencée",
|
||||
"foreignKeyEditor.tableNotSet": "(table non définie)",
|
||||
"history.queryHistory": "Historique des requêtes",
|
||||
"history.recentlyClosedTabs": "Onglets récemment fermés",
|
||||
"history.searchQueryHistory": "Rechercher dans l'historique des requêtes",
|
||||
"importExport.action": "Action",
|
||||
"importExport.addWebUrl": "Ajouter une URL web",
|
||||
"importExport.advancedConfiguration": "Configuration avancée",
|
||||
"importExport.archiveFolder": "Dossier d'archive",
|
||||
"importExport.columns": "Colonnes",
|
||||
"importExport.createZipFileInArchive": "Créer un fichier ZIP dans l'archive",
|
||||
"importExport.currentArchive": "Archive actuelle",
|
||||
"importExport.currentDatabase": "BD actuelle",
|
||||
"importExport.dragDropImportedFilesHere": "Glissez-déposez les fichiers importés ici",
|
||||
"importExport.exportToZipArchive": "Archive ZIP de sortie",
|
||||
"importExport.exportToZipFile": "Exporter vers un fichier ZIP",
|
||||
"importExport.generateScript": "Générer un script",
|
||||
"importExport.importFromZipArchive": "Archive ZIP d'entrée",
|
||||
"importExport.importFromZipFile": "Importer depuis un fichier ZIP (dans le dossier d'archive)",
|
||||
"importExport.mapSourceTablesFiles": "Mapper les tables/fichiers source",
|
||||
"importExport.messages": "Messages",
|
||||
"importExport.newArchive": "Nouvelle archive",
|
||||
"importExport.outputFiles": "Fichiers de sortie",
|
||||
"importExport.preview": "Aperçu",
|
||||
"importExport.processingImportExport": "Traitement de l'import/export...",
|
||||
"importExport.run": "Exécuter",
|
||||
"importExport.schedule": "Planifier",
|
||||
"importExport.source": "Source",
|
||||
"importExport.sourceConfiguration": "Configuration de la source",
|
||||
"importExport.sourceFiles": "Fichiers source",
|
||||
"importExport.startVariableIndex": "Index de variable de départ",
|
||||
"importExport.status": "Statut",
|
||||
"importExport.stop": "Arrêter",
|
||||
"importExport.storageType": "Type de stockage",
|
||||
"importExport.tablesViewsCollections": "Tables / vues / collections",
|
||||
"importExport.target": "Cible",
|
||||
"importExport.targetConfiguration": "Configuration de la cible",
|
||||
"indexEditor.filteredIndexCondition": "Condition d'index filtré",
|
||||
"indexEditor.indexName": "Nom de l'index",
|
||||
"indexEditor.isUnique": "Est un index unique",
|
||||
"logs.autoScroll": "Défilement automatique",
|
||||
"logs.caller": "Appelant :",
|
||||
"logs.callerTab": "Appelant",
|
||||
"logs.chooseDate": "Choisir la date",
|
||||
"logs.codeTab": "Code",
|
||||
"logs.connectionId": "ID de connexion :",
|
||||
"logs.connectionTab": "Connexion",
|
||||
"logs.database": "Base de données :",
|
||||
"logs.databaseTab": "Base de données",
|
||||
"logs.date": "Date :",
|
||||
"logs.dateTab": "Date",
|
||||
"logs.details": "Détails",
|
||||
"logs.engine": "Moteur :",
|
||||
"logs.engineTab": "Moteur",
|
||||
"logs.loadingNextRows": "Chargement des lignes suivantes...",
|
||||
"logs.message": "Message :",
|
||||
"logs.messageCode": "Code du message :",
|
||||
"logs.messageTab": "Message",
|
||||
"logs.name": "Nom :",
|
||||
"logs.nameTab": "Nom",
|
||||
"logs.noDataForSelectedDate": "Aucune donnée pour la date sélectionnée",
|
||||
"logs.recentLogs": "Journaux récents",
|
||||
"logs.refresh": "Rafraîchir",
|
||||
"logs.time": "Heure :",
|
||||
"logs.timeTab": "Heure",
|
||||
"menu.edit": "Modifier",
|
||||
"menu.file": "Fichier",
|
||||
"menu.help": "Aide",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "Le générateur SQL n'est pas disponible pour la base de données actuelle",
|
||||
"newObject.tableDescription": "Créer une table dans la base de données actuelle",
|
||||
"newObject.tableDisabled": "La création de table n'est pas disponible pour la base de données actuelle",
|
||||
"plugins.searchExtensionsOnWeb": "Rechercher des extensions sur le web",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Seuls les fichiers pertinents pour vos connexions, votre plateforme et votre édition de DbGate sont listés. Veuillez d'abord définir des connexions.",
|
||||
"publicCloudWidget.refreshFiles": "Rafraîchir les fichiers",
|
||||
"publicCloudWidget.refreshList": "Rafraîchir la liste",
|
||||
"publicCloudWidget.searchPublicFiles": "Rechercher des fichiers publics",
|
||||
"query.limitRows": "Limiter à {queryRowsLimit} lignes",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(aucun paramètre)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Nom de colonne",
|
||||
"sqlObject.databaseEmpty": "La base de données {database} est vide ou la structure n'est pas chargée, appuyez sur le bouton Rafraîchir pour recharger la structure",
|
||||
"sqlObject.loadingStructure": "Chargement de la structure de la base de données",
|
||||
"sqlObject.name": "Nom",
|
||||
"sqlObject.newCollection": "Nouvelle collection/conteneur",
|
||||
"sqlObject.rowCount": "Nombre de lignes",
|
||||
"sqlObject.schemaName": "Schéma",
|
||||
"sqlObject.search.placeholder": "Rechercher dans les tables, vues, procédures",
|
||||
"sqlObject.searchBy": "Rechercher par :",
|
||||
"sqlObject.sizeBytes": "Taille (octets)",
|
||||
"sqlObject.sortBy": "Trier par :",
|
||||
"sqlObject.tableComment": "Commentaire de table",
|
||||
"sqlObject.tableEngine": "Moteur de table",
|
||||
"sqlObject.tableViewProcedureName": "Nom de table/vue/procédure",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Clés",
|
||||
"widget.pinned": "Épinglé",
|
||||
"widget.tablesViewsFunctions": "Tables, vues, fonctions",
|
||||
"widgets.addNew": "Ajouter un nouvel élément",
|
||||
"widgets.administration": "Administration",
|
||||
"widgets.archive": "Archive (données tabulaires enregistrées)",
|
||||
"widgets.availableExtensions": "Extensions disponibles",
|
||||
"widgets.databaseConnections": "Connexions de base de données",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Favoris et fichiers enregistrés",
|
||||
"widgets.installedExtensions": "Extensions installées",
|
||||
"widgets.managePlugins": "Gérer les plugins",
|
||||
"widgets.premiumPromo": "Promotion Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Historique des requêtes et onglets fermés",
|
||||
"widgets.selectedCellDataDetailView": "Vue détaillée des données de la cellule sélectionnée",
|
||||
"widgets.viewApplicationLogs": "Afficher les journaux de l'application"
|
||||
}
|
||||
|
||||
+103
-2
@@ -3,7 +3,11 @@
|
||||
"app.loading_plugin": "Caricamento plugin {plugin} ...",
|
||||
"app.preparingPlugins": "Preparazione plugin ...",
|
||||
"app.starting": "Avvio DbGate",
|
||||
"connection.authToken": "Token di autenticazione",
|
||||
"cellDataWidget.autodetect": "Rilevamento automatico - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Formato non selezionato",
|
||||
"cellDataWidget.mustSelectOneCell": "Deve essere selezionata una cella",
|
||||
"cellDataWidget.noDataSelected": "Nessun dato selezionato",
|
||||
"cellDataWidget.title": "Vista dati cella",
|
||||
"chart.detect": "Rileva grafico",
|
||||
"chart.open": "Apri grafico",
|
||||
"clipboard.SQLInsert": "SQL INSERTs",
|
||||
@@ -41,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Sparse",
|
||||
"columnEditor.isUnsigned": "Unsigned",
|
||||
"columnEditor.isZerofill": "Zero fill",
|
||||
"columnLine.addReference": "Aggiungi riferimento",
|
||||
"columnLine.sortAscending": "Ordina crescente",
|
||||
"columnLine.sortDescending": "Ordina decrescente",
|
||||
"columnLine.unsort": "Rimuovi ordinamento",
|
||||
"columnsConstraintEditor.addNewColumn": "Aggiungi nuova colonna",
|
||||
"columnsConstraintEditor.chooseColumn": "Scegli colonna",
|
||||
"columnsConstraintEditor.selectColumn": "Seleziona colonna",
|
||||
@@ -290,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Mostra la combinazione di tasti desiderata e premi INVIO",
|
||||
"common.addNew": "Aggiungi nuovo",
|
||||
"common.advanced": "Avanzate",
|
||||
"common.allFields": "Tutti {field}",
|
||||
"common.archive": "Archivio (JSONL)",
|
||||
"common.cancel": "Annulla",
|
||||
"common.close": "Chiudi",
|
||||
@@ -316,6 +325,7 @@
|
||||
"common.kill": "Termina",
|
||||
"common.loadingData": "Caricamento dati",
|
||||
"common.name": "Nome",
|
||||
"common.newConnection": "Nuova connessione",
|
||||
"common.notSelectedOptional": "(non selezionato - opzionale)",
|
||||
"common.parameters": "Parametri",
|
||||
"common.passwordEncrypted": "La password è crittografata",
|
||||
@@ -325,6 +335,7 @@
|
||||
"common.queryEditor": "Editor query SQL",
|
||||
"common.refresh": "Aggiorna",
|
||||
"common.remove": "Rimuovi",
|
||||
"common.removeAll": "Rimuovi tutto",
|
||||
"common.reset": "Ripristina",
|
||||
"common.save": "Salva",
|
||||
"common.saveAndNext": "Salva e avanti",
|
||||
@@ -332,6 +343,7 @@
|
||||
"common.schema": "Schema",
|
||||
"common.search": "Cerca",
|
||||
"common.searchBy": "Cerca per:",
|
||||
"common.server": "Server",
|
||||
"common.sqlGenerator": "Generatore SQL",
|
||||
"common.table": "Tabella",
|
||||
"common.testingConnection": "Test connessione",
|
||||
@@ -340,6 +352,7 @@
|
||||
"connection.allowedDatabasesRegex": "Espressione regolare database consentiti",
|
||||
"connection.askPassword": "Non salvare, richiedi password",
|
||||
"connection.askUser": "Non salvare, richiedi login e password",
|
||||
"connection.authToken": "Token di autenticazione",
|
||||
"connection.authentication": "Autenticazione",
|
||||
"connection.autoDetectNatMap": "Rileva automaticamente mappa NAT (usa per Redis Cluster in rete Docker)",
|
||||
"connection.chooseType": "Scegli tipo",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Trigger",
|
||||
"dbObject.truncateTable": "Truncate tabella",
|
||||
"dbObject.views": "Viste",
|
||||
"designerTable.addReferences": "Aggiungi riferimenti",
|
||||
"designerTable.changeColor": "Cambia colore",
|
||||
"designerTable.defineVirtualForeignKey": "Definisci chiave esterna virtuale",
|
||||
"designerTable.newAlias": "Nuovo alias",
|
||||
"designerTable.removeTableAlias": "Rimuovi alias tabella",
|
||||
"designerTable.setTableAlias": "Imposta alias tabella",
|
||||
"error.driverNotFound": "Connessione database non valida, driver non trovato",
|
||||
"error.selectedCloudConnection": "La connessione selezionata è da DbGate cloud",
|
||||
"error.selectedNotCloudConnection": "La connessione selezionata non è da DbGate cloud",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "File designer query",
|
||||
"file.sqlFiles": "File SQL",
|
||||
"file.sqliteDatabase": "Database SQLite",
|
||||
"files.allSupportedFiles": "Tutti i file supportati",
|
||||
"files.favorites": "Preferiti",
|
||||
"files.openFile": "Apri file",
|
||||
"files.refreshFiles": "Aggiorna file",
|
||||
"files.savedFiles": "File salvati",
|
||||
"files.searchSavedFiles": "Cerca file salvati",
|
||||
"files.sqlFiles": "File SQL",
|
||||
"files.teamFiles": "File team",
|
||||
"files.uploadFile": "Carica file",
|
||||
"filter.after": "Dopo...",
|
||||
"filter.and": "E",
|
||||
"filter.arrayIsEmpty": "Array è vuoto",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Colonna rif - ",
|
||||
"foreignKeyEditor.referencedTable": "Tabella referenziata",
|
||||
"foreignKeyEditor.tableNotSet": "(tabella non impostata)",
|
||||
"history.queryHistory": "Cronologia query",
|
||||
"history.recentlyClosedTabs": "Schede chiuse di recente",
|
||||
"history.searchQueryHistory": "Cerca nella cronologia query",
|
||||
"importExport.action": "Azione",
|
||||
"importExport.addWebUrl": "Aggiungi URL web",
|
||||
"importExport.advancedConfiguration": "Configurazione avanzata",
|
||||
"importExport.archiveFolder": "Cartella archivio",
|
||||
"importExport.columns": "Colonne",
|
||||
"importExport.createZipFileInArchive": "Crea file ZIP nell'archivio",
|
||||
"importExport.currentArchive": "Archivio corrente",
|
||||
"importExport.currentDatabase": "DB corrente",
|
||||
"importExport.dragDropImportedFilesHere": "Trascina e rilascia qui i file da importare",
|
||||
"importExport.exportToZipArchive": "Archivio ZIP di output",
|
||||
"importExport.exportToZipFile": "Esporta in file ZIP",
|
||||
"importExport.generateScript": "Genera script",
|
||||
"importExport.importFromZipArchive": "Archivio ZIP di input",
|
||||
"importExport.importFromZipFile": "Importa da file ZIP (nella cartella archivio)",
|
||||
"importExport.mapSourceTablesFiles": "Mappa tabelle/file sorgente",
|
||||
"importExport.messages": "Messaggi",
|
||||
"importExport.newArchive": "Nuovo archivio",
|
||||
"importExport.outputFiles": "File di output",
|
||||
"importExport.preview": "Anteprima",
|
||||
"importExport.processingImportExport": "Elaborazione import/export ...",
|
||||
"importExport.run": "Esegui",
|
||||
"importExport.schedule": "Pianifica",
|
||||
"importExport.source": "Sorgente",
|
||||
"importExport.sourceConfiguration": "Configurazione sorgente",
|
||||
"importExport.sourceFiles": "File sorgente",
|
||||
"importExport.startVariableIndex": "Indice variabile iniziale",
|
||||
"importExport.status": "Stato",
|
||||
"importExport.stop": "Ferma",
|
||||
"importExport.storageType": "Tipo archiviazione",
|
||||
"importExport.tablesViewsCollections": "Tabelle / viste / collezioni",
|
||||
"importExport.target": "Destinazione",
|
||||
"importExport.targetConfiguration": "Configurazione destinazione",
|
||||
"indexEditor.filteredIndexCondition": "Condizione indice filtrato",
|
||||
"indexEditor.indexName": "Nome indice",
|
||||
"indexEditor.isUnique": "È indice univoco",
|
||||
"logs.autoScroll": "Scorrimento automatico",
|
||||
"logs.caller": "Chiamante:",
|
||||
"logs.callerTab": "Chiamante",
|
||||
"logs.chooseDate": "Scegli data",
|
||||
"logs.codeTab": "Codice",
|
||||
"logs.connectionId": "ID connessione:",
|
||||
"logs.connectionTab": "Connessione",
|
||||
"logs.database": "Database:",
|
||||
"logs.databaseTab": "Database",
|
||||
"logs.date": "Data:",
|
||||
"logs.dateTab": "Data",
|
||||
"logs.details": "Dettagli",
|
||||
"logs.engine": "Motore:",
|
||||
"logs.engineTab": "Motore",
|
||||
"logs.loadingNextRows": "Caricamento righe successive...",
|
||||
"logs.message": "Messaggio:",
|
||||
"logs.messageCode": "Codice messaggio:",
|
||||
"logs.messageTab": "Messaggio",
|
||||
"logs.name": "Nome:",
|
||||
"logs.nameTab": "Nome",
|
||||
"logs.noDataForSelectedDate": "Nessun dato per la data selezionata",
|
||||
"logs.recentLogs": "Log recenti",
|
||||
"logs.refresh": "Aggiorna",
|
||||
"logs.time": "Ora:",
|
||||
"logs.timeTab": "Ora",
|
||||
"menu.edit": "Modifica",
|
||||
"menu.file": "File",
|
||||
"menu.help": "Aiuto",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "Il generatore SQL non è disponibile per il database corrente",
|
||||
"newObject.tableDescription": "Crea tabella nel database corrente",
|
||||
"newObject.tableDisabled": "La creazione tabella non è disponibile per il database corrente",
|
||||
"plugins.searchExtensionsOnWeb": "Cerca estensioni sul web",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Sono elencati solo i file rilevanti per le tue connessioni, piattaforma ed edizione DbGate. Definisci prima le connessioni.",
|
||||
"publicCloudWidget.refreshFiles": "Aggiorna file",
|
||||
"publicCloudWidget.refreshList": "Aggiorna elenco",
|
||||
"publicCloudWidget.searchPublicFiles": "Cerca file pubblici",
|
||||
"query.limitRows": "Limita a {queryRowsLimit} righe",
|
||||
"query.named": ":variabile",
|
||||
"query.noParameters": "(nessun parametro)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Nome colonna",
|
||||
"sqlObject.databaseEmpty": "Il database {database} è vuoto o la struttura non è caricata, premi il pulsante Aggiorna per ricaricare la struttura",
|
||||
"sqlObject.loadingStructure": "Caricamento struttura database",
|
||||
"sqlObject.name": "Nome",
|
||||
"sqlObject.newCollection": "Nuova collezione/container",
|
||||
"sqlObject.rowCount": "Conteggio righe",
|
||||
"sqlObject.schemaName": "Schema",
|
||||
"sqlObject.search.placeholder": "Cerca in tabelle, viste, procedure",
|
||||
"sqlObject.searchBy": "Cerca per:",
|
||||
"sqlObject.sizeBytes": "Dimensione (byte)",
|
||||
"sqlObject.sortBy": "Ordina per:",
|
||||
"sqlObject.tableComment": "Commento tabella",
|
||||
"sqlObject.tableEngine": "Motore tabella",
|
||||
"sqlObject.tableViewProcedureName": "Nome tabella/vista/procedura",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Chiavi",
|
||||
"widget.pinned": "Fissate",
|
||||
"widget.tablesViewsFunctions": "Tabelle, viste, funzioni",
|
||||
"widgets.addNew": "Aggiungi nuovo",
|
||||
"widgets.administration": "Amministrazione",
|
||||
"widgets.archive": "Archivio (dati tabellari salvati)",
|
||||
"widgets.availableExtensions": "Estensioni disponibili",
|
||||
"widgets.databaseConnections": "Connessioni database",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Preferiti e file salvati",
|
||||
"widgets.installedExtensions": "Estensioni installate",
|
||||
"widgets.managePlugins": "Gestisci plugin",
|
||||
"widgets.premiumPromo": "Promo Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Cronologia query e schede chiuse",
|
||||
"widgets.selectedCellDataDetailView": "Vista dettagliata dati cella selezionata",
|
||||
"widgets.viewApplicationLogs": "Visualizza log applicazione"
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+103
-2
@@ -3,7 +3,11 @@
|
||||
"app.loading_plugin": "Carregando plugin {plugin} ...",
|
||||
"app.preparingPlugins": "Preparando plugins ...",
|
||||
"app.starting": "Iniciando DbGate",
|
||||
"connection.authToken": "Token de autenticação",
|
||||
"cellDataWidget.autodetect": "Auto detectar - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Formato não selecionado",
|
||||
"cellDataWidget.mustSelectOneCell": "Deve ser selecionada uma célula",
|
||||
"cellDataWidget.noDataSelected": "Nenhum dado selecionado",
|
||||
"cellDataWidget.title": "Visualização de dados da célula",
|
||||
"chart.detect": "Detectar gráfico",
|
||||
"chart.open": "Abrir gráfico",
|
||||
"clipboard.SQLInsert": "SQL INSERTs",
|
||||
@@ -41,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Esparso",
|
||||
"columnEditor.isUnsigned": "Sem sinal",
|
||||
"columnEditor.isZerofill": "Preenchimento com zero",
|
||||
"columnLine.addReference": "Adicionar referência",
|
||||
"columnLine.sortAscending": "Ordenar crescente",
|
||||
"columnLine.sortDescending": "Ordenar decrescente",
|
||||
"columnLine.unsort": "Remover ordenação",
|
||||
"columnsConstraintEditor.addNewColumn": "Adicionar nova coluna",
|
||||
"columnsConstraintEditor.chooseColumn": "Escolher coluna",
|
||||
"columnsConstraintEditor.selectColumn": "Selecionar coluna",
|
||||
@@ -290,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Mostre a combinação de teclas desejada e pressione ENTER",
|
||||
"common.addNew": "Adicionar novo",
|
||||
"common.advanced": "Avançado",
|
||||
"common.allFields": "Todos {field}",
|
||||
"common.archive": "Arquivo (JSONL)",
|
||||
"common.cancel": "Cancelar",
|
||||
"common.close": "Fechar",
|
||||
@@ -316,6 +325,7 @@
|
||||
"common.kill": "Encerrar",
|
||||
"common.loadingData": "Carregando dados",
|
||||
"common.name": "Nome",
|
||||
"common.newConnection": "Nova conexão",
|
||||
"common.notSelectedOptional": "(não selecionado - opcional)",
|
||||
"common.parameters": "Parâmetros",
|
||||
"common.passwordEncrypted": "Senha está criptografada",
|
||||
@@ -325,6 +335,7 @@
|
||||
"common.queryEditor": "Editor de consulta SQL",
|
||||
"common.refresh": "Atualizar",
|
||||
"common.remove": "Remover",
|
||||
"common.removeAll": "Remover tudo",
|
||||
"common.reset": "Resetar",
|
||||
"common.save": "Salvar",
|
||||
"common.saveAndNext": "Salvar e próximo",
|
||||
@@ -332,6 +343,7 @@
|
||||
"common.schema": "Schema",
|
||||
"common.search": "Pesquisar",
|
||||
"common.searchBy": "Pesquisar por:",
|
||||
"common.server": "Servidor",
|
||||
"common.sqlGenerator": "Gerador SQL",
|
||||
"common.table": "Tabela",
|
||||
"common.testingConnection": "Testando conexão",
|
||||
@@ -340,6 +352,7 @@
|
||||
"connection.allowedDatabasesRegex": "Expressão regular de bancos de dados permitidos",
|
||||
"connection.askPassword": "Não salvar, perguntar senha",
|
||||
"connection.askUser": "Não salvar, perguntar login e senha",
|
||||
"connection.authToken": "Token de autenticação",
|
||||
"connection.authentication": "Autenticação",
|
||||
"connection.autoDetectNatMap": "Auto detectar mapa NAT (use para Redis Cluster em rede Docker)",
|
||||
"connection.chooseType": "Escolher tipo",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Gatilhos",
|
||||
"dbObject.truncateTable": "Truncar tabela",
|
||||
"dbObject.views": "Visões",
|
||||
"designerTable.addReferences": "Adicionar referências",
|
||||
"designerTable.changeColor": "Alterar cor",
|
||||
"designerTable.defineVirtualForeignKey": "Definir chave estrangeira virtual",
|
||||
"designerTable.newAlias": "Novo alias",
|
||||
"designerTable.removeTableAlias": "Remover alias da tabela",
|
||||
"designerTable.setTableAlias": "Definir alias da tabela",
|
||||
"error.driverNotFound": "Conexão de banco de dados inválida, driver não encontrado",
|
||||
"error.selectedCloudConnection": "Conexão selecionada é da nuvem DbGate",
|
||||
"error.selectedNotCloudConnection": "Conexão selecionada não é da nuvem DbGate",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "Arquivos de designer de consulta",
|
||||
"file.sqlFiles": "Arquivos SQL",
|
||||
"file.sqliteDatabase": "Banco de dados SQLite",
|
||||
"files.allSupportedFiles": "Todos os arquivos suportados",
|
||||
"files.favorites": "Favoritos",
|
||||
"files.openFile": "Abrir arquivo",
|
||||
"files.refreshFiles": "Atualizar arquivos",
|
||||
"files.savedFiles": "Arquivos salvos",
|
||||
"files.searchSavedFiles": "Pesquisar arquivos salvos",
|
||||
"files.sqlFiles": "Arquivos SQL",
|
||||
"files.teamFiles": "Arquivos de equipe",
|
||||
"files.uploadFile": "Enviar arquivo",
|
||||
"filter.after": "Depois de...",
|
||||
"filter.and": "E",
|
||||
"filter.arrayIsEmpty": "Array está vazio",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Coluna ref - ",
|
||||
"foreignKeyEditor.referencedTable": "Tabela referenciada",
|
||||
"foreignKeyEditor.tableNotSet": "(tabela não definida)",
|
||||
"history.queryHistory": "Histórico de consultas",
|
||||
"history.recentlyClosedTabs": "Abas fechadas recentemente",
|
||||
"history.searchQueryHistory": "Pesquisar histórico de consultas",
|
||||
"importExport.action": "Ação",
|
||||
"importExport.addWebUrl": "Adicionar URL da web",
|
||||
"importExport.advancedConfiguration": "Configuração avançada",
|
||||
"importExport.archiveFolder": "Pasta de arquivo",
|
||||
"importExport.columns": "Colunas",
|
||||
"importExport.createZipFileInArchive": "Criar arquivo ZIP no arquivo",
|
||||
"importExport.currentArchive": "Arquivo atual",
|
||||
"importExport.currentDatabase": "BD atual",
|
||||
"importExport.dragDropImportedFilesHere": "Arraste e solte arquivos importados aqui",
|
||||
"importExport.exportToZipArchive": "Arquivo ZIP de saída",
|
||||
"importExport.exportToZipFile": "Exportar para arquivo ZIP",
|
||||
"importExport.generateScript": "Gerar script",
|
||||
"importExport.importFromZipArchive": "Arquivo ZIP de entrada",
|
||||
"importExport.importFromZipFile": "Importar de arquivo ZIP (na pasta de arquivo)",
|
||||
"importExport.mapSourceTablesFiles": "Mapear tabelas/arquivos de origem",
|
||||
"importExport.messages": "Mensagens",
|
||||
"importExport.newArchive": "Novo arquivo",
|
||||
"importExport.outputFiles": "Arquivos de saída",
|
||||
"importExport.preview": "Visualizar",
|
||||
"importExport.processingImportExport": "Processando importação/exportação ...",
|
||||
"importExport.run": "Executar",
|
||||
"importExport.schedule": "Agendar",
|
||||
"importExport.source": "Origem",
|
||||
"importExport.sourceConfiguration": "Configuração de origem",
|
||||
"importExport.sourceFiles": "Arquivos de origem",
|
||||
"importExport.startVariableIndex": "Índice inicial da variável",
|
||||
"importExport.status": "Status",
|
||||
"importExport.stop": "Parar",
|
||||
"importExport.storageType": "Tipo de armazenamento",
|
||||
"importExport.tablesViewsCollections": "Tabelas / visões / coleções",
|
||||
"importExport.target": "Destino",
|
||||
"importExport.targetConfiguration": "Configuração de destino",
|
||||
"indexEditor.filteredIndexCondition": "Condição de índice filtrado",
|
||||
"indexEditor.indexName": "Nome do índice",
|
||||
"indexEditor.isUnique": "É índice único",
|
||||
"logs.autoScroll": "Rolagem automática",
|
||||
"logs.caller": "Chamador:",
|
||||
"logs.callerTab": "Chamador",
|
||||
"logs.chooseDate": "Escolher data",
|
||||
"logs.codeTab": "Código",
|
||||
"logs.connectionId": "ID da conexão:",
|
||||
"logs.connectionTab": "Conexão",
|
||||
"logs.database": "Banco de dados:",
|
||||
"logs.databaseTab": "Banco de dados",
|
||||
"logs.date": "Data:",
|
||||
"logs.dateTab": "Data",
|
||||
"logs.details": "Detalhes",
|
||||
"logs.engine": "Motor:",
|
||||
"logs.engineTab": "Motor",
|
||||
"logs.loadingNextRows": "Carregando próximas linhas...",
|
||||
"logs.message": "Mensagem:",
|
||||
"logs.messageCode": "Código da mensagem:",
|
||||
"logs.messageTab": "Mensagem",
|
||||
"logs.name": "Nome:",
|
||||
"logs.nameTab": "Nome",
|
||||
"logs.noDataForSelectedDate": "Nenhum dado para a data selecionada",
|
||||
"logs.recentLogs": "Logs recentes",
|
||||
"logs.refresh": "Atualizar",
|
||||
"logs.time": "Hora:",
|
||||
"logs.timeTab": "Hora",
|
||||
"menu.edit": "Editar",
|
||||
"menu.file": "Arquivo",
|
||||
"menu.help": "Ajuda",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "Gerador SQL não está disponível para o banco de dados atual",
|
||||
"newObject.tableDescription": "Criar tabela no banco de dados atual",
|
||||
"newObject.tableDisabled": "Criação de tabela não está disponível para o banco de dados atual",
|
||||
"plugins.searchExtensionsOnWeb": "Pesquisar extensões na web",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Apenas arquivos relevantes para suas conexões, plataforma e edição do DbGate são listados. Defina conexões primeiro.",
|
||||
"publicCloudWidget.refreshFiles": "Atualizar arquivos",
|
||||
"publicCloudWidget.refreshList": "Atualizar lista",
|
||||
"publicCloudWidget.searchPublicFiles": "Pesquisar arquivos públicos",
|
||||
"query.limitRows": "Limitar a {queryRowsLimit} linhas",
|
||||
"query.named": ":variável",
|
||||
"query.noParameters": "(sem parâmetros)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Nome da coluna",
|
||||
"sqlObject.databaseEmpty": "Banco de dados {database} está vazio ou estrutura não foi carregada, pressione o botão Atualizar para recarregar a estrutura",
|
||||
"sqlObject.loadingStructure": "Carregando estrutura do banco de dados",
|
||||
"sqlObject.name": "Nome",
|
||||
"sqlObject.newCollection": "Nova coleção/contêiner",
|
||||
"sqlObject.rowCount": "Contagem de linhas",
|
||||
"sqlObject.schemaName": "Schema",
|
||||
"sqlObject.search.placeholder": "Pesquisar em tabelas, visões, procedimentos",
|
||||
"sqlObject.searchBy": "Pesquisar por:",
|
||||
"sqlObject.sizeBytes": "Tamanho (bytes)",
|
||||
"sqlObject.sortBy": "Ordenar por:",
|
||||
"sqlObject.tableComment": "Comentário da tabela",
|
||||
"sqlObject.tableEngine": "Motor da tabela",
|
||||
"sqlObject.tableViewProcedureName": "Nome da tabela/visão/procedimento",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Chaves",
|
||||
"widget.pinned": "Fixados",
|
||||
"widget.tablesViewsFunctions": "Tabelas, visões, funções",
|
||||
"widgets.addNew": "Adicionar novo",
|
||||
"widgets.administration": "Administração",
|
||||
"widgets.archive": "Arquivo (dados tabulares salvos)",
|
||||
"widgets.availableExtensions": "Extensões disponíveis",
|
||||
"widgets.databaseConnections": "Conexões de banco de dados",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Favoritos e arquivos salvos",
|
||||
"widgets.installedExtensions": "Extensões instaladas",
|
||||
"widgets.managePlugins": "Gerenciar plugins",
|
||||
"widgets.premiumPromo": "Promoção Premium",
|
||||
"widgets.queryHistoryAndClosedTabs": "Histórico de consultas e abas fechadas",
|
||||
"widgets.selectedCellDataDetailView": "Visualização detalhada de dados da célula selecionada",
|
||||
"widgets.viewApplicationLogs": "Ver logs da aplicação"
|
||||
}
|
||||
}
|
||||
|
||||
+102
-1
@@ -3,6 +3,11 @@
|
||||
"app.loading_plugin": "Načítavam plugin {plugin} ...",
|
||||
"app.preparingPlugins": "Príprava pluginov...",
|
||||
"app.starting": "Spúšťam DbGate",
|
||||
"cellDataWidget.autodetect": "Autodetekcia - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "Formát nie je zvolený",
|
||||
"cellDataWidget.mustSelectOneCell": "Musí byť vybraná jedna bunka",
|
||||
"cellDataWidget.noDataSelected": "Nie sú vybrané žiadne dáta",
|
||||
"cellDataWidget.title": "Zobrazenie dát bunky",
|
||||
"chart.detect": "Rozpoznať graf",
|
||||
"chart.open": "Otvoriť graf",
|
||||
"clipboard.SQLInsert": "SQL INSERT príkazy",
|
||||
@@ -40,6 +45,10 @@
|
||||
"columnEditor.isSparse": "Riedky",
|
||||
"columnEditor.isUnsigned": "Bez znamienka",
|
||||
"columnEditor.isZerofill": "Výplň nulami",
|
||||
"columnLine.addReference": "Pridať referenciu",
|
||||
"columnLine.sortAscending": "Zoradiť vzostupne",
|
||||
"columnLine.sortDescending": "Zoradiť zostupne",
|
||||
"columnLine.unsort": "Zrušiť zoradenie",
|
||||
"columnsConstraintEditor.addNewColumn": "Pridať nový stĺpec",
|
||||
"columnsConstraintEditor.chooseColumn": "Vybrať stĺpec",
|
||||
"columnsConstraintEditor.selectColumn": "Vybrať stĺpec",
|
||||
@@ -289,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "Zobraziť požadovanú klávesovú kombináciu a stlačiť ENTER",
|
||||
"common.addNew": "Pridať nový",
|
||||
"common.advanced": "Pokročilé",
|
||||
"common.allFields": "Všetky {field}",
|
||||
"common.archive": "Archivovať (JSONL)",
|
||||
"common.cancel": "Zrušiť",
|
||||
"common.close": "Zavrieť",
|
||||
@@ -315,6 +325,7 @@
|
||||
"common.kill": "Ukončiť",
|
||||
"common.loadingData": "Načítavanie dát",
|
||||
"common.name": "Názov",
|
||||
"common.newConnection": "Nové pripojenie",
|
||||
"common.notSelectedOptional": "(nezvolené - voliteľné)",
|
||||
"common.parameters": "Parametre",
|
||||
"common.passwordEncrypted": "Heslo je zašifrované",
|
||||
@@ -324,6 +335,7 @@
|
||||
"common.queryEditor": "Editor SQL dotazov",
|
||||
"common.refresh": "Obnoviť",
|
||||
"common.remove": "Odstrániť",
|
||||
"common.removeAll": "Odstrániť všetko",
|
||||
"common.reset": "Resetovať",
|
||||
"common.save": "Uložiť",
|
||||
"common.saveAndNext": "Uložiť a pokračovať",
|
||||
@@ -331,6 +343,7 @@
|
||||
"common.schema": "Schéma",
|
||||
"common.search": "Hledat",
|
||||
"common.searchBy": "Hľadať podľa:",
|
||||
"common.server": "Server",
|
||||
"common.sqlGenerator": "SQL Generátor",
|
||||
"common.table": "Tabuľka",
|
||||
"common.testingConnection": "Testovanie pripojenia",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "Triggery",
|
||||
"dbObject.truncateTable": "Orezanie tabuľky",
|
||||
"dbObject.views": "Pohľady",
|
||||
"designerTable.addReferences": "Pridať referencie",
|
||||
"designerTable.changeColor": "Zmeniť farbu",
|
||||
"designerTable.defineVirtualForeignKey": "Definovať virtuálny cudzí kľúč",
|
||||
"designerTable.newAlias": "Nový alias",
|
||||
"designerTable.removeTableAlias": "Odstrániť alias tabuľky",
|
||||
"designerTable.setTableAlias": "Nastaviť alias tabuľky",
|
||||
"error.driverNotFound": "Neplatné pripojenie k databáze, ovládač nenájdený",
|
||||
"error.selectedCloudConnection": "Vybrané pripojenie je z DbGate cloudu",
|
||||
"error.selectedNotCloudConnection": "Vybrané pripojenie nie je z DbGate cloudu",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "Súbory návrhu dotazu",
|
||||
"file.sqlFiles": "SQL súbory",
|
||||
"file.sqliteDatabase": "SQLite databáza",
|
||||
"files.allSupportedFiles": "Všetky podporované súbory",
|
||||
"files.favorites": "Obľúbené",
|
||||
"files.openFile": "Otvoriť súbor",
|
||||
"files.refreshFiles": "Obnoviť súbory",
|
||||
"files.savedFiles": "Uložené súbory",
|
||||
"files.searchSavedFiles": "Hľadať v uložených súboroch",
|
||||
"files.sqlFiles": "SQL súbory",
|
||||
"files.teamFiles": "Tímové súbory",
|
||||
"files.uploadFile": "Nahrať súbor",
|
||||
"filter.after": "Po...",
|
||||
"filter.and": "A",
|
||||
"filter.arrayIsEmpty": "Pole je prázdne",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "Referencovaný stĺpec - ",
|
||||
"foreignKeyEditor.referencedTable": "Referencovaná tabuľka - ",
|
||||
"foreignKeyEditor.tableNotSet": "(tabuľka nie je nastavená)",
|
||||
"history.queryHistory": "História dotazov",
|
||||
"history.recentlyClosedTabs": "Nedávno zatvorené karty",
|
||||
"history.searchQueryHistory": "Hľadať v histórii dotazov",
|
||||
"importExport.action": "Akcia",
|
||||
"importExport.addWebUrl": "Pridať web URL",
|
||||
"importExport.advancedConfiguration": "Pokročilá konfigurácia",
|
||||
"importExport.archiveFolder": "Archívny priečinok",
|
||||
"importExport.columns": "Stĺpce",
|
||||
"importExport.createZipFileInArchive": "Vytvoriť ZIP súbor v archíve",
|
||||
"importExport.currentArchive": "Aktuálny archív",
|
||||
"importExport.currentDatabase": "Aktuálna DB",
|
||||
"importExport.dragDropImportedFilesHere": "Pretiahnite importované súbory sem",
|
||||
"importExport.exportToZipArchive": "Exportovať do ZIP archívu",
|
||||
"importExport.exportToZipFile": "Exportovať do ZIP súboru",
|
||||
"importExport.generateScript": "Generovať skript",
|
||||
"importExport.importFromZipArchive": "Importovať zo ZIP archívu",
|
||||
"importExport.importFromZipFile": "Importovať zo ZIP súboru (v archívnej zložke)",
|
||||
"importExport.mapSourceTablesFiles": "Mapovať zdrojové tabuľky/súbory",
|
||||
"importExport.messages": "Správy",
|
||||
"importExport.newArchive": "Nový archív",
|
||||
"importExport.outputFiles": "Výstupné súbory",
|
||||
"importExport.preview": "Náhľad",
|
||||
"importExport.processingImportExport": "Spracovanie importu/exportu ...",
|
||||
"importExport.run": "Spustiť",
|
||||
"importExport.schedule": "Plánovanie",
|
||||
"importExport.source": "Zdroj",
|
||||
"importExport.sourceConfiguration": "Konfigurácia zdroja",
|
||||
"importExport.sourceFiles": "Zdrojové súbory",
|
||||
"importExport.startVariableIndex": "Počiatočný index premennej",
|
||||
"importExport.status": "Stav",
|
||||
"importExport.stop": "Zastaviť",
|
||||
"importExport.storageType": "Typ úložiska",
|
||||
"importExport.tablesViewsCollections": "Tabuľky / pohľady / kolekcie",
|
||||
"importExport.target": "Cieľ",
|
||||
"importExport.targetConfiguration": "Konfigurácia cieľa",
|
||||
"indexEditor.filteredIndexCondition": "Podmienka filtrovaného indexu",
|
||||
"indexEditor.indexName": "Názov indexu",
|
||||
"indexEditor.isUnique": "Je jedinečný index",
|
||||
"logs.autoScroll": "Automatické rolovanie",
|
||||
"logs.caller": "Volajúci:",
|
||||
"logs.callerTab": "Volajúci",
|
||||
"logs.chooseDate": "Vybrať dátum",
|
||||
"logs.codeTab": "Kód",
|
||||
"logs.connectionId": "ID pripojenia:",
|
||||
"logs.connectionTab": "Pripojenie",
|
||||
"logs.database": "Databáza:",
|
||||
"logs.databaseTab": "Databáza",
|
||||
"logs.date": "Dátum:",
|
||||
"logs.dateTab": "Dátum",
|
||||
"logs.details": "Detaily",
|
||||
"logs.engine": "Engine:",
|
||||
"logs.engineTab": "Engine",
|
||||
"logs.loadingNextRows": "Načítavanie ďalších riadkov...",
|
||||
"logs.message": "Správa:",
|
||||
"logs.messageCode": "Kód správy:",
|
||||
"logs.messageTab": "Správa",
|
||||
"logs.name": "Názov:",
|
||||
"logs.nameTab": "Názov",
|
||||
"logs.noDataForSelectedDate": "Pre zvolený dátum nie sú k dispozícii žiadne dáta",
|
||||
"logs.recentLogs": "Nedávne logy",
|
||||
"logs.refresh": "Obnoviť",
|
||||
"logs.time": "Čas:",
|
||||
"logs.timeTab": "Čas",
|
||||
"menu.edit": "Upraviť",
|
||||
"menu.file": "Súbor",
|
||||
"menu.help": "Pomoc",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "SQL Generátor nie je k dispozícii pre aktuálnu databázu",
|
||||
"newObject.tableDescription": "Vytvoriť tabuľku v aktuálnej databáze",
|
||||
"newObject.tableDisabled": "Vytvorenie tabuľky nie je k dispozícii pre aktuálnu databázu",
|
||||
"plugins.searchExtensionsOnWeb": "Hľadať rozšírenia na webe",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "Sú zobrazené iba súbory relevantné pre vaše pripojenia, platformu a edíciu DbGate. Najprv definujte pripojenia.",
|
||||
"publicCloudWidget.refreshFiles": "Obnoviť súbory",
|
||||
"publicCloudWidget.refreshList": "Obnoviť zoznam",
|
||||
"publicCloudWidget.searchPublicFiles": "Hľadať verejné súbory",
|
||||
"query.limitRows": "Obmedziť na {queryRowsLimit} riadkov",
|
||||
"query.named": ":premenná",
|
||||
"query.noParameters": "(žiadne parametre)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "Názov stĺpca",
|
||||
"sqlObject.databaseEmpty": "Databáza {database} je prázdna alebo štruktúra nie je načítaná, stlačte tlačidlo Obnoviť pre opätovné načítanie štruktúry",
|
||||
"sqlObject.loadingStructure": "Načítavanie štruktúry databázy",
|
||||
"sqlObject.name": "Názov",
|
||||
"sqlObject.newCollection": "Nová kolekcia/kontajner",
|
||||
"sqlObject.rowCount": "Počet riadkov",
|
||||
"sqlObject.schemaName": "Schéma",
|
||||
"sqlObject.search.placeholder": "Hľadať v tabuľkách, pohľadoch, procedúrach",
|
||||
"sqlObject.searchBy": "Hľadať podľa:",
|
||||
"sqlObject.sizeBytes": "Veľkosť (bajty)",
|
||||
"sqlObject.sortBy": "Zoradiť podľa:",
|
||||
"sqlObject.tableComment": "Komentár tabuľky",
|
||||
"sqlObject.tableEngine": "Engine tabuľky",
|
||||
"sqlObject.tableViewProcedureName": "Názov tabuľky/pohľadu/procedúry",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "Kľúče",
|
||||
"widget.pinned": "Pripnuté",
|
||||
"widget.tablesViewsFunctions": "Tabuľky, pohľady, funkcie",
|
||||
"widgets.addNew": "Pridať nový",
|
||||
"widgets.administration": "Administrácia",
|
||||
"widgets.archive": "Archív (uložené tabuľkové dáta)",
|
||||
"widgets.availableExtensions": "Dostupné rozšírenia",
|
||||
"widgets.databaseConnections": "Databázové pripojenia",
|
||||
"widgets.dbgateCloud": "DbGate Cloud",
|
||||
"widgets.favoritesAndSavedFiles": "Obľúbené a uložené súbory",
|
||||
"widgets.installedExtensions": "Nainštalované rozšírenia",
|
||||
"widgets.managePlugins": "Spravovať pluginy",
|
||||
"widgets.premiumPromo": "Premium promo",
|
||||
"widgets.queryHistoryAndClosedTabs": "História dotazov a zatvorené karty",
|
||||
"widgets.selectedCellDataDetailView": "Detailné zobrazenie dát vybranej bunky",
|
||||
"widgets.viewApplicationLogs": "Zobraziť aplikačné logy"
|
||||
}
|
||||
}
|
||||
|
||||
+102
-1
@@ -3,6 +3,11 @@
|
||||
"app.loading_plugin": "正在加载插件 {plugin} ...",
|
||||
"app.preparingPlugins": "正在准备插件 ...",
|
||||
"app.starting": "正在启动 DbGate",
|
||||
"cellDataWidget.autodetect": "自动检测 - {autoDetectTitle}",
|
||||
"cellDataWidget.formatNotSelected": "未选择格式",
|
||||
"cellDataWidget.mustSelectOneCell": "必须选择一个单元格",
|
||||
"cellDataWidget.noDataSelected": "未选择数据",
|
||||
"cellDataWidget.title": "单元格数据视图",
|
||||
"chart.detect": "检测图表",
|
||||
"chart.open": "打开图表",
|
||||
"clipboard.SQLInsert": "SQL INSERT 语句",
|
||||
@@ -40,6 +45,10 @@
|
||||
"columnEditor.isSparse": "稀疏",
|
||||
"columnEditor.isUnsigned": "无符号",
|
||||
"columnEditor.isZerofill": "零填充",
|
||||
"columnLine.addReference": "添加引用",
|
||||
"columnLine.sortAscending": "升序排序",
|
||||
"columnLine.sortDescending": "降序排序",
|
||||
"columnLine.unsort": "取消排序",
|
||||
"columnsConstraintEditor.addNewColumn": "添加新列",
|
||||
"columnsConstraintEditor.chooseColumn": "选择列",
|
||||
"columnsConstraintEditor.selectColumn": "选择列",
|
||||
@@ -289,6 +298,7 @@
|
||||
"commandModal.showKeyCombination": "显示所需的键盘组合并按回车键",
|
||||
"common.addNew": "添加新项",
|
||||
"common.advanced": "高级",
|
||||
"common.allFields": "所有 {field}",
|
||||
"common.archive": "归档 (JSONL)",
|
||||
"common.cancel": "取消",
|
||||
"common.close": "关闭",
|
||||
@@ -315,6 +325,7 @@
|
||||
"common.kill": "终止",
|
||||
"common.loadingData": "正在加载数据",
|
||||
"common.name": "名称",
|
||||
"common.newConnection": "新建连接",
|
||||
"common.notSelectedOptional": "(未选择 - 可选)",
|
||||
"common.parameters": "参数",
|
||||
"common.passwordEncrypted": "密码已加密",
|
||||
@@ -324,6 +335,7 @@
|
||||
"common.queryEditor": "SQL 查询编辑器",
|
||||
"common.refresh": "刷新",
|
||||
"common.remove": "移除",
|
||||
"common.removeAll": "全部移除",
|
||||
"common.reset": "重置",
|
||||
"common.save": "保存",
|
||||
"common.saveAndNext": "保存并下一个",
|
||||
@@ -331,6 +343,7 @@
|
||||
"common.schema": "模式",
|
||||
"common.search": "搜索",
|
||||
"common.searchBy": "搜索方式:",
|
||||
"common.server": "服务器",
|
||||
"common.sqlGenerator": "SQL 生成器",
|
||||
"common.table": "表",
|
||||
"common.testingConnection": "正在测试连接",
|
||||
@@ -574,6 +587,12 @@
|
||||
"dbObject.triggers": "触发器",
|
||||
"dbObject.truncateTable": "截断表",
|
||||
"dbObject.views": "视图",
|
||||
"designerTable.addReferences": "添加引用",
|
||||
"designerTable.changeColor": "更改颜色",
|
||||
"designerTable.defineVirtualForeignKey": "定义虚拟外键",
|
||||
"designerTable.newAlias": "新建别名",
|
||||
"designerTable.removeTableAlias": "移除表别名",
|
||||
"designerTable.setTableAlias": "设置表别名",
|
||||
"error.driverNotFound": "无效的数据库连接,未找到驱动程序",
|
||||
"error.selectedCloudConnection": "选定的连接来自DbGate云",
|
||||
"error.selectedNotCloudConnection": "选定的连接不来自DbGate云",
|
||||
@@ -588,6 +607,15 @@
|
||||
"file.queryDesignerFiles": "查询设计器文件",
|
||||
"file.sqlFiles": "SQL文件",
|
||||
"file.sqliteDatabase": "SQLite数据库",
|
||||
"files.allSupportedFiles": "所有支持的文件",
|
||||
"files.favorites": "收藏",
|
||||
"files.openFile": "打开文件",
|
||||
"files.refreshFiles": "刷新文件",
|
||||
"files.savedFiles": "已保存文件",
|
||||
"files.searchSavedFiles": "搜索已保存文件",
|
||||
"files.sqlFiles": "SQL 文件",
|
||||
"files.teamFiles": "团队文件",
|
||||
"files.uploadFile": "上传文件",
|
||||
"filter.after": "之后...",
|
||||
"filter.and": "且",
|
||||
"filter.arrayIsEmpty": "数组为空",
|
||||
@@ -669,16 +697,69 @@
|
||||
"foreignKeyEditor.refColumn": "引用列 - ",
|
||||
"foreignKeyEditor.referencedTable": "引用表",
|
||||
"foreignKeyEditor.tableNotSet": "(未设置表)",
|
||||
"history.queryHistory": "查询历史",
|
||||
"history.recentlyClosedTabs": "最近关闭的标签页",
|
||||
"history.searchQueryHistory": "搜索查询历史",
|
||||
"importExport.action": "操作",
|
||||
"importExport.addWebUrl": "添加 Web URL",
|
||||
"importExport.advancedConfiguration": "高级配置",
|
||||
"importExport.archiveFolder": "归档文件夹",
|
||||
"importExport.columns": "列",
|
||||
"importExport.createZipFileInArchive": "在存档中创建ZIP文件",
|
||||
"importExport.currentArchive": "当前归档",
|
||||
"importExport.currentDatabase": "当前数据库",
|
||||
"importExport.dragDropImportedFilesHere": "将导入的文件拖放到此处",
|
||||
"importExport.exportToZipArchive": "输出ZIP存档",
|
||||
"importExport.exportToZipFile": "导出到ZIP文件",
|
||||
"importExport.generateScript": "生成脚本",
|
||||
"importExport.importFromZipArchive": "输入ZIP存档",
|
||||
"importExport.importFromZipFile": "从ZIP文件导入(在存档文件夹中)",
|
||||
"importExport.mapSourceTablesFiles": "映射源表/文件",
|
||||
"importExport.messages": "消息",
|
||||
"importExport.newArchive": "新建归档",
|
||||
"importExport.outputFiles": "输出文件",
|
||||
"importExport.preview": "预览",
|
||||
"importExport.processingImportExport": "正在处理导入/导出 ...",
|
||||
"importExport.run": "运行",
|
||||
"importExport.schedule": "计划",
|
||||
"importExport.source": "源",
|
||||
"importExport.sourceConfiguration": "源配置",
|
||||
"importExport.sourceFiles": "源文件",
|
||||
"importExport.startVariableIndex": "起始变量索引",
|
||||
"importExport.status": "状态",
|
||||
"importExport.stop": "停止",
|
||||
"importExport.storageType": "存储类型",
|
||||
"importExport.tablesViewsCollections": "表 / 视图 / 集合",
|
||||
"importExport.target": "目标",
|
||||
"importExport.targetConfiguration": "目标配置",
|
||||
"indexEditor.filteredIndexCondition": "过滤索引条件",
|
||||
"indexEditor.indexName": "索引名称",
|
||||
"indexEditor.isUnique": "是唯一索引",
|
||||
"logs.autoScroll": "自动滚动",
|
||||
"logs.caller": "调用方:",
|
||||
"logs.callerTab": "调用方",
|
||||
"logs.chooseDate": "选择日期",
|
||||
"logs.codeTab": "代码",
|
||||
"logs.connectionId": "连接 ID:",
|
||||
"logs.connectionTab": "连接",
|
||||
"logs.database": "数据库:",
|
||||
"logs.databaseTab": "数据库",
|
||||
"logs.date": "日期:",
|
||||
"logs.dateTab": "日期",
|
||||
"logs.details": "详情",
|
||||
"logs.engine": "引擎:",
|
||||
"logs.engineTab": "引擎",
|
||||
"logs.loadingNextRows": "正在加载下一批行...",
|
||||
"logs.message": "消息:",
|
||||
"logs.messageCode": "消息代码:",
|
||||
"logs.messageTab": "消息",
|
||||
"logs.name": "名称:",
|
||||
"logs.nameTab": "名称",
|
||||
"logs.noDataForSelectedDate": "所选日期无数据",
|
||||
"logs.recentLogs": "最近日志",
|
||||
"logs.refresh": "刷新",
|
||||
"logs.time": "时间:",
|
||||
"logs.timeTab": "时间",
|
||||
"menu.edit": "编辑",
|
||||
"menu.file": "文件",
|
||||
"menu.help": "帮助",
|
||||
@@ -703,6 +784,11 @@
|
||||
"newObject.sqlGeneratorDisabled": "当前数据库不支持SQL生成器",
|
||||
"newObject.tableDescription": "在当前数据库中创建表",
|
||||
"newObject.tableDisabled": "当前数据库不支持创建表",
|
||||
"plugins.searchExtensionsOnWeb": "在网页上搜索扩展",
|
||||
"publicCloudWidget.onlyRelevantFilesListed": "仅列出与您的连接、平台和 DbGate 版本相关的文件。请先定义连接。",
|
||||
"publicCloudWidget.refreshFiles": "刷新文件",
|
||||
"publicCloudWidget.refreshList": "刷新列表",
|
||||
"publicCloudWidget.searchPublicFiles": "搜索公共文件",
|
||||
"query.limitRows": "限制 {queryRowsLimit} 行",
|
||||
"query.named": ":variable",
|
||||
"query.noParameters": "(无参数)",
|
||||
@@ -819,10 +905,14 @@
|
||||
"sqlObject.columnName": "列名称",
|
||||
"sqlObject.databaseEmpty": "数据库 {database} 为空或结构未加载,请按刷新按钮重新加载结构",
|
||||
"sqlObject.loadingStructure": "加载数据库结构",
|
||||
"sqlObject.name": "名称",
|
||||
"sqlObject.newCollection": "新集合/容器",
|
||||
"sqlObject.rowCount": "行数",
|
||||
"sqlObject.schemaName": "模式",
|
||||
"sqlObject.search.placeholder": "在表、视图、存储过程中搜索",
|
||||
"sqlObject.searchBy": "搜索条件:",
|
||||
"sqlObject.sizeBytes": "大小(字节)",
|
||||
"sqlObject.sortBy": "排序方式:",
|
||||
"sqlObject.tableComment": "表注释",
|
||||
"sqlObject.tableEngine": "表引擎",
|
||||
"sqlObject.tableViewProcedureName": "表/视图/存储过程名称",
|
||||
@@ -902,6 +992,17 @@
|
||||
"widget.keys": "键",
|
||||
"widget.pinned": "已固定",
|
||||
"widget.tablesViewsFunctions": "表、视图、函数",
|
||||
"widgets.addNew": "添加新项",
|
||||
"widgets.administration": "管理",
|
||||
"widgets.archive": "归档(已保存的表格数据)",
|
||||
"widgets.availableExtensions": "可用扩展",
|
||||
"widgets.databaseConnections": "数据库连接",
|
||||
"widgets.dbgateCloud": "DbGate 云",
|
||||
"widgets.favoritesAndSavedFiles": "收藏和已保存文件",
|
||||
"widgets.installedExtensions": "已安装扩展",
|
||||
"widgets.managePlugins": "管理插件",
|
||||
"widgets.premiumPromo": "高级版推广",
|
||||
"widgets.queryHistoryAndClosedTabs": "查询历史和已关闭标签页",
|
||||
"widgets.selectedCellDataDetailView": "选定单元格数据详细视图",
|
||||
"widgets.viewApplicationLogs": "查看应用程序日志"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ checkout-and-merge-pro:
|
||||
repository: dbgate/dbgate-pro
|
||||
token: ${{ secrets.GH_TOKEN }}
|
||||
path: dbgate-pro
|
||||
ref: f27a03d4aff5b00a009643df146a9c17bdbf7801
|
||||
ref: 8df782559b84d6b59342c9488f3ca340074f35d6
|
||||
- name: Merge dbgate/dbgate-pro
|
||||
run: |
|
||||
mkdir ../dbgate-pro
|
||||
|
||||
@@ -49,26 +49,26 @@ jobs:
|
||||
cd packages/tools
|
||||
yarn test:ci
|
||||
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: integration-tests/result.json
|
||||
action-name: Integration tests
|
||||
# - uses: tanmen/jest-reporter@v1
|
||||
# if: always()
|
||||
# with:
|
||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# result-file: integration-tests/result.json
|
||||
# action-name: Integration tests
|
||||
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/filterparser/result.json
|
||||
action-name: Filter parser test results
|
||||
# - uses: tanmen/jest-reporter@v1
|
||||
# if: always()
|
||||
# with:
|
||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# result-file: packages/filterparser/result.json
|
||||
# action-name: Filter parser test results
|
||||
|
||||
- uses: tanmen/jest-reporter@v1
|
||||
if: always()
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
result-file: packages/datalib/result.json
|
||||
action-name: Datalib (perspectives) test results
|
||||
# - uses: tanmen/jest-reporter@v1
|
||||
# if: always()
|
||||
# with:
|
||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# result-file: packages/datalib/result.json
|
||||
# action-name: Datalib (perspectives) test results
|
||||
|
||||
services:
|
||||
postgres-integr:
|
||||
|
||||
Reference in New Issue
Block a user