mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-23 23:05:59 +00:00
Merge pull request #1281 from dbgate/feature/translation4
Feature/translation4
This commit is contained in:
@@ -53,14 +53,15 @@
|
||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let data;
|
||||
|
||||
const handleRename = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: data.fileName,
|
||||
label: 'New file name',
|
||||
header: 'Rename file',
|
||||
label: _t('appFile.newFileName', { defaultMessage: 'New file name' }),
|
||||
header: _t('appFile.renameFile', { defaultMessage: 'Rename file' }),
|
||||
onConfirm: newFile => {
|
||||
apiCall('apps/rename-file', {
|
||||
file: data.fileName,
|
||||
@@ -74,7 +75,7 @@
|
||||
|
||||
const handleDelete = () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really delete file ${data.fileName}?`,
|
||||
message: _t('appFile.deleteFileConfirm', { defaultMessage: 'Really delete file {fileName}?', values: { fileName: data.fileName } }),
|
||||
onConfirm: () => {
|
||||
apiCall('apps/delete-file', {
|
||||
file: data.fileName,
|
||||
@@ -101,10 +102,10 @@
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
{ text: 'Delete', onClick: handleDelete },
|
||||
{ text: 'Rename', onClick: handleRename },
|
||||
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile },
|
||||
data.fileType.endsWith('.json') && { text: 'Open JSON', onClick: handleOpenJsonFile },
|
||||
{ text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
{ text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
data.fileType.endsWith('.sql') && { text: _t('common.openSql', { defaultMessage: 'Open SQL' }), onClick: handleOpenSqlFile },
|
||||
data.fileType.endsWith('.json') && { text: _t('common.openJson', { defaultMessage: 'Open JSON' }), onClick: handleOpenJsonFile },
|
||||
|
||||
// data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile },
|
||||
];
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { useConnectionList } from '../utility/metadataLoaders';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -34,8 +35,8 @@
|
||||
|
||||
showModal(InputTextModal, {
|
||||
value: name,
|
||||
label: 'New application name',
|
||||
header: 'Rename application',
|
||||
label: _t('appFolder.newApplicationName', { defaultMessage: 'New application name' }),
|
||||
header: _t('appFolder.renameApplication', { defaultMessage: 'Rename application' }),
|
||||
onConfirm: async newFolder => {
|
||||
await apiCall('apps/rename-folder', {
|
||||
folder: data.name,
|
||||
@@ -60,16 +61,16 @@
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
{ text: 'Delete', onClick: handleDelete },
|
||||
{ text: 'Rename', onClick: handleRename },
|
||||
{ text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
{ text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
|
||||
$currentDatabase && [
|
||||
!isOnCurrentDb($currentDatabase, $connections) && {
|
||||
text: 'Enable on current database',
|
||||
text: _t('appFolder.enableOnCurrentDatabase', { defaultMessage: 'Enable on current database' }),
|
||||
onClick: () => setOnCurrentDb(true),
|
||||
},
|
||||
isOnCurrentDb($currentDatabase, $connections) && {
|
||||
text: 'Disable on current database',
|
||||
text: _t('appFolder.disableOnCurrentDatabase', { defaultMessage: 'Disable on current database' }),
|
||||
onClick: () => setOnCurrentDb(false),
|
||||
},
|
||||
],
|
||||
@@ -90,7 +91,7 @@
|
||||
title={data.name}
|
||||
icon={'img app'}
|
||||
statusIcon={isOnCurrentDb($currentDatabase, $connections) ? 'icon check' : null}
|
||||
statusTitle={`Application ${data.name} is used for database ${$currentDatabase?.name}`}
|
||||
statusTitle={_t('appFolder.applicationUsedForDatabase', { defaultMessage: 'Application {application} is used for database {database}', values: { application: data.name, database: $currentDatabase?.name } })}
|
||||
isBold={data.name == $currentApplication}
|
||||
on:click={() => ($currentApplication = data.name)}
|
||||
menu={createMenu}
|
||||
|
||||
@@ -82,6 +82,7 @@
|
||||
import { apiCall } from '../utility/api';
|
||||
import { openImportExportTab } from '../utility/importExportTools';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let data;
|
||||
$: isZipped = data.folderName?.endsWith('.zip');
|
||||
@@ -89,8 +90,8 @@
|
||||
const handleRename = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: data.fileName,
|
||||
label: 'New file name',
|
||||
header: 'Rename file',
|
||||
label: _t('archiveFile.newFileName', { defaultMessage: 'New file name' }),
|
||||
header: _t('archiveFile.renameFile', { defaultMessage: 'Rename file' }),
|
||||
onConfirm: newFile => {
|
||||
apiCall('archive/rename-file', {
|
||||
file: data.fileName,
|
||||
@@ -104,7 +105,7 @@
|
||||
|
||||
const handleDelete = () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really delete file ${data.fileName}?`,
|
||||
message: _t('archiveFile.deleteFileConfirm', { defaultMessage: 'Really delete file {fileName}?', values: { fileName: data.fileName } }),
|
||||
onConfirm: () => {
|
||||
apiCall('archive/delete-file', {
|
||||
file: data.fileName,
|
||||
@@ -147,10 +148,10 @@
|
||||
}
|
||||
|
||||
return [
|
||||
data.fileType == 'jsonl' && { text: 'Open', onClick: handleOpenArchive },
|
||||
data.fileType == 'jsonl' && { text: 'Open in text editor', onClick: handleOpenJsonLinesText },
|
||||
!isZipped && { text: 'Delete', onClick: handleDelete },
|
||||
!isZipped && { text: 'Rename', onClick: handleRename },
|
||||
data.fileType == 'jsonl' && { text: _t('common.open', { defaultMessage: 'Open' }), onClick: handleOpenArchive },
|
||||
data.fileType == 'jsonl' && { text: _t('common.openInTextEditor', { defaultMessage: 'Open in text editor' }), onClick: handleOpenJsonLinesText },
|
||||
!isZipped && { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
!isZipped && { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
data.fileType == 'jsonl' &&
|
||||
createQuickExportMenu(
|
||||
fmt => async () => {
|
||||
@@ -185,19 +186,19 @@
|
||||
},
|
||||
}
|
||||
),
|
||||
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile },
|
||||
data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile },
|
||||
data.fileType.endsWith('.sql') && { text: _t('common.openSql', { defaultMessage: 'Open SQL' }), onClick: handleOpenSqlFile },
|
||||
data.fileType.endsWith('.yaml') && { text: _t('common.openYaml', { defaultMessage: 'Open YAML' }), onClick: handleOpenYamlFile },
|
||||
!isZipped &&
|
||||
isProApp() &&
|
||||
data.fileType == 'jsonl' && {
|
||||
text: 'Open in profiler',
|
||||
text: _t('common.openInProfiler', { defaultMessage: 'Open in profiler' }),
|
||||
submenu: getExtensions()
|
||||
.drivers.filter(eng => eng.profilerFormatterFunction)
|
||||
.map(eng => ({
|
||||
text: eng.title,
|
||||
onClick: () => {
|
||||
openNewTab({
|
||||
title: 'Profiler',
|
||||
title: _t('common.profiler', { defaultMessage: 'Profiler' }),
|
||||
icon: 'img profiler',
|
||||
tabComponent: 'ProfilerTab',
|
||||
props: {
|
||||
|
||||
@@ -21,14 +21,15 @@
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||
import { saveFileToDisk } from '../utility/exportFileTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let data;
|
||||
|
||||
const handleDelete = () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: data.name.endsWith('.link')
|
||||
? `Really delete link to folder ${data.name}? Folder content remains untouched.`
|
||||
: `Really delete folder ${data.name}?`,
|
||||
? _t('archiveFolder.deleteLinkConfirm', { defaultMessage: 'Really delete link to folder {folderName}? Folder content remains untouched.', values: { folderName: data.name } })
|
||||
: _t('archiveFolder.deleteFolderConfirm', { defaultMessage: 'Really delete folder {folderName}?', values: { folderName: data.name } }),
|
||||
onConfirm: () => {
|
||||
apiCall('archive/delete-folder', { folder: data.name });
|
||||
},
|
||||
@@ -42,8 +43,8 @@
|
||||
|
||||
showModal(InputTextModal, {
|
||||
value: name,
|
||||
label: 'New folder name',
|
||||
header: 'Rename folder',
|
||||
label: _t('archiveFolder.newFolderName', { defaultMessage: 'New folder name' }),
|
||||
header: _t('archiveFolder.renameFolder', { defaultMessage: 'Rename folder' }),
|
||||
onConfirm: async newFolder => {
|
||||
await apiCall('archive/rename-folder', {
|
||||
folder: data.name,
|
||||
@@ -95,7 +96,7 @@ await dbgateApi.deployDb(${JSON.stringify(
|
||||
const handleCompareWithCurrentDb = () => {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Compare',
|
||||
title: _t('common.compare', { defaultMessage: 'Compare' }),
|
||||
icon: 'img compare',
|
||||
tabComponent: 'CompareModelTab',
|
||||
props: {
|
||||
@@ -153,7 +154,7 @@ await dbgateApi.deployDb(${JSON.stringify(
|
||||
});
|
||||
},
|
||||
{
|
||||
formatLabel: 'ZIP files',
|
||||
formatLabel: _t('common.zipFiles', { defaultMessage: 'ZIP files' }),
|
||||
formatExtension: 'zip',
|
||||
defaultFileName: data.name?.endsWith('.zip') ? data.name : data.name + '.zip',
|
||||
}
|
||||
@@ -162,28 +163,28 @@ await dbgateApi.deployDb(${JSON.stringify(
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
data.name != 'default' && { text: 'Delete', onClick: handleDelete },
|
||||
data.name != 'default' && { text: 'Rename', onClick: handleRename },
|
||||
isProApp() && { text: 'Data deployer', onClick: handleOpenDataDeployTab },
|
||||
data.name != 'default' && { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
data.name != 'default' && { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
isProApp() && { text: _t('common.dataDeployer', { defaultMessage: 'Data deployer' }), onClick: handleOpenDataDeployTab },
|
||||
$currentDatabase && [
|
||||
{ text: 'Generate deploy DB SQL', onClick: handleGenerateDeploySql },
|
||||
hasPermission(`run-shell-script`) && { text: 'Shell: Deploy DB', onClick: handleGenerateDeployScript },
|
||||
{ text: _t('archiveFolder.generateDeployDbSql', { defaultMessage: 'Generate deploy DB SQL' }), onClick: handleGenerateDeploySql },
|
||||
hasPermission(`run-shell-script`) && { text: _t('archiveFolder.shellDeployDb', { defaultMessage: 'Shell: Deploy DB' }), onClick: handleGenerateDeployScript },
|
||||
],
|
||||
data.name != 'default' &&
|
||||
isProApp() &&
|
||||
data.name.endsWith('.zip') && { text: 'Unpack ZIP', onClick: () => handleZipUnzip('archive/unzip') },
|
||||
data.name.endsWith('.zip') && { text: _t('archiveFolder.unpackZip', { defaultMessage: 'Unpack ZIP' }), onClick: () => handleZipUnzip('archive/unzip') },
|
||||
data.name != 'default' &&
|
||||
isProApp() &&
|
||||
!data.name.endsWith('.zip') && { text: 'Pack (create ZIP)', onClick: () => handleZipUnzip('archive/zip') },
|
||||
!data.name.endsWith('.zip') && { text: _t('archiveFolder.packZip', { defaultMessage: 'Pack (create ZIP)' }), onClick: () => handleZipUnzip('archive/zip') },
|
||||
|
||||
isProApp() && { text: 'Download ZIP', onClick: handleDownloadZip },
|
||||
isProApp() && { text: _t('archiveFolder.downloadZip', { defaultMessage: 'Download ZIP' }), onClick: handleDownloadZip },
|
||||
|
||||
data.name != 'default' &&
|
||||
hasPermission('dbops/model/compare') &&
|
||||
isProApp() &&
|
||||
_.get($currentDatabase, 'connection._id') && {
|
||||
onClick: handleCompareWithCurrentDb,
|
||||
text: `Compare with ${_.get($currentDatabase, 'name')}`,
|
||||
text: _t('archiveFolder.compareWithCurrentDb', { defaultMessage: 'Compare with {name}', values: { name: _.get($currentDatabase, 'name') } }),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@@ -407,8 +407,8 @@ await dbgateApi.executeQuery(${JSON.stringify(
|
||||
|
||||
const handleCreateNewApp = () => {
|
||||
showModal(InputTextModal, {
|
||||
header: 'New application',
|
||||
label: 'Application name',
|
||||
header: _t('database.newApplication', { defaultMessage: 'New application' }),
|
||||
label: _t('database.applicationName', { defaultMessage: 'Application name' }),
|
||||
value: _.startCase(name),
|
||||
onConfirm: async appName => {
|
||||
const newAppId = await apiCall('apps/create-app-from-db', {
|
||||
|
||||
@@ -199,12 +199,12 @@
|
||||
divider: true,
|
||||
},
|
||||
hasPermission('dbops/export') && {
|
||||
label: 'Export',
|
||||
label: _t('common.export', { defaultMessage: 'Export' }),
|
||||
functionName: 'tableReader',
|
||||
isExport: true,
|
||||
},
|
||||
hasPermission('dbops/import') && {
|
||||
label: 'Import',
|
||||
label: _t('common.import', { defaultMessage: 'Import' }),
|
||||
isImport: true,
|
||||
requiresWriteAccess: true,
|
||||
},
|
||||
@@ -260,7 +260,7 @@
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
label: 'Export',
|
||||
label: _t('common.export', { defaultMessage: 'Export' }),
|
||||
isExport: true,
|
||||
functionName: 'tableReader',
|
||||
},
|
||||
@@ -310,7 +310,7 @@
|
||||
divider: true,
|
||||
},
|
||||
{
|
||||
label: 'Export',
|
||||
label: _t('common.export', { defaultMessage: 'Export' }),
|
||||
isExport: true,
|
||||
functionName: 'tableReader',
|
||||
},
|
||||
@@ -402,7 +402,7 @@
|
||||
icon: 'img perspective',
|
||||
},
|
||||
hasPermission('dbops/export') && {
|
||||
label: 'Export',
|
||||
label: _t('common.export', { defaultMessage: 'Export' }),
|
||||
isExport: true,
|
||||
functionName: 'tableReader',
|
||||
},
|
||||
|
||||
@@ -193,6 +193,7 @@
|
||||
import { saveFileToDisk } from '../utility/exportFileTools';
|
||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let data;
|
||||
|
||||
@@ -214,27 +215,26 @@
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
handler?.tabComponent && { text: 'Open', onClick: openTab },
|
||||
handler?.tabComponent && { text: _t('common.open', { defaultMessage: 'Open' }), onClick: openTab },
|
||||
|
||||
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: 'Rename', onClick: handleRename },
|
||||
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: 'Create copy', onClick: handleCopy },
|
||||
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: 'Delete', onClick: handleDelete },
|
||||
|
||||
data.teamFileId && data.allowWrite && { text: 'Rename', onClick: handleRename },
|
||||
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: _t('common.createCopy', { defaultMessage: 'Create copy' }), onClick: handleCopy },
|
||||
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
data.teamFileId && data.allowWrite && { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
data.teamFileId &&
|
||||
data.allowRead &&
|
||||
hasPermission('all-team-files/create') && { text: 'Create copy', onClick: handleCopy },
|
||||
data.teamFileId && data.allowWrite && { text: 'Delete', onClick: handleDelete },
|
||||
hasPermission('all-team-files/create') && { text: _t('common.createCopy', { defaultMessage: 'Create copy' }), onClick: handleCopy },
|
||||
data.teamFileId && data.allowWrite && { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
|
||||
folder == 'markdown' && { text: 'Show page', onClick: showMarkdownPage },
|
||||
!data.teamFileId && { text: 'Download', onClick: handleDownload },
|
||||
data.teamFileId && data.allowRead && { text: 'Download', onClick: handleDownload },
|
||||
folder == 'markdown' && { text: _t('common.showPage', { defaultMessage: 'Show page' }), onClick: showMarkdownPage },
|
||||
!data.teamFileId && { text: _t('common.download', { defaultMessage: 'Download' }), onClick: handleDownload },
|
||||
data.teamFileId && data.allowRead && { text: _t('common.download', { defaultMessage: 'Download' }), onClick: handleDownload },
|
||||
];
|
||||
}
|
||||
|
||||
const handleDelete = () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really delete file ${data.file}?`,
|
||||
message: _t('common.reallyDeleteFile', { defaultMessage: 'Really delete file {file}?', values: { file: data.file } }),
|
||||
onConfirm: () => {
|
||||
if (data.teamFileId) {
|
||||
apiCall('team-files/delete', { teamFileId: data.teamFileId });
|
||||
@@ -253,8 +253,8 @@
|
||||
const handleRename = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: data.file,
|
||||
label: 'New file name',
|
||||
header: 'Rename file',
|
||||
label: _t('common.newFileName', { defaultMessage: 'New file name' }),
|
||||
header: _t('common.renameFile', { defaultMessage: 'Rename file' }),
|
||||
onConfirm: newFile => {
|
||||
if (data.teamFileId) {
|
||||
apiCall('team-files/update', { teamFileId: data.teamFileId, name: newFile });
|
||||
@@ -274,8 +274,8 @@
|
||||
const handleCopy = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: data.file,
|
||||
label: 'New file name',
|
||||
header: 'Copy file',
|
||||
label: _t('savedFile.newFileName', { defaultMessage: 'New file name' }),
|
||||
header: _t('savedFile.copyFile', { defaultMessage: 'Copy file' }),
|
||||
onConfirm: newFile => {
|
||||
if (data.teamFileId) {
|
||||
apiCall('team-files/copy', { teamFileId: data.teamFileId, newName: newFile });
|
||||
@@ -323,12 +323,12 @@
|
||||
if (data.teamFileId) {
|
||||
if (data?.metadata?.autoExecute) {
|
||||
if (!data.allowUse) {
|
||||
showSnackbarError('You do not have permission to use this team file');
|
||||
showSnackbarError(_t('savedFile.noPermissionUseTeamFile', { defaultMessage: 'You do not have permission to use this team file' }));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (!data.allowRead) {
|
||||
showSnackbarError('You do not have permission to read this team file');
|
||||
showSnackbarError(_t('savedFile.noPermissionReadTeamFile', { defaultMessage: 'You do not have permission to read this team file' }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
import { getLocalStorage } from '../utility/storageCache';
|
||||
import registerCommand from './registerCommand';
|
||||
import { formatKeyText, switchCurrentDatabase } from '../utility/common';
|
||||
import { _tval, __t } from '../translations';
|
||||
import { _tval, __t, _t } from '../translations';
|
||||
|
||||
let domInput;
|
||||
let filter = '';
|
||||
@@ -181,7 +181,7 @@
|
||||
domInput.focus();
|
||||
}}
|
||||
>
|
||||
<FontIcon icon="icon menu" /> Commands
|
||||
<FontIcon icon="icon menu" /> {_t('commandPalette.commands', { defaultMessage: 'Commands' })}
|
||||
</div>
|
||||
<div
|
||||
class="page"
|
||||
@@ -191,7 +191,7 @@
|
||||
domInput.focus();
|
||||
}}
|
||||
>
|
||||
<FontIcon icon="icon database" /> Database
|
||||
<FontIcon icon="icon database" /> {_t('common.database', { defaultMessage: 'Database' })}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mainInner">
|
||||
@@ -201,8 +201,8 @@
|
||||
bind:this={domInput}
|
||||
bind:value={filter}
|
||||
on:keydown={handleKeyDown}
|
||||
placeholder={parentCommand?.text ||
|
||||
($visibleCommandPalette == 'database' ? 'Search in database' : 'Search in commands')}
|
||||
placeholder={_tval(parentCommand?.text) ||
|
||||
($visibleCommandPalette == 'database' ? _t('commandPalette.searchInDatabase', { defaultMessage: 'Search in database' }) : _t('commandPalette.searchInCommands', { defaultMessage: 'Search in commands' }))}
|
||||
/>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script context="module" lang="ts">
|
||||
import { __t } from '../translations'
|
||||
import { __t, _t } from '../translations'
|
||||
const getCurrentEditor = () => getActiveComponent('SqlDataGridCore');
|
||||
|
||||
registerCommand({
|
||||
@@ -127,7 +127,7 @@
|
||||
export function openQuery(sql?) {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Query #',
|
||||
title: _t('common.queryNumber', { defaultMessage: 'Query #' }),
|
||||
icon: 'img sql-file',
|
||||
tabComponent: 'QueryTab',
|
||||
focused: true,
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import dragScroll from '../utility/dragScroll';
|
||||
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||
import { __t } from '../translations';
|
||||
import { __t, _t } from '../translations';
|
||||
|
||||
export let value;
|
||||
export let onChange;
|
||||
@@ -849,45 +849,45 @@
|
||||
settings?.customizeStyle && [
|
||||
{ divider: true },
|
||||
isProApp() && {
|
||||
text: 'Column properties',
|
||||
text: _t('designer.columnProperties', { defaultMessage: 'Column properties' }),
|
||||
submenu: [
|
||||
{
|
||||
text: `Nullability: ${value?.style?.showNullability ? 'YES' : 'NO'}`,
|
||||
text: _t('designer.nullabilityYesNo', { defaultMessage: 'Nullability: {show}', values: { show: value?.style?.showNullability ? 'YES' : 'NO' } }),
|
||||
onClick: changeStyleFunc('showNullability', !value?.style?.showNullability),
|
||||
},
|
||||
{
|
||||
text: `Data type: ${value?.style?.showDataType ? 'YES' : 'NO'}`,
|
||||
text: _t('designer.dataTypeYesNo', { defaultMessage: 'Data type: {show}', values: { show: value?.style?.showDataType ? 'YES' : 'NO' } }),
|
||||
onClick: changeStyleFunc('showDataType', !value?.style?.showDataType),
|
||||
},
|
||||
],
|
||||
},
|
||||
isProApp() && {
|
||||
text: `Columns - ${_.startCase(value?.style?.filterColumns || 'all')}`,
|
||||
text: _t('designer.columns', { defaultMessage: 'Columns - { filterColumns }', values: { filterColumns: _.startCase(value?.style?.filterColumns || 'all') } }),
|
||||
submenu: [
|
||||
{
|
||||
text: 'All',
|
||||
text: _t('designer.all', { defaultMessage: 'All' }),
|
||||
onClick: changeStyleFunc('filterColumns', ''),
|
||||
},
|
||||
{
|
||||
text: 'Primary Key',
|
||||
text: _t('designer.primaryKey', { defaultMessage: 'Primary Key' }),
|
||||
onClick: changeStyleFunc('filterColumns', 'primaryKey'),
|
||||
},
|
||||
{
|
||||
text: 'All Keys',
|
||||
text: _t('designer.allKeys', { defaultMessage: 'All Keys' }),
|
||||
onClick: changeStyleFunc('filterColumns', 'allKeys'),
|
||||
},
|
||||
{
|
||||
text: 'Not Null',
|
||||
text: _t('designer.notNull', { defaultMessage: 'Not Null' }),
|
||||
onClick: changeStyleFunc('filterColumns', 'notNull'),
|
||||
},
|
||||
{
|
||||
text: 'Keys And Not Null',
|
||||
text: _t('designer.keysAndNotNull', { defaultMessage: 'Keys And Not Null' }),
|
||||
onClick: changeStyleFunc('filterColumns', 'keysAndNotNull'),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: `Zoom - ${(value?.style?.zoomKoef || 1) * 100}%`,
|
||||
text: _t('designer.zoom', { defaultMessage: 'Zoom - {zoom}%', values: { zoom: ((value?.style?.zoomKoef || 1) * 100) } }),
|
||||
submenu: DIAGRAM_ZOOMS.map(koef => ({
|
||||
text: `${koef * 100} %`,
|
||||
onClick: changeStyleFunc('zoomKoef', koef.toString()),
|
||||
@@ -1016,11 +1016,11 @@
|
||||
use:dragScroll={handleDragScroll}
|
||||
>
|
||||
{#if !(tables?.length > 0)}
|
||||
<div class="empty">Drag & drop tables or views from left panel here</div>
|
||||
<div class="empty">{_t('designer.dragDropTables', { defaultMessage: 'Drag & drop tables or views from left panel here' })}</div>
|
||||
|
||||
{#if allowAddTablesButton}
|
||||
<div class="addAllTables">
|
||||
<FormStyledButton value="Add all tables" on:click={handleAddAllTables} />
|
||||
<FormStyledButton value={_t('designer.addAllTables', { defaultMessage: 'Add all tables' })} on:click={handleAddAllTables} />
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
@@ -1119,7 +1119,7 @@
|
||||
<div class="panel">
|
||||
<DragColumnMemory {settings} {sourceDragColumn$} {targetDragColumn$} />
|
||||
<div class="searchbox">
|
||||
<SearchInput bind:value={columnFilter} placeholder="Filter columns" />
|
||||
<SearchInput bind:value={columnFilter} placeholder={_t('designer.filterColumns', { defaultMessage: 'Filter columns' })} />
|
||||
<CloseSearchButton bind:filter={columnFilter} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
import DropDownButton from '../buttons/DropDownButton.svelte';
|
||||
import { _tval } from '../translations';
|
||||
|
||||
interface TabDef {
|
||||
label: string;
|
||||
@@ -46,7 +47,7 @@
|
||||
data-testid={tab.testid}
|
||||
>
|
||||
<span class="ml-2 noselect">
|
||||
{tab.label}
|
||||
{_tval(tab.label)}
|
||||
</span>
|
||||
</div>
|
||||
{/each}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { getFormContext } from './FormProviderCore.svelte';
|
||||
|
||||
import FormSelectField from './FormSelectField.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let additionalFolders = [];
|
||||
export let name;
|
||||
@@ -35,7 +36,7 @@
|
||||
label: folder,
|
||||
})),
|
||||
allowCreateNew && {
|
||||
label: '(Create new)',
|
||||
label: _t('archiveFolder.createNew', { defaultMessage: '(Create new)' }),
|
||||
value: '@create',
|
||||
},
|
||||
];
|
||||
@@ -48,8 +49,8 @@
|
||||
function handleChange(e) {
|
||||
if (e.detail == '@create') {
|
||||
showModal(InputTextModal, {
|
||||
header: 'Archive',
|
||||
label: 'Name of new archive folder',
|
||||
header: _t('archiveFolder.archive', { defaultMessage: 'Archive' }),
|
||||
label: _t('archiveFolder.nameOfNewArchiveFolder', { defaultMessage: 'Name of new archive folder' }),
|
||||
onConfirm: createOption,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let value = '';
|
||||
export let conid;
|
||||
@@ -33,8 +34,8 @@
|
||||
|
||||
async function handleAddNewApplication() {
|
||||
showModal(InputTextModal, {
|
||||
header: 'New application',
|
||||
label: 'Application name',
|
||||
header: _t('database.newApplication', { defaultMessage: 'New application' }),
|
||||
label: _t('database.applicationName', { defaultMessage: 'Application name' }),
|
||||
value: _.startCase(database),
|
||||
onConfirm: async appName => {
|
||||
const newAppId = await apiCall('apps/create-app-from-db', {
|
||||
|
||||
@@ -310,21 +310,21 @@
|
||||
},
|
||||
});
|
||||
}}
|
||||
>{columnCount > 0 ? `(${columnCount} columns)` : '(copy from source)'}
|
||||
>{columnCount > 0 ? _t('importExport.columnsCount', { defaultMessage: '({columnCount} columns)', values: { columnCount } }) : _t('importExport.copyFromSource', { defaultMessage: '(copy from source)' })}
|
||||
</Link>
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="3" let:row>
|
||||
{#if progressHolder[row]?.status == 'running' && isRunning}
|
||||
<FontIcon icon="icon loading" />
|
||||
{#if progressHolder[row]?.writtenRowCount}
|
||||
{progressHolder[row]?.writtenRowCount} rows writtem
|
||||
{progressHolder[row]?.writtenRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
|
||||
{:else if progressHolder[row]?.readRowCount}
|
||||
{progressHolder[row]?.readRowCount} rows read
|
||||
{progressHolder[row]?.readRowCount} {_t('importExport.rowsRead', { defaultMessage: 'rows read' })}
|
||||
{:else}
|
||||
Running
|
||||
{_t('importExport.running', { defaultMessage: 'Running' })}
|
||||
{/if}
|
||||
{:else if progressHolder[row]?.status == 'error'}
|
||||
<FontIcon icon="img error" /> Error
|
||||
<FontIcon icon="img error" /> {_t('common.error', { defaultMessage: 'Error' })}
|
||||
{#if progressHolder[row]?.errorMessage}
|
||||
<FontIcon
|
||||
icon="img info"
|
||||
@@ -337,20 +337,20 @@
|
||||
{:else if progressHolder[row]?.status == 'done'}
|
||||
<FontIcon icon="img ok" />
|
||||
{#if progressHolder[row]?.writtenRowCount}
|
||||
{progressHolder[row]?.writtenRowCount} rows written
|
||||
{progressHolder[row]?.writtenRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
|
||||
{:else if progressHolder[row]?.readRowCount}
|
||||
{progressHolder[row]?.readRowCount} rows written
|
||||
{progressHolder[row]?.readRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
|
||||
{:else}
|
||||
Done
|
||||
{_t('common.done', { defaultMessage: 'Done' })}
|
||||
{/if}
|
||||
{:else}
|
||||
<FontIcon icon="icon wait" />
|
||||
{#if progressHolder[row]?.writtenRowCount}
|
||||
{progressHolder[row]?.writtenRowCount} rows writtem
|
||||
{progressHolder[row]?.writtenRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
|
||||
{:else if progressHolder[row]?.readRowCount}
|
||||
{progressHolder[row]?.readRowCount} rows read
|
||||
{progressHolder[row]?.readRowCount} {_t('importExport.rowsRead', { defaultMessage: 'rows read' })}
|
||||
{:else}
|
||||
Queued
|
||||
{_t('importExport.queued', { defaultMessage: 'Queued' })}
|
||||
{/if}
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -114,8 +114,8 @@
|
||||
value={_t('importExport.newArchive', { defaultMessage: "New archive" })}
|
||||
on:click={() => {
|
||||
showModal(InputTextModal, {
|
||||
header: 'Archive',
|
||||
label: 'Name of new archive folder',
|
||||
header: _t('importExport.archive', { defaultMessage: 'Archive' }),
|
||||
label: _t('importExport.nameOfNewArchiveFolder', { defaultMessage: 'Name of new archive folder' }),
|
||||
value: `import-${moment().format('YYYY-MM-DD-hh-mm-ss')}`,
|
||||
onConfirm: value => {
|
||||
values.update(x => ({
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import Link from '../elements/Link.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
const config = useConfig();
|
||||
$: version = $config?.version;
|
||||
@@ -15,18 +16,18 @@
|
||||
</script>
|
||||
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">About DbGate</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('aboutModal.aboutDbGate', { defaultMessage: 'About DbGate' })}</svelte:fragment>
|
||||
<div class="flex">
|
||||
<img src="logo192.png" />
|
||||
<div class="ml-4">
|
||||
<div>
|
||||
Version: <span>{version}</span>
|
||||
{_t('aboutModal.version', { defaultMessage: 'Version' })}: <span>{version}</span>
|
||||
</div>
|
||||
<div>
|
||||
Build date: <span>{moment(buildTime).format('YYYY-MM-DD')}</span>
|
||||
{_t('aboutModal.buildDate', { defaultMessage: 'Build date' })}: <span>{moment(buildTime).format('YYYY-MM-DD')}</span>
|
||||
</div>
|
||||
<div>
|
||||
License type: <span
|
||||
{_t('aboutModal.licenseType', { defaultMessage: 'License type' })}: <span
|
||||
>{$config?.checkedLicense && $config?.checkedLicense?.type != 'community'
|
||||
? ($config?.checkedLicense?.licenseTypeObj?.name ?? 'Unknown')
|
||||
: 'Community'}</span
|
||||
@@ -34,16 +35,16 @@
|
||||
</div>
|
||||
{#if $config?.checkedLicense?.users}
|
||||
<div>
|
||||
User count: <span>{$config?.checkedLicense?.users}</span>
|
||||
{_t('aboutModal.userCount', { defaultMessage: 'User count' })}: <span>{$config?.checkedLicense?.users}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="mt-2">
|
||||
<FontIcon icon="mdi mdi-web color-icon-blue" /> Web: <Link href="https://www.dbgate.io">dbgate.io</Link>
|
||||
<FontIcon icon="mdi mdi-web color-icon-blue" /> {_t('aboutModal.web', { defaultMessage: 'Web' })}: <Link href="https://www.dbgate.io">dbgate.io</Link>
|
||||
</div>
|
||||
{#if isProApp()}
|
||||
<div>
|
||||
<FontIcon icon="mdi mdi-email color-icon-red" /> Support: <Link href="mailto:support@dbgate.io"
|
||||
<FontIcon icon="mdi mdi-email color-icon-red" /> {_t('aboutModal.support', { defaultMessage: 'Support' })}: <Link href="mailto:support@dbgate.io"
|
||||
>support@dbgate.io</Link
|
||||
>
|
||||
</div>
|
||||
@@ -55,10 +56,10 @@
|
||||
</div> -->
|
||||
|
||||
<div class="mt-2">
|
||||
Source codes: <Link href="https://github.com/dbgate/dbgate/">GitHub</Link>
|
||||
{_t('aboutModal.sourceCodes', { defaultMessage: 'Source codes' })}: <Link href="https://github.com/dbgate/dbgate/">GitHub</Link>
|
||||
</div>
|
||||
<div>
|
||||
Docker container: <Link
|
||||
{_t('aboutModal.dockerContainer', { defaultMessage: 'Docker container' })}: <Link
|
||||
href={isProApp()
|
||||
? 'https://hub.docker.com/r/dbgate/dbgate-premium'
|
||||
: 'https://hub.docker.com/r/dbgate/dbgate'}>Docker Hub</Link
|
||||
@@ -69,13 +70,13 @@
|
||||
</div> -->
|
||||
|
||||
<div class="mt-2">
|
||||
Produced by: <span>Sprinx System a.s.</span>
|
||||
{_t('aboutModal.producedBy', { defaultMessage: 'Produced by' })}: <span>Sprinx System a.s.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormStyledButton value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import TextField from '../forms/TextField.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
@@ -26,10 +27,10 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Add key</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('addDbKeyModal.addKey', { defaultMessage: 'Add key' })}</svelte:fragment>
|
||||
|
||||
<div class="container">
|
||||
<FormFieldTemplateLarge label="Key" type="text" noMargin>
|
||||
<FormFieldTemplateLarge label={_t('addDbKeyModal.key', { defaultMessage: 'Key' })} type="text" noMargin>
|
||||
<TextField
|
||||
value={keyName}
|
||||
on:change={e => {
|
||||
@@ -41,7 +42,7 @@
|
||||
|
||||
<div class="m-3" />
|
||||
|
||||
<FormFieldTemplateLarge label="Type" type="combo" noMargin>
|
||||
<FormFieldTemplateLarge label={_t('addDbKeyModal.type', { defaultMessage: 'Type' })} type="combo" noMargin>
|
||||
<SelectField
|
||||
options={driver.supportedKeyTypes.map(t => ({ value: t.name, label: t.label }))}
|
||||
value={type}
|
||||
@@ -62,8 +63,8 @@
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormStyledButton value="OK" on:click={e => handleSubmit()} />
|
||||
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
|
||||
<FormStyledButton value={_t('common.ok', { defaultMessage: 'OK' })} on:click={e => handleSubmit()} />
|
||||
<FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let onConfirm;
|
||||
export let url;
|
||||
@@ -18,13 +19,13 @@
|
||||
|
||||
<FormProvider initialValues={{ url }}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Download imported file from web</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('changeDownloadUrlModal.header', { defaultMessage: 'Download imported file from web' })}</svelte:fragment>
|
||||
|
||||
<FormTextField label="URL" name="url" style={{ width: '30vw' }} focused />
|
||||
<FormTextField label={_t('changeDownloadUrlModal.urlLabel', { defaultMessage: 'URL' })} name="url" style={{ width: '30vw' }} focused />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit value="OK" on:click={handleSubmit} />
|
||||
<FormStyledButton value="Cancel" on:click={closeCurrentModal} />
|
||||
<FormSubmit value={_t('common.ok', { defaultMessage: 'OK' })} on:click={handleSubmit} />
|
||||
<FormStyledButton value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let message = '';
|
||||
export let onConfirm;
|
||||
@@ -13,21 +14,21 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Choose archive folder</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('archiveFolderModal.chooseArchiveFolder', { defaultMessage: 'Choose archive folder' })}</svelte:fragment>
|
||||
|
||||
<div>{message}</div>
|
||||
|
||||
<FormArchiveFolderSelect label="Archive folder" name="archiveFolder" isNative allowCreateNew />
|
||||
<FormArchiveFolderSelect label={_t('archiveFolderModal.archiveFolder', { defaultMessage: 'Archive folder' })} name="archiveFolder" isNative allowCreateNew />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={e => {
|
||||
closeCurrentModal();
|
||||
onConfirm(e.detail.archiveFolder);
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import { useCloudContentList } from '../utility/metadataLoaders';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let message = '';
|
||||
export let onConfirm;
|
||||
@@ -18,22 +19,21 @@
|
||||
{#if $cloudContentList}
|
||||
<FormProvider initialValues={{ cloudFolder: $cloudContentList?.find(x => x.isPrivate)?.folid }}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Choose cloud folder</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('cloudFolderModal.chooseCloudFolder', { defaultMessage: 'Choose cloud folder' })}</svelte:fragment>
|
||||
|
||||
<div>{message}</div>
|
||||
|
||||
<FormCloudFolderSelect label="Cloud folder" name="cloudFolder" isNative {requiredRoleVariants} />
|
||||
|
||||
<FormCloudFolderSelect label={_t('cloudFolderModal.cloudFolder', { defaultMessage: 'Cloud folder' })} name="cloudFolder" isNative {requiredRoleVariants} />
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={e => {
|
||||
closeCurrentModal();
|
||||
console.log('onConfirm', e.detail);
|
||||
onConfirm(e.detail.cloudFolder);
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -11,8 +11,9 @@
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import _ from 'lodash';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let header = 'Configure columns';
|
||||
export let header = _t('columnMapModal.configureColumns', { defaultMessage: 'Configure columns' });
|
||||
export let onConfirm;
|
||||
|
||||
export let sourceTableInfo;
|
||||
@@ -69,7 +70,7 @@
|
||||
if (!value) return;
|
||||
if (value.length == 0) return;
|
||||
if (value.some(x => !x.src || !x.dst)) {
|
||||
validationError = 'Source and target columns must be defined';
|
||||
validationError = _t('columnMapModal.sourceAndTargetColumnsMustBeDefined', { defaultMessage: 'Source and target columns must be defined' });
|
||||
return;
|
||||
}
|
||||
const duplicates = _.chain(value.map(x => x.dst))
|
||||
@@ -78,7 +79,7 @@
|
||||
.keys()
|
||||
.value();
|
||||
if (duplicates.length > 0) {
|
||||
validationError = 'Target columns must be unique, duplicates found: ' + duplicates.join(', ');
|
||||
validationError = _t('columnMapModal.targetColumnsMustBeUnique', { defaultMessage: 'Target columns must be unique, duplicates found: ' }) + duplicates.join(', ');
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -95,19 +96,19 @@
|
||||
|
||||
{#if resetValue.length == 0}
|
||||
<div class="m-3">
|
||||
When no columns are defined in this mapping, source row is copied to target without any modifications
|
||||
{_t('columnMapModal.noColumnsDefined', { defaultMessage: 'When no columns are defined in this mapping, source row is copied to target without any modifications' })}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<TableControl
|
||||
columns={[
|
||||
{ fieldName: 'use', header: 'Use', slot: 4 },
|
||||
{ fieldName: 'src', header: 'Source column', slot: 1 },
|
||||
{ fieldName: 'dst', header: 'Target column', slot: 2 },
|
||||
{ fieldName: 'use', header: _t('columnMapModal.use', { defaultMessage: 'Use' }), slot: 4 },
|
||||
{ fieldName: 'src', header: _t('columnMapModal.sourceColumn', { defaultMessage: 'Source column' }), slot: 1 },
|
||||
{ fieldName: 'dst', header: _t('columnMapModal.targetColumn', { defaultMessage: 'Target column' }), slot: 2 },
|
||||
{ fieldName: 'actions', header: '', slot: 3 },
|
||||
]}
|
||||
rows={value || []}
|
||||
emptyMessage="No transform defined"
|
||||
emptyMessage={_t('columnMapModal.noTransformDefined', { defaultMessage: 'No transform defined' })}
|
||||
>
|
||||
<svelte:fragment slot="4" let:row let:index>
|
||||
<CheckboxField
|
||||
@@ -136,7 +137,7 @@
|
||||
<Link
|
||||
onClick={() => {
|
||||
value = value.filter((x, i) => i != index);
|
||||
}}>Remove</Link
|
||||
}}>{_t('common.Remove', { defaultMessage: 'Remove' })}</Link
|
||||
>
|
||||
</svelte:fragment>
|
||||
</TableControl>
|
||||
@@ -160,14 +161,14 @@
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Add column"
|
||||
value={_t('columnMapModal.addColumn', { defaultMessage: 'Add column' })}
|
||||
on:click={() => {
|
||||
value = [...(value || []), {}];
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Reset"
|
||||
value={_t('columnMapModal.reset', { defaultMessage: 'Reset' })}
|
||||
disabled={!differentFromReset}
|
||||
on:click={() => {
|
||||
value = resetValue;
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let message;
|
||||
export let onConfirm;
|
||||
export let confirmLabel = 'OK';
|
||||
export let confirmLabel = _t('common.ok', { defaultMessage: 'OK' });
|
||||
export let header = null;
|
||||
</script>
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">
|
||||
{header || 'Confirm'}
|
||||
{header || _t('common.confirm', { defaultMessage: 'Confirm' })}
|
||||
</svelte:fragment>
|
||||
|
||||
{message}
|
||||
@@ -31,7 +32,7 @@
|
||||
/>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Close"
|
||||
value={_t('common.close', { defaultMessage: 'Close' })}
|
||||
on:click={closeCurrentModal}
|
||||
data-testid="ConfirmModal_closeButton"
|
||||
/>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let script;
|
||||
export let onConfirm;
|
||||
@@ -19,7 +20,7 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">Save changes</div>
|
||||
<div slot="header">{_t('common.saveChanges', { defaultMessage: 'Save changes' })}</div>
|
||||
|
||||
<div class="editor">
|
||||
<AceEditor mode="javascript" readOnly value={script} />
|
||||
@@ -28,7 +29,7 @@
|
||||
{#if skipConfirmSettingKey}
|
||||
<div class="mt-2">
|
||||
<TemplatedCheckboxField
|
||||
label="Don't ask again"
|
||||
label={_t('common.dontAskAgain', { defaultMessage: "Don't ask again" })}
|
||||
templateProps={{ noMargin: true }}
|
||||
checked={dontAskAgain}
|
||||
on:change={e => {
|
||||
@@ -41,16 +42,16 @@
|
||||
|
||||
<div slot="footer">
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={() => {
|
||||
closeCurrentModal();
|
||||
onConfirm();
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Open script"
|
||||
value={_t('common.openScript', { defaultMessage: 'Open script' })}
|
||||
on:click={() => {
|
||||
newQuery({
|
||||
initialData: script,
|
||||
|
||||
@@ -54,6 +54,7 @@
|
||||
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal, showModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let sql;
|
||||
export let onConfirm;
|
||||
@@ -81,7 +82,7 @@
|
||||
|
||||
<FormProviderCore {values}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">Save changes</div>
|
||||
<div slot="header">{_t('common.saveChanges', { defaultMessage: 'Save changes' })}</div>
|
||||
|
||||
<div class="editor">
|
||||
<SqlEditor {engine} value={currentScript} readOnly />
|
||||
@@ -91,7 +92,7 @@
|
||||
<div class="mt-2">
|
||||
<FormCheckboxField
|
||||
templateProps={{ noMargin: true }}
|
||||
label="Delete references CASCADE"
|
||||
label={_t('sqlModal.deleteReferencesCascade', { defaultMessage: 'Delete references CASCADE' })}
|
||||
name="deleteReferencesCascade"
|
||||
data-testid="ConfirmSqlModal_deleteReferencesCascade"
|
||||
/>
|
||||
@@ -101,13 +102,13 @@
|
||||
{#if $values.deleteReferencesCascade}
|
||||
<div class="form-margin flex">
|
||||
<FormStyledButton
|
||||
value="Check all"
|
||||
value={_t('common.checkAll', { defaultMessage: 'Check all' })}
|
||||
on:click={() => {
|
||||
$values = _.omitBy($values, (v, k) => k.startsWith('deleteReferencesFor_'));
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton
|
||||
value="Uncheck all"
|
||||
value={_t('common.uncheckAll', { defaultMessage: 'Uncheck all' })}
|
||||
on:click={() => {
|
||||
const newValues = { ...$values };
|
||||
for (const item of deleteCascadesScripts) {
|
||||
@@ -135,12 +136,11 @@
|
||||
{#if isRecreated}
|
||||
<div class="form-margin">
|
||||
<div>
|
||||
<FontIcon icon="img warn" /> This operation is not directly supported by SQL engine. DbGate can emulate it, but
|
||||
please check the generated SQL script.
|
||||
<FontIcon icon="img warn" /> {_t('sqlModal.recreateWarning', { defaultMessage: "This operation is not directly supported by SQL engine. DbGate can emulate it, but please check the generated SQL script." })}
|
||||
</div>
|
||||
<FormCheckboxField
|
||||
templateProps={{ noMargin: true }}
|
||||
label="Allow recreate (don't use on production databases)"
|
||||
label={_t('sqlModal.allowRecreate', { defaultMessage: "Allow recreate (don't use on production databases)" })}
|
||||
name="allowRecreate"
|
||||
/>
|
||||
</div>
|
||||
@@ -149,7 +149,7 @@
|
||||
{#if skipConfirmSettingKey}
|
||||
<div class="mt-2">
|
||||
<TemplatedCheckboxField
|
||||
label="Don't ask again"
|
||||
label={_t('common.dontAskAgain', { defaultMessage: "Don't ask again" })}
|
||||
templateProps={{ noMargin: true }}
|
||||
checked={dontAskAgain}
|
||||
on:change={e => {
|
||||
@@ -162,7 +162,7 @@
|
||||
|
||||
<div slot="footer">
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
disabled={isRecreated && !$values.allowRecreate}
|
||||
on:click={e => {
|
||||
closeCurrentModal();
|
||||
@@ -172,13 +172,13 @@
|
||||
/>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Close"
|
||||
value={_t('common.close', { defaultMessage: 'Close' })}
|
||||
on:click={closeCurrentModal}
|
||||
data-testid="ConfirmSqlModal_closeButton"
|
||||
/>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Open script"
|
||||
value={_t('common.openScript', { defaultMessage: 'Open script' })}
|
||||
on:click={() => {
|
||||
newQuery({
|
||||
initialData: currentScript,
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
import { callServerPing } from '../utility/connectionsPinger';
|
||||
import { getConnectionLabel } from 'dbgate-tools';
|
||||
import { openedConnections } from '../stores';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let passwordMode;
|
||||
@@ -125,11 +126,11 @@
|
||||
|
||||
<FormProviderCore {values}>
|
||||
<ModalBase {...$$restProps} simple>
|
||||
<svelte:fragment slot="header">Database Log In ({engineTitle})</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('databaseLoginModal.header', { defaultMessage: 'Database Log In ({engineTitle})', values: {engineTitle} })}</svelte:fragment>
|
||||
|
||||
<FormTextField label="Connection" name="connectionLabel" disabled />
|
||||
<FormTextField label={_t('databaseLoginModal.connection', { defaultMessage: 'Connection' })} name="connectionLabel" disabled />
|
||||
<FormTextField
|
||||
label="Username"
|
||||
label={_t('databaseLoginModal.username', { defaultMessage: 'Username' })}
|
||||
name="user"
|
||||
autocomplete="username"
|
||||
disabled={usedPasswordMode == 'askPassword'}
|
||||
@@ -138,7 +139,7 @@
|
||||
data-testid="DatabaseLoginModal_username"
|
||||
/>
|
||||
<FormPasswordField
|
||||
label="Password"
|
||||
label={_t('databaseLoginModal.password', { defaultMessage: 'Password' })}
|
||||
name="password"
|
||||
autocomplete="current-password"
|
||||
focused={usedPasswordMode == 'askPassword'}
|
||||
@@ -148,34 +149,34 @@
|
||||
|
||||
{#if isTesting}
|
||||
<div>
|
||||
<FontIcon icon="icon loading" /> Testing connection
|
||||
<FontIcon icon="icon loading" /> {_t('databaseLoginModal.testingConnection', { defaultMessage: 'Testing connection' })}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
{#if !isTesting && sqlConnectResult && sqlConnectResult.msgtype == 'error'}
|
||||
<div class="error-result">
|
||||
Connect failed: <FontIcon icon="img error" />
|
||||
{_t('databaseLoginModal.connectFailed', { defaultMessage: 'Connect failed:' })} <FontIcon icon="img error" />
|
||||
{sqlConnectResult.error}
|
||||
<Link
|
||||
onClick={() =>
|
||||
showModal(ErrorMessageModal, {
|
||||
message: sqlConnectResult.detail,
|
||||
showAsCode: true,
|
||||
title: 'Database connection error',
|
||||
title: _t('databaseLoginModal.connectionError', { defaultMessage: 'Database connection error' }),
|
||||
})}
|
||||
>
|
||||
Show detail
|
||||
{_t('databaseLoginModal.showDetail', { defaultMessage: 'Show detail' })}
|
||||
</Link>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
{#if isTesting}
|
||||
<FormStyledButton value="Stop connecting" on:click={handleCancelTest} data-testid="DatabaseLoginModal_stop" />
|
||||
<FormStyledButton value={_t('databaseLoginModal.stopConnecting', { defaultMessage: 'Stop connecting' })} on:click={handleCancelTest} data-testid="DatabaseLoginModal_stop" />
|
||||
{:else}
|
||||
<FormSubmit value="Connect" on:click={handleSubmit} data-testid="DatabaseLoginModal_connect" />
|
||||
<FormSubmit value={_t('databaseLoginModal.connect', { defaultMessage: 'Connect' })} on:click={handleSubmit} data-testid="DatabaseLoginModal_connect" />
|
||||
{/if}
|
||||
<FormStyledButton value="Close" on:click={closeCurrentModal} data-testid="DatabaseLoginModal_close" />
|
||||
<FormStyledButton value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} data-testid="DatabaseLoginModal_close" />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProviderCore>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import FormProvider from '../forms/FormProvider.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let keyInfo;
|
||||
export let label;
|
||||
@@ -21,7 +22,7 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Add item</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('dbKeyAddItemModal.header', { defaultMessage: 'Add item' })}</svelte:fragment>
|
||||
|
||||
<div class="container">
|
||||
<DbKeyItemDetail
|
||||
@@ -34,8 +35,8 @@
|
||||
</div>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormStyledButton value="OK" on:click={e => handleSubmit()} />
|
||||
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
|
||||
<FormStyledButton value={_t('common.ok', { defaultMessage: 'OK' })} on:click={e => handleSubmit()} />
|
||||
<FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
import { currentDatabase } from '../stores';
|
||||
import { filterAppsForDatabase } from '../utility/appTools';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
@@ -52,10 +53,10 @@
|
||||
|
||||
<FormProviderCore {values}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Define description</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('defineDictionaryDescriptionModal.header', { defaultMessage: 'Define description' })}</svelte:fragment>
|
||||
|
||||
<FormSelectField
|
||||
label="Target application (mandatory)"
|
||||
label={_t('defineDictionaryDescriptionModal.targetApplication', { defaultMessage: 'Target application (mandatory)' })}
|
||||
name="targetApplication"
|
||||
disableInitialize
|
||||
selectFieldComponent={TargetApplicationSelect}
|
||||
@@ -68,8 +69,8 @@
|
||||
rows={$tableInfo?.columns || []}
|
||||
columns={[
|
||||
{ fieldName: 'checked', header: '', slot: 1 },
|
||||
{ fieldName: 'columnName', header: 'Column' },
|
||||
{ fieldName: 'dataType', header: 'Data type' },
|
||||
{ fieldName: 'columnName', header: _t('defineDictionaryDescriptionModal.column', { defaultMessage: 'Column' }) },
|
||||
{ fieldName: 'dataType', header: _t('defineDictionaryDescriptionModal.dataType', { defaultMessage: 'Data type' }) },
|
||||
]}
|
||||
>
|
||||
<input
|
||||
@@ -88,15 +89,15 @@
|
||||
</TableControl>
|
||||
</div>
|
||||
|
||||
<FormTextField name="columns" label="Show columns" />
|
||||
<FormTextField name="columns" label={_t('defineDictionaryDescriptionModal.showColumns', { defaultMessage: 'Show columns' })} />
|
||||
|
||||
<FormTextField name="delimiter" label="Delimiter" />
|
||||
<FormTextField name="delimiter" label={_t('defineDictionaryDescriptionModal.delimiter', { defaultMessage: 'Delimiter' })} />
|
||||
|
||||
<!-- <FormCheckboxField name="useForAllDatabases" label="Use for all databases" /> -->
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
disabled={!checkDescriptionExpression($values?.columns, $tableInfo) || !$values.targetApplication}
|
||||
on:click={async () => {
|
||||
closeCurrentModal();
|
||||
@@ -122,7 +123,7 @@
|
||||
onConfirm?.();
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProviderCore>
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import _ from 'lodash';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let onConfirm;
|
||||
export let conid;
|
||||
@@ -126,15 +127,15 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Lookup from {pureName}</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('dictionaryLookupModal.header', { defaultMessage: 'Lookup from {pureName}', values: {pureName} })}</svelte:fragment>
|
||||
|
||||
<!-- <FormTextField name="search" label='Search' placeholder="Search" bind:value={search} /> -->
|
||||
<div class="largeFormMarker">
|
||||
<SearchInput placeholder="Search" bind:value={search} isDebounced />
|
||||
<SearchInput placeholder={_t("common.search", { defaultMessage: "Search" })} bind:value={search} isDebounced />
|
||||
</div>
|
||||
|
||||
{#if isLoading}
|
||||
<LoadingInfo message="Loading data" />
|
||||
<LoadingInfo message={_t('dictionaryLookupModal.loadingData', { defaultMessage: "Loading data" })} />
|
||||
{/if}
|
||||
|
||||
{#if !isLoading && tableInfo && description && rows && tableInfo?.primaryKey?.columns?.length == 1}
|
||||
@@ -161,13 +162,13 @@
|
||||
},
|
||||
{
|
||||
fieldName: 'value',
|
||||
header: 'Value',
|
||||
header: _t('dictionaryLookupModal.value', { defaultMessage: 'Value' }),
|
||||
formatter: row => row[tableInfo.primaryKey.columns[0].columnName],
|
||||
width: '100px',
|
||||
},
|
||||
{
|
||||
fieldName: 'description',
|
||||
header: 'Description',
|
||||
header: _t('dictionaryLookupModal.description', { defaultMessage: 'Description' }),
|
||||
formatter: row => description.columns.map(col => row[col]).join(description.delimiter || ' '),
|
||||
},
|
||||
]}
|
||||
@@ -194,15 +195,15 @@
|
||||
<svelte:fragment slot="footer">
|
||||
{#if multiselect}
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={() => {
|
||||
closeCurrentModal();
|
||||
onConfirm(checkedKeys);
|
||||
}}
|
||||
/>
|
||||
{/if}
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value="Customize" on:click={defineDescription} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('dictionaryLookupModal.customize', { defaultMessage: 'Customize' })} on:click={defineDescription} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<div slot="footer" class="footer">
|
||||
<div>
|
||||
<FormStyledButton
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
title="Ctrl+Enter"
|
||||
on:click={() => {
|
||||
onSave(parseCellValue(textValue, dataEditorTypesBehaviour));
|
||||
|
||||
@@ -30,11 +30,10 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">Edit JSON value</div>
|
||||
<div slot="header">{_t('editJsonModal.header', { defaultMessage: 'Edit JSON value' })}</div>
|
||||
{#if showPasteInfo}
|
||||
<div class="m-2">
|
||||
Edit JSON object or array. You can paste JSON array or object directly into data grid, new row(s) will be added
|
||||
to recordset.
|
||||
{_t('editJsonModal.pasteInfo', { defaultMessage: "Edit JSON object or array. You can paste JSON array or object directly into data grid, new row(s) will be added to recordset." })}
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
|
||||
@@ -168,11 +168,11 @@
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps} fullScreen>
|
||||
<div slot="header">
|
||||
{mode == 'export' ? 'Export' : 'Import'} connections & settings
|
||||
{mode == 'export' ? 'Export' : 'Import'} {_t('importExport.connectionsSettings', { defaultMessage: 'connections & settings' })}
|
||||
<span class="check-uncheck">
|
||||
<Link onClick={() => handleCheckAll(true)}>Check all</Link>
|
||||
<Link onClick={() => handleCheckAll(true)}>{_t('common.checkAll', { defaultMessage: 'Check all' })}</Link>
|
||||
|
|
||||
<Link onClick={() => handleCheckAll(false)}>Uncheck all</Link>
|
||||
<Link onClick={() => handleCheckAll(false)}>{_t('common.uncheckAll', { defaultMessage: 'Uncheck all' })}</Link>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -180,16 +180,16 @@
|
||||
<TabControl
|
||||
tabs={_.compact([
|
||||
connections?.length && {
|
||||
label: `Connections (${checkedConnections?.length}/${connections?.length})`,
|
||||
label: _t('importExport.connectionsNum', { defaultMessage:'Connections ({checkedConnections}/{connections})', values: { checkedConnections: checkedConnections?.length, connections: connections?.length } }),
|
||||
slot: 1,
|
||||
},
|
||||
users?.length && { label: `Users (${checkedUsers?.length}/${users?.length})`, slot: 2 },
|
||||
roles?.length && { label: `Roles (${checkedRoles?.length}/${roles?.length})`, slot: 3 },
|
||||
users?.length && { label: _t('importExport.usersNum', { defaultMessage:'Users ({checkedUsers}/{users})', values: { checkedUsers: checkedUsers?.length, users: users?.length } }), slot: 2 },
|
||||
roles?.length && { label: _t('importExport.rolesNum', { defaultMessage:'Roles ({checkedRoles}/{roles})', values: { checkedRoles: checkedRoles?.length, roles: roles?.length } }), slot: 3 },
|
||||
authMethods?.length && {
|
||||
label: `Auth methods (${checkedAuthMethods?.length}/${authMethods?.length})`,
|
||||
label: _t('importExport.authMethodsNum', { defaultMessage:'Auth methods ({checkedAuthMethods}/{authMethods})', values: { checkedAuthMethods: checkedAuthMethods?.length, authMethods: authMethods?.length } }),
|
||||
slot: 4,
|
||||
},
|
||||
config?.length && { label: `Config (${checkedConfig?.length}/${config?.length})`, slot: 5 },
|
||||
config?.length && { label: _t('importExport.configNum', { defaultMessage:'Config ({checkedConfig}/{config})', values: { checkedConfig: checkedConfig?.length, config: config?.length } }), slot: 5 },
|
||||
])}
|
||||
>
|
||||
<svelte:fragment slot="1">
|
||||
@@ -199,10 +199,10 @@
|
||||
stickyHeader
|
||||
columns={[
|
||||
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true },
|
||||
{ header: 'Display name', fieldName: 'displayName', sortable: true, filterable: true },
|
||||
{ header: 'Engine', fieldName: 'engine', sortable: true, filterable: true },
|
||||
{ header: 'Server', fieldName: 'server', sortable: true, filterable: true },
|
||||
{ header: 'User', fieldName: 'user', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.displayName', { defaultMessage: 'Display name' }), fieldName: 'displayName', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.engine', { defaultMessage: 'Engine' }), fieldName: 'engine', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.server', { defaultMessage: 'Server' }), fieldName: 'server', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.user', { defaultMessage: 'User' }), fieldName: 'user', sortable: true, filterable: true },
|
||||
]}
|
||||
clickable
|
||||
rows={connections}
|
||||
@@ -225,8 +225,8 @@
|
||||
stickyHeader
|
||||
columns={[
|
||||
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true },
|
||||
{ header: 'Login', fieldName: 'login', sortable: true, filterable: true },
|
||||
{ header: 'E-mail', fieldName: 'email', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.login', { defaultMessage: 'Login' }), fieldName: 'login', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.email', { defaultMessage: 'E-mail' }), fieldName: 'email', sortable: true, filterable: true },
|
||||
]}
|
||||
clickable
|
||||
rows={users}
|
||||
@@ -249,7 +249,7 @@
|
||||
stickyHeader
|
||||
columns={[
|
||||
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true },
|
||||
{ header: 'Name', fieldName: 'name', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.name', { defaultMessage: 'Name' }), fieldName: 'name', sortable: true, filterable: true },
|
||||
]}
|
||||
clickable
|
||||
rows={roles}
|
||||
@@ -272,8 +272,8 @@
|
||||
stickyHeader
|
||||
columns={[
|
||||
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true },
|
||||
{ header: 'Name', fieldName: 'name', sortable: true, filterable: true },
|
||||
{ header: 'Type', fieldName: 'type', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.name', { defaultMessage: 'Name' }), fieldName: 'name', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.type', { defaultMessage: 'Type' }), fieldName: 'type', sortable: true, filterable: true },
|
||||
]}
|
||||
clickable
|
||||
rows={authMethods}
|
||||
@@ -296,9 +296,9 @@
|
||||
stickyHeader
|
||||
columns={[
|
||||
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true },
|
||||
{ header: 'Group', fieldName: 'group', sortable: true, filterable: true },
|
||||
{ header: 'Key', fieldName: 'key', sortable: true, filterable: true },
|
||||
{ header: 'Value', fieldName: 'value', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.group', { defaultMessage: 'Group' }), fieldName: 'group', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.key', { defaultMessage: 'Key' }), fieldName: 'key', sortable: true, filterable: true },
|
||||
{ header: _t('importExport.value', { defaultMessage: 'Value' }), fieldName: 'value', sortable: true, filterable: true },
|
||||
]}
|
||||
clickable
|
||||
rows={config}
|
||||
@@ -340,7 +340,7 @@
|
||||
>
|
||||
{/if}
|
||||
<LargeButton icon="icon close" on:click={closeCurrentModal} data-testid="EditJsonModal_closeButton"
|
||||
>Close</LargeButton
|
||||
>{_t('common.close', { defaultMessage: 'Close' })}</LargeButton
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||
import FormButton from '../forms/FormButton.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let editingData;
|
||||
export let savingTab;
|
||||
@@ -113,28 +114,28 @@
|
||||
|
||||
<FormProvider {initialValues}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">{editingData ? 'Edit favorite' : 'Share / add to favorites'}</svelte:fragment>
|
||||
<svelte:fragment slot="header">{editingData ? _t('favorite.editFavorite', { defaultMessage: 'Edit favorite' }) : _t('favorite.shareAddToFavorites', { defaultMessage: 'Share / add to favorites' })}</svelte:fragment>
|
||||
|
||||
<FormTextField label="Title" name="title" focused />
|
||||
<FormTextField label="Icon" name="icon" />
|
||||
<FormTextField label={_t('favorite.title', { defaultMessage: 'Title' })} name="title" focused />
|
||||
<FormTextField label={_t('favorite.icon', { defaultMessage: 'Icon' })} name="icon" />
|
||||
|
||||
<FormTextField label="URL path" name="urlPath" />
|
||||
<FormTextField label={_t('favorite.urlPath', { defaultMessage: 'URL path' })} name="urlPath" />
|
||||
{#if !!savingTab && !electron && canWriteFavorite}
|
||||
<FormCheckboxField label="Share as link" name="shareAsLink" />
|
||||
<FormCheckboxField label={_t('favorite.shareAsLink', { defaultMessage: 'Share as link' })} name="shareAsLink" />
|
||||
{/if}
|
||||
<FormValues let:values>
|
||||
{#if !values.shareAsLink && canWriteFavorite}
|
||||
<FormCheckboxField label="Show in toolbar" name="showInToolbar" />
|
||||
<FormCheckboxField label="Open on startup" name="openOnStartup" />
|
||||
<FormCheckboxField label={_t('favorite.showInToolbar', { defaultMessage: 'Show in toolbar' })} name="showInToolbar" />
|
||||
<FormCheckboxField label={_t('favorite.openOnStartup', { defaultMessage: 'Open on startup' })} name="openOnStartup" />
|
||||
{/if}
|
||||
</FormValues>
|
||||
{#if !!savingTab && !!savedFile}
|
||||
<FormSelectField
|
||||
label="What to save"
|
||||
label={_t('favorite.whatToSave', { defaultMessage: 'What to save' })}
|
||||
name="whatToSave"
|
||||
options={[
|
||||
{ label: 'Link to file', value: 'fileName' },
|
||||
{ label: 'Content', value: 'content' },
|
||||
{ label: _t('favorite.linkToFile', { defaultMessage: 'Link to file' }), value: 'fileName' },
|
||||
{ label: _t('favorite.content', { defaultMessage: 'Content' }), value: 'content' },
|
||||
]}
|
||||
/>
|
||||
{/if}
|
||||
@@ -142,12 +143,12 @@
|
||||
<svelte:fragment slot="footer">
|
||||
<FormValues let:values>
|
||||
{#if !values.shareAsLink && canWriteFavorite}
|
||||
<FormSubmit value="OK" on:click={handleSubmit} />
|
||||
<FormSubmit value={_t('common.ok', { defaultMessage: 'OK' })} on:click={handleSubmit} />
|
||||
{/if}
|
||||
{#if values.shareAsLink || !canWriteFavorite}
|
||||
<FormButton value="Copy link" on:click={handleCopyLink} />
|
||||
<FormButton value={_t('common.copyLink', { defaultMessage: 'Copy link' })} on:click={handleCopyLink} />
|
||||
{/if}
|
||||
<FormButton value="Cancel" on:click={closeCurrentModal} />
|
||||
<FormButton value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</FormValues>
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import FormStyledButton from '../buttons/FormStyledButton.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let onFilter;
|
||||
|
||||
@@ -16,35 +17,35 @@
|
||||
</script>
|
||||
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">Filter multiple values</div>
|
||||
<div slot="header">{_t('filterMultipleValues.filterMultipleValues', { defaultMessage: 'Filter multiple values' })}</div>
|
||||
|
||||
<div class="flex">
|
||||
<TextAreaField rows={10} bind:value focused />
|
||||
<div>
|
||||
<div>
|
||||
<input type="radio" bind:group value="is" id="__is" />
|
||||
<label for="__is">Is one of line</label>'
|
||||
<label for="__is">{_t('filterMultipleValues.isOneOfLine', { defaultMessage: 'Is one of line' })}</label>'
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" bind:group value="is_not" id="__is_not" />
|
||||
<label for="__is_not">Is not one of line</label>'
|
||||
<label for="__is_not">{_t('filterMultipleValues.isNotOneOfLine', { defaultMessage: 'Is not one of line' })}</label>'
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" bind:group value="contains" id="__contains" />
|
||||
<label for="__contains">Contains</label>'
|
||||
<label for="__contains">{_t('filterMultipleValues.contains', { defaultMessage: 'Contains' })}</label>'
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" bind:group value="begins" id="__begins" />
|
||||
<label for="__begins">Begins</label>'
|
||||
<label for="__begins">{_t('filterMultipleValues.begins', { defaultMessage: 'Begins' })}</label>'
|
||||
</div>
|
||||
<div>
|
||||
<input type="radio" bind:group value="ends" id="__ends" />
|
||||
<label for="__ends">Ends</label>'
|
||||
<label for="__ends">{_t('filterMultipleValues.ends', { defaultMessage: 'Ends' })}</label>'
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div slot="footer">
|
||||
<FormStyledButton value="OK" on:click={handleOk} />
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton value={_t('common.ok', { defaultMessage: 'OK' })} on:click={handleOk} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</div>
|
||||
</ModalBase>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
import newQuery from '../query/newQuery';
|
||||
import SqlEditor from '../query/SqlEditor.svelte';
|
||||
import keycodes from '../utility/keycodes';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
@@ -77,24 +78,23 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Generate SQL from data</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('generateSqlFromData.generateSqlFromData', { defaultMessage: 'Generate SQL from data' })}</svelte:fragment>
|
||||
|
||||
<div class="flex mb-3">
|
||||
<div class="m-1 col-4">
|
||||
<div class="m-1">Choose query type</div>
|
||||
|
||||
<div class="m-1">{_t('generateSqlFromData.chooseQueryType', { defaultMessage: 'Choose query type' })}</div>
|
||||
<TableControl
|
||||
rows={QUERY_TYPES.map(name => ({ name }))}
|
||||
bind:selectedIndex={queryTypeIndex}
|
||||
bind:domTable={domQueryType}
|
||||
focusOnCreate
|
||||
selectable
|
||||
columns={[{ fieldName: 'name', header: 'Query type' }]}
|
||||
columns={[{ fieldName: 'name', header: _t('generateSqlFromData.queryType', { defaultMessage: 'Query type' }) }]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="m-1 col-4">
|
||||
<div class="m-1">Value columns</div>
|
||||
<div class="m-1">{_t('generateSqlFromData.valueColumns', { defaultMessage: 'Value columns' })}</div>
|
||||
|
||||
<CheckableColumnList
|
||||
{allColumns}
|
||||
@@ -120,13 +120,13 @@
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={() => {
|
||||
newQuery({ initialData: sqlPreview });
|
||||
closeCurrentModal();
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<FormTextField {label} name="value" focused data-testid="InputTextModal_value" />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit value="OK" on:click={e => handleSubmit(e.detail)} data-testid="InputTextModal_ok" />
|
||||
<FormSubmit value={_t('common.ok', { defaultMessage: 'OK' })} on:click={e => handleSubmit(e.detail)} data-testid="InputTextModal_ok" />
|
||||
<FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} data-testid="InputTextModal_cancel" />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
import _ from 'lodash';
|
||||
|
||||
export let sql;
|
||||
export let onInsert;
|
||||
@@ -104,12 +106,11 @@
|
||||
</script>
|
||||
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Insert join</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('insertJoin.insertJoin', { defaultMessage: 'Insert join' })}</svelte:fragment>
|
||||
|
||||
<div class="flex mb-3">
|
||||
<div class="m-1 col-3">
|
||||
<div class="m-1">Existing table</div>
|
||||
|
||||
<div class="m-1">{_t('insertJoin.existingTable', { defaultMessage: 'Existing table' })}</div>
|
||||
<TableControl
|
||||
rows={sources}
|
||||
focusOnCreate
|
||||
@@ -118,14 +119,14 @@
|
||||
selectable
|
||||
on:keydown={sourceKeyDown}
|
||||
columns={[
|
||||
{ fieldName: 'alias', header: 'Alias' },
|
||||
{ fieldName: 'name', header: 'Name' },
|
||||
{ fieldName: 'alias', header: _t('insertJoin.alias', { defaultMessage: 'Alias' }) },
|
||||
{ fieldName: 'name', header: _t('insertJoin.name', { defaultMessage: 'Name' }) },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="m-1 col-6">
|
||||
<div class="m-1">New table</div>
|
||||
<div class="m-1">{_t('insertJoin.newTable', { defaultMessage: 'New table' })}</div>
|
||||
|
||||
<TableControl
|
||||
rows={targets}
|
||||
@@ -134,15 +135,15 @@
|
||||
selectable
|
||||
on:keydown={targetKeyDown}
|
||||
columns={[
|
||||
{ fieldName: 'baseColumns', header: 'Column from' },
|
||||
{ fieldName: 'refTable', header: 'Table to' },
|
||||
{ fieldName: 'refColumns', header: 'Column to' },
|
||||
{ fieldName: 'baseColumns', header: _t('insertJoin.columnFrom', { defaultMessage: 'Column from' }) },
|
||||
{ fieldName: 'refTable', header: _t('insertJoin.tableTo', { defaultMessage: 'Table to' }) },
|
||||
{ fieldName: 'refColumns', header: _t('insertJoin.columnTo', { defaultMessage: 'Column to' }) },
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="m-1 col-3">
|
||||
<div class="m-1">Join</div>
|
||||
<div class="m-1">{_t('insertJoin.join', { defaultMessage: 'Join' })}</div>
|
||||
|
||||
<TableControl
|
||||
rows={JOIN_TYPES.map(name => ({ name }))}
|
||||
@@ -150,10 +151,10 @@
|
||||
bind:domTable={domJoin}
|
||||
selectable
|
||||
on:keydown={joinKeyDown}
|
||||
columns={[{ fieldName: 'name', header: 'Join type' }]}
|
||||
columns={[{ fieldName: 'name', header: _t('insertJoin.joinType', { defaultMessage: 'Join type' }) }]}
|
||||
/>
|
||||
|
||||
<div class="m-1">Alias</div>
|
||||
<div class="m-1">{_t('insertJoin.alias', { defaultMessage: 'Alias' })}</div>
|
||||
<TextField
|
||||
value={alias}
|
||||
on:input={e => {
|
||||
@@ -171,13 +172,13 @@
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormStyledButton
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={() => {
|
||||
closeCurrentModal();
|
||||
onInsert(sqlPreview);
|
||||
}}
|
||||
/>
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { openWebLink } from '../utility/simpleTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
@@ -15,7 +16,7 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">License limit error</div>
|
||||
<div slot="header">{_t('licenseLimit.licenseLimitError', { defaultMessage: 'License limit error' })}</div>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="icon">
|
||||
@@ -23,15 +24,15 @@
|
||||
</div>
|
||||
<div data-testid="LicenseLimitMessageModal_message">
|
||||
<p>
|
||||
Cloud operation ended with error:<br />
|
||||
{_t('licenseLimit.cloudOperationEndedWithError', { defaultMessage: 'Cloud operation ended with error:' })}<br />
|
||||
{message}
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is a limitation of the free version of DbGate. To continue using cloud operations, please {#if !isProApp()}download
|
||||
and{/if} purchase DbGate Premium.
|
||||
{_t('licenseLimit.limitationMessage', { defaultMessage: 'This is a limitation of the free version of DbGate. To continue using cloud operations, please' })} {#if !isProApp()} {_t('licenseLimit.download', { defaultMessage: 'download and' })}
|
||||
{/if} {_t('licenseLimit.purchase', { defaultMessage: 'purchase DbGate Premium.' })}
|
||||
</p>
|
||||
<p>Free version limit:</p>
|
||||
<p>{_t('licenseLimit.freeVersionLimit', { defaultMessage: 'Free version limit:' })}</p>
|
||||
<ul>
|
||||
{#each licenseLimits || [] as limit}
|
||||
<li>{limit}</li>
|
||||
@@ -41,16 +42,16 @@
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<FormSubmit value="Close" on:click={closeCurrentModal} data-testid="LicenseLimitMessageModal_closeButton" />
|
||||
<FormSubmit value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} data-testid="LicenseLimitMessageModal_closeButton" />
|
||||
{#if !isProApp()}
|
||||
<FormStyledButton
|
||||
value="Download DbGate Premium"
|
||||
value={_t('licenseLimit.downloadDbGatePremium', { defaultMessage: 'Download DbGate Premium' })}
|
||||
on:click={() => openWebLink('https://www.dbgate.io/download/')}
|
||||
skipWidth
|
||||
/>
|
||||
{/if}
|
||||
<FormStyledButton
|
||||
value="Purchase DbGate Premium"
|
||||
value={_t('licenseLimit.purchaseDbGatePremium', { defaultMessage: 'Purchase DbGate Premium' })}
|
||||
on:click={() => openWebLink('https://www.dbgate.io/purchase/premium/')}
|
||||
skipWidth
|
||||
/>
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
|
||||
const { errorMessage } = resp || {};
|
||||
if (errorMessage) {
|
||||
showModal(ErrorMessageModal, { title: 'Error when executing operation', message: errorMessage });
|
||||
showModal(ErrorMessageModal, { title: _t('error.executingOperation', { defaultMessage: 'Error when executing operation' }), message: errorMessage });
|
||||
} else {
|
||||
showSnackbarSuccess('Saved to database');
|
||||
showSnackbarSuccess(_t('common.savedToDatabase', { defaultMessage: 'Saved to database' }));
|
||||
apiCall('database-connections/sync-model', dbid);
|
||||
closeCurrentModal();
|
||||
}
|
||||
@@ -51,7 +51,7 @@
|
||||
<FormArgumentList args={driver?.newCollectionFormParams} />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit value="OK" on:click={e => handleSubmit(e.detail)} disabled={isSaving} />
|
||||
<FormSubmit value={_t('common.ok', { defaultMessage: 'OK' })} on:click={e => handleSubmit(e.detail)} disabled={isSaving} />
|
||||
<FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
{
|
||||
icon: 'icon compare',
|
||||
colorClass: 'color-icon-red',
|
||||
title: _t('common.compare', { defaultMessage: 'Compare database' }),
|
||||
title: _t('common.compareDatabase', { defaultMessage: 'Compare database' }),
|
||||
description: _t('newObject.compareDescription', { defaultMessage: 'Compare database schemas' }),
|
||||
command: 'database.compare',
|
||||
testid: 'NewObjectModal_databaseCompare',
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import getElectron from '../utility/getElectron';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
@@ -26,7 +27,7 @@
|
||||
|
||||
<FormProvider initialValues={parameterValues}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Edit query parameters</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('queryParameters.editQueryParameters', { defaultMessage: 'Edit query parameters' })}</svelte:fragment>
|
||||
|
||||
<div class="params">
|
||||
{#each parameterNames as parameterName, index}
|
||||
@@ -34,11 +35,11 @@
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div>String values must be 'quoted'. You can use valid SQL expressions.</div>
|
||||
<div>{_t('queryParameters.stringValuesMustBeQuoted', { defaultMessage: "String values must be 'quoted'. You can use valid SQL expressions." })}</div>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit value="Run query" on:click={handleSubmit} />
|
||||
<FormStyledButton value="Close" on:click={handleClose} />
|
||||
<FormSubmit value={_t('queryParameters.runQuery', { defaultMessage: 'Run query' })} on:click={handleSubmit} />
|
||||
<FormStyledButton value={_t('common.close', { defaultMessage: 'Close' })} on:click={handleClose} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let value;
|
||||
export let onConfirm;
|
||||
@@ -18,24 +19,24 @@
|
||||
|
||||
<FormProvider initialValues={{ value }}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Rows limit</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('query.rowsLimit', { defaultMessage: 'Rows limit' })}</svelte:fragment>
|
||||
|
||||
<FormTextField
|
||||
label="Return only N rows from query"
|
||||
label={_t('query.returnOnlyNRows', { defaultMessage: 'Return only N rows from query' })}
|
||||
name="value"
|
||||
focused
|
||||
data-testid="RowsLimitModal_value"
|
||||
placeholder="(No rows limit)"
|
||||
placeholder={_t('query.noRowsLimit', { defaultMessage: '(No rows limit)' })}
|
||||
/>
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={e => handleSubmit(parseInt(e.detail.value) || null)}
|
||||
data-testid="RowsLimitModal_setLimit"
|
||||
/>
|
||||
<FormStyledButton value="Set no limit" on:click={e => handleSubmit(null)} data-testid="RowsLimitModal_setNoLimit" />
|
||||
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} data-testid="RowsLimitModal_cancel" />
|
||||
<FormStyledButton value={_t('common.setNoLimit', { defaultMessage: 'Set no limit' })} on:click={e => handleSubmit(null)} data-testid="RowsLimitModal_setNoLimit" />
|
||||
<FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} data-testid="RowsLimitModal_cancel" />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
import ModalBase from './ModalBase.svelte';
|
||||
import { closeCurrentModal } from './modalTools';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let script;
|
||||
export let header;
|
||||
@@ -77,14 +78,14 @@
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
{#if isRunning}
|
||||
<FormStyledButton value="Stop" on:click={handleStop} data-testid="RunScriptModal_stop" />
|
||||
<FormStyledButton value={_t('script.stop', { defaultMessage: 'Stop' })} on:click={handleStop} data-testid="RunScriptModal_stop" />
|
||||
{:else}
|
||||
<FormStyledButton value="Close" on:click={handleClose} data-testid="RunScriptModal_close" />
|
||||
<FormStyledButton value={_t('common.close', { defaultMessage: 'Close' })} on:click={handleClose} data-testid="RunScriptModal_close" />
|
||||
{/if}
|
||||
|
||||
{#if onOpenResult && !isRunning}
|
||||
<FormStyledButton
|
||||
value={openResultLabel || 'Open result'}
|
||||
value={openResultLabel || _t('script.openResult', { defaultMessage: 'Open result' })}
|
||||
on:click={() => {
|
||||
closeCurrentModal();
|
||||
onOpenResult();
|
||||
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
<FormProvider initialValues={{ file, folder }}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Save to archive</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('archive.saveToArchive', { defaultMessage: 'Save to archive' })}</svelte:fragment>
|
||||
|
||||
<FormArchiveFolderSelect label="Folder" name="folder" isNative allowCreateNew skipZipFiles />
|
||||
<FormTextField label="File name" name="file" disabled={fileIsReadOnly} />
|
||||
<FormArchiveFolderSelect label={_t('archive.folder', { defaultMessage: 'Folder' })} name="folder" isNative allowCreateNew skipZipFiles />
|
||||
<FormTextField label={_t('archive.fileName', { defaultMessage: 'File name' })} name="file" disabled={fileIsReadOnly} />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit value={_t('common.save', { defaultMessage: 'Save' })} on:click={handleSubmit} />
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
<FormTextField label="File name" name="name" focused />
|
||||
{#if $cloudSigninTokenHolder && !$values['saveToTeamFolder']}
|
||||
<FormCloudFolderSelect
|
||||
label="Choose cloud folder"
|
||||
label={_t('cloud.chooseCloudFolder', { defaultMessage: "Choose cloud folder" })}
|
||||
name="cloudFolder"
|
||||
isNative
|
||||
requiredRoleVariants={['write', 'admin']}
|
||||
@@ -134,13 +134,13 @@
|
||||
: [
|
||||
{
|
||||
folid: '__local',
|
||||
name: "Local folder (don't store on cloud)",
|
||||
name: _t('cloud.localFolder', { defaultMessage: "Local folder (don't store on cloud)" }),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
{/if}
|
||||
{#if $configValue?.storageDatabase}
|
||||
<FormCheckboxField label="Save to team folder" name="saveToTeamFolder" />
|
||||
<FormCheckboxField label={_t('cloud.saveToTeamFolder', { defaultMessage: "Save to team folder" })} name="saveToTeamFolder" />
|
||||
{/if}
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
@@ -148,12 +148,12 @@
|
||||
{#if electron}
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Save to disk"
|
||||
value={_t('common.saveToDisk', { defaultMessage: 'Save to disk' })}
|
||||
on:click={async () => {
|
||||
const file = await electron.showSaveDialog({
|
||||
filters: [
|
||||
{ name: `${fileExtension.toUpperCase()} files`, extensions: [fileExtension] },
|
||||
{ name: `All files`, extensions: ['*'] },
|
||||
{ name: _t('common.fileType', { defaultMessage: '{extension} files', values: {extension: fileExtension.toUpperCase()} }), extensions: [fileExtension] },
|
||||
{ name: _t('common.allFiles', { defaultMessage: 'All files' }), extensions: ['*'] },
|
||||
],
|
||||
defaultPath: filePath || `${name}.${fileExtension}`,
|
||||
properties: ['showOverwriteConfirmation'],
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<FormSubmit value="OK" on:click={handleOk} />
|
||||
<FormSubmit value={_t('common.ok', {defaultMessage: "OK"})} on:click={handleOk} />
|
||||
<FormButton type="button" value={_t('common.close', {defaultMessage: 'Close'})} on:click={closeCurrentModal} />
|
||||
</div>
|
||||
</ModalBase>
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
</script>
|
||||
|
||||
<ModalBase {...$$restProps}>
|
||||
<div slot="header">SQL Script</div>
|
||||
<div slot="header">{_t('script.sqlScript', { defaultMessage: 'SQL Script' })}</div>
|
||||
|
||||
<div class="editor">
|
||||
<SqlEditor {engine} value={sql} readOnly />
|
||||
@@ -29,7 +29,7 @@
|
||||
/>
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Open script"
|
||||
value={_t('common.openScript', { defaultMessage: "Open script" })}
|
||||
on:click={() => {
|
||||
newQuery({
|
||||
initialData: sql,
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
import LoadingInfo from '../elements/LoadingInfo.svelte';
|
||||
import { getObjectTypeFieldLabel } from '../utility/common';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
@@ -113,7 +114,7 @@
|
||||
function editSql() {
|
||||
openNewTab(
|
||||
{
|
||||
title: 'Query #',
|
||||
title: _t('query.queryNumber', { defaultMessage: 'Query #' }),
|
||||
icon: 'img sql-file',
|
||||
tabComponent: 'QueryTab',
|
||||
focused: true,
|
||||
@@ -133,7 +134,7 @@
|
||||
<FormProviderCore values={valuesStore} template={FormFieldTemplateTiny}>
|
||||
<ModalBase {...$$restProps} fullScreen>
|
||||
<svelte:fragment slot="header">
|
||||
SQL Generator
|
||||
{_t('sqlGenerator.sqlGenerator', { defaultMessage: 'SQL Generator' })}
|
||||
<span class="dbname">
|
||||
<FontIcon icon="icon database" />
|
||||
{database}
|
||||
@@ -146,9 +147,9 @@
|
||||
<HorizontalSplitter initialValue="300px" bind:size={managerSize}>
|
||||
<svelte:fragment slot="1">
|
||||
<div class="flexcol flex1">
|
||||
<WidgetTitle>Choose objects</WidgetTitle>
|
||||
<WidgetTitle>{_t('sqlGenerator.chooseObjects', { defaultMessage: 'Choose objects' })}</WidgetTitle>
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search tables or objects" bind:value={objectsFilter} />
|
||||
<SearchInput placeholder={_t('sqlGenerator.searchTablesOrObjects', { defaultMessage: 'Search tables or objects' })} bind:value={objectsFilter} />
|
||||
</SearchBoxWrapper>
|
||||
|
||||
<WidgetsInnerContainer>
|
||||
@@ -174,54 +175,53 @@
|
||||
{:else}
|
||||
<div class="flexcol flex1">
|
||||
{#if truncated}
|
||||
<ErrorInfo icon="img warn" message="SQL truncated, file size limit exceed" />
|
||||
<ErrorInfo icon="img warn" message={_t('sqlGenerator.sqlTruncated', { defaultMessage: 'SQL truncated, file size limit exceed' })} />
|
||||
{/if}
|
||||
<div class="relative flex1">
|
||||
<SqlEditor readOnly value={sqlPreview} />
|
||||
</div>
|
||||
</div>
|
||||
{#if busy}
|
||||
<LoadingInfo wrapper message="Loading SQL preview" />
|
||||
<LoadingInfo wrapper message={_t('sqlGenerator.loadingSqlPreview', { defaultMessage: "Loading SQL preview" })} />
|
||||
{/if}
|
||||
{/if}
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="2">
|
||||
<div class="flexcol flex1">
|
||||
<WidgetTitle>Generator settings</WidgetTitle>
|
||||
<WidgetTitle>{_t('sqlGenerator.generatorSettings', { defaultMessage: 'Generator settings' })}</WidgetTitle>
|
||||
<WidgetsInnerContainer>
|
||||
<FormValues let:values>
|
||||
<div class="obj-heading">Tables</div>
|
||||
<FormCheckboxField label="Drop tables" name="dropTables" />
|
||||
<div class="obj-heading">{_t('sqlGenerator.tables', { defaultMessage: 'Tables' })}</div>
|
||||
<FormCheckboxField label={_t('sqlGenerator.dropTables', { defaultMessage: 'Drop tables' })} name="dropTables" />
|
||||
{#if values.dropTables}
|
||||
<div class="ml-2">
|
||||
<FormCheckboxField label="Test if exists" name="checkIfTableExists" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.testIfExists', { defaultMessage: 'Test if exists' })} name="checkIfTableExists" />
|
||||
</div>
|
||||
{/if}
|
||||
<FormCheckboxField label="Drop references" name="dropReferences" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.dropReferences', { defaultMessage: 'Drop references' })} name="dropReferences" />
|
||||
|
||||
<FormCheckboxField label="Create tables" name="createTables" />
|
||||
<FormCheckboxField label="Create references" name="createReferences" />
|
||||
<FormCheckboxField label="Create foreign keys" name="createForeignKeys" />
|
||||
<FormCheckboxField label="Create indexes" name="createIndexes" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.createTables', { defaultMessage: 'Create tables' })} name="createTables" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.createReferences', { defaultMessage: 'Create references' })} name="createReferences" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.createForeignKeys', { defaultMessage: 'Create foreign keys' })} name="createForeignKeys" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.createIndexes', { defaultMessage: 'Create indexes' })} name="createIndexes" />
|
||||
|
||||
<FormCheckboxField label="Insert" name="insert" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.insert', { defaultMessage: 'Insert' })} name="insert" />
|
||||
{#if values.insert}
|
||||
<div class="ml-2">
|
||||
<FormCheckboxField label="Skip autoincrement column" name="skipAutoincrementColumn" />
|
||||
<FormCheckboxField label="Disable constraints" name="disableConstraints" />
|
||||
<FormCheckboxField label="Omit NULL values" name="omitNulls" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.skipAutoincrementColumn', { defaultMessage: 'Skip autoincrement column' })} name="skipAutoincrementColumn" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.disableConstraints', { defaultMessage: 'Disable constraints' })} name="disableConstraints" />
|
||||
<FormCheckboxField label={_t('sqlGenerator.omitNulls', { defaultMessage: 'Omit NULL values' })} name="omitNulls" />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<FormCheckboxField label="Truncate tables (delete all rows)" name="truncate" />
|
||||
|
||||
<FormCheckboxField label={_t('sqlGenerator.truncate', { defaultMessage: 'Truncate tables (delete all rows)' })} name="truncate" />
|
||||
{#each ['View', 'Matview', 'Procedure', 'Function', 'Trigger', 'SchedulerEvent'] as objtype}
|
||||
<div class="obj-heading">{getObjectTypeFieldLabel(objtype + 's')}</div>
|
||||
<FormCheckboxField label="Create" name={`create${objtype}s`} />
|
||||
<FormCheckboxField label="Drop" name={`drop${objtype}s`} />
|
||||
<FormCheckboxField label={_t('sqlGenerator.create', { defaultMessage: 'Create {objtype}s', values: {objtype} })} name={`create${objtype}s`} />
|
||||
<FormCheckboxField label={_t('sqlGenerator.drop', { defaultMessage: `Drop ${objtype}s` })} name={`drop${objtype}s`} />
|
||||
{#if values[`drop${objtype}s`]}
|
||||
<div class="ml-2">
|
||||
<FormCheckboxField label="Check if exists" name={`checkIf${objtype}Exists`} />
|
||||
<FormCheckboxField label={_t('sqlGenerator.checkIfExists', { defaultMessage: 'Check if exists' })} name={`checkIf${objtype}Exists`} />
|
||||
</div>
|
||||
{/if}
|
||||
{/each}
|
||||
@@ -241,8 +241,8 @@
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<div class="flex m-2">
|
||||
<LargeButton on:click={editSql} icon="icon sql-file">Edit SQL</LargeButton>
|
||||
<LargeButton on:click={closeCurrentModal} icon="icon close">Close</LargeButton>
|
||||
<LargeButton on:click={editSql} icon="icon sql-file">{_t('sqlGenerator.editSql', { defaultMessage: 'Edit SQL' })}</LargeButton>
|
||||
<LargeButton on:click={closeCurrentModal} icon="icon close">{_t('common.close', { defaultMessage: 'Close' })}</LargeButton>
|
||||
</div>
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import FormConnectionSelect from '../impexp/FormConnectionSelect.svelte';
|
||||
import FormDatabaseSelect from '../impexp/FormDatabaseSelect.svelte';
|
||||
import { changeTab } from '../utility/common';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let editingData;
|
||||
export let callingTab;
|
||||
@@ -46,15 +47,15 @@
|
||||
|
||||
<FormProvider {initialValues}>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Switch database</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('switchDatabase.switchDatabase', { defaultMessage: 'Switch database' })}</svelte:fragment>
|
||||
|
||||
<FormConnectionSelect name="conid" label="Server" direction="source" isNative />
|
||||
<FormDatabaseSelect conidName="conid" name="database" label="Database" isNative />
|
||||
<FormConnectionSelect name="conid" label={_t('switchDatabase.server', { defaultMessage: 'Server' })} direction="source" isNative />
|
||||
<FormDatabaseSelect conidName="conid" name="database" label={_t('common.database', { defaultMessage: 'Database' })} isNative />
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormValues let:values>
|
||||
<FormSubmit value="OK" on:click={handleSubmit} />
|
||||
<FormButton value="Cancel" on:click={closeCurrentModal} />
|
||||
<FormSubmit value={_t('common.ok', { defaultMessage: 'OK' })} on:click={handleSubmit} />
|
||||
<FormButton value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
|
||||
</FormValues>
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
<svelte:fragment slot="footer">
|
||||
{#if multiselect}
|
||||
<FormSubmit
|
||||
value="OK"
|
||||
value={_t('common.ok', { defaultMessage: 'OK' })}
|
||||
on:click={() => {
|
||||
closeCurrentModal();
|
||||
onConfirm(checkedKeys);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
import type { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveCustomJoinConfig } from 'dbgate-datalib';
|
||||
import uuidv1 from 'uuid/v1';
|
||||
import TextField from '../forms/TextField.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
@@ -90,7 +91,7 @@
|
||||
|
||||
$: connections = useConnectionList();
|
||||
$: connectionOptions = [
|
||||
{ value: null, label: 'The same as root' },
|
||||
{ value: null, label: _t('customJoin.theSameAsRoot', { defaultMessage: 'The same as root' }) },
|
||||
..._.sortBy(
|
||||
($connections || [])
|
||||
// .filter(x => !x.unsaved)
|
||||
@@ -107,7 +108,7 @@
|
||||
$: databases = useDatabaseList({ conid: conidOverride || conid });
|
||||
|
||||
$: databaseOptions = [
|
||||
{ value: null, label: 'The same as root' },
|
||||
{ value: null, label: _t('customJoin.theSameAsRoot', { defaultMessage: 'The same as root' }) },
|
||||
..._.sortBy(
|
||||
($databases || []).map(db => ({
|
||||
value: db.name,
|
||||
@@ -147,11 +148,11 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Define custom join</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('customJoin.defineCustomJoin', { defaultMessage: 'Define custom join' })}</svelte:fragment>
|
||||
|
||||
<div class="largeFormMarker">
|
||||
<div class="row">
|
||||
<div class="label col-3">Join name</div>
|
||||
<div class="label col-3">{_t('customJoin.joinName', { defaultMessage: 'Join name' })}</div>
|
||||
<div class="col-9">
|
||||
<TextField
|
||||
value={joinName}
|
||||
@@ -164,7 +165,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="label col-3">Base table</div>
|
||||
<div class="label col-3">{_t('customJoin.baseTable', { defaultMessage: 'Base table' })}</div>
|
||||
<div class="col-9">
|
||||
<SelectField
|
||||
value={fromDesignerId}
|
||||
@@ -181,7 +182,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="label col-3">Connection</div>
|
||||
<div class="label col-3">{_t('customJoin.connection', { defaultMessage: 'Connection' })}</div>
|
||||
<div class="col-9">
|
||||
<SelectField
|
||||
value={conidOverride}
|
||||
@@ -195,7 +196,7 @@
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="label col-3">Database</div>
|
||||
<div class="label col-3">{_t('customJoin.database', { defaultMessage: 'Database' })}</div>
|
||||
<div class="col-9">
|
||||
<SelectField
|
||||
value={databaseOverride}
|
||||
@@ -212,7 +213,7 @@
|
||||
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} label="Database" /> -->
|
||||
|
||||
<div class="row">
|
||||
<div class="label col-3">Referenced table</div>
|
||||
<div class="label col-3">{_t('customJoin.referencedTable', { defaultMessage: 'Referenced table' })}</div>
|
||||
<div class="col-9">
|
||||
<SelectField
|
||||
value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })}
|
||||
@@ -239,10 +240,10 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-5 mr-1">
|
||||
Base column - {fromTableInfo?.pureName}
|
||||
{_t('customJoin.baseColumn', { defaultMessage: 'Base column' })} - {fromTableInfo?.pureName}
|
||||
</div>
|
||||
<div class="col-5 ml-1">
|
||||
Ref column - {refTableName || '(table not set)'}
|
||||
{_t('customJoin.refColumn', { defaultMessage: 'Ref column' })} - {refTableName || _t('customJoin.tableNotSet', { defaultMessage: '(table not set)' })}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -286,7 +287,7 @@
|
||||
</div>
|
||||
<div class="col-2 button">
|
||||
<FormStyledButton
|
||||
value="Delete"
|
||||
value={_t('common.delete', { defaultMessage: 'Delete' })}
|
||||
on:click={e => {
|
||||
const x = [...columns];
|
||||
x.splice(index, 1);
|
||||
@@ -299,7 +300,7 @@
|
||||
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Add column"
|
||||
value={_t('customJoin.addColumn', { defaultMessage: 'Add column' })}
|
||||
on:click={() => {
|
||||
columns = [
|
||||
...columns,
|
||||
@@ -314,7 +315,7 @@
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value={'Save'}
|
||||
value={_t('common.save', { defaultMessage: 'Save' })}
|
||||
on:click={() => {
|
||||
setConfig(cfg => {
|
||||
const newNode = createPerspectiveNodeConfig({ pureName: refTableName, schemaName: refSchemaName });
|
||||
@@ -361,7 +362,7 @@
|
||||
}}
|
||||
/>
|
||||
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { filterName } from 'dbgate-tools';
|
||||
import InlineButton from '../buttons/InlineButton.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let items: any[];
|
||||
export let showProcedure = false;
|
||||
@@ -49,49 +50,49 @@
|
||||
}}
|
||||
>
|
||||
<FontIcon icon="icon delete" padRight />
|
||||
Clear
|
||||
{_t('messageView.clear', { defaultMessage: "Clear" })}
|
||||
</InlineButton>
|
||||
{/if}
|
||||
<RowsFilterSwitcher
|
||||
icon="img debug"
|
||||
label="Debug"
|
||||
label={_t('messageView.debug', { defaultMessage: "Debug" })}
|
||||
{values}
|
||||
field="hideDebug"
|
||||
count={items.filter(x => x.severity == 'debug').length}
|
||||
/>
|
||||
<RowsFilterSwitcher
|
||||
icon="img info"
|
||||
label="Info"
|
||||
label={_t('messageView.info', { defaultMessage: "Info" })}
|
||||
{values}
|
||||
field="hideInfo"
|
||||
count={items.filter(x => x.severity == 'info').length}
|
||||
/>
|
||||
<RowsFilterSwitcher
|
||||
icon="img error"
|
||||
label="Error"
|
||||
label={_t('messageView.error', { defaultMessage: "Error" })}
|
||||
{values}
|
||||
field="hideError"
|
||||
count={items.filter(x => x.severity == 'error').length}
|
||||
/>
|
||||
<SearchInput placeholder="Filter log messages" bind:value={filter} />
|
||||
<SearchInput placeholder={_t('messageView.filterLogMessages', { defaultMessage: "Filter log messages" })} bind:value={filter} />
|
||||
</div>
|
||||
<div class="tablewrap">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td class="header">Number</td>
|
||||
<td class="header">Message</td>
|
||||
<td class="header">Time</td>
|
||||
<td class="header">Delta</td>
|
||||
<td class="header">Duration</td>
|
||||
<td class="header">{_t('messageView.number', { defaultMessage: 'Number' })}</td>
|
||||
<td class="header">{_t('messageView.message', { defaultMessage: 'Message' })}</td>
|
||||
<td class="header">{_t('messageView.time', { defaultMessage: 'Time' })}</td>
|
||||
<td class="header">{_t('messageView.delta', { defaultMessage: 'Delta' })}</td>
|
||||
<td class="header">{_t('messageView.duration', { defaultMessage: 'Duration' })}</td>
|
||||
{#if showProcedure}
|
||||
<td class="header">Procedure</td>
|
||||
<td class="header">{_t('messageView.procedure', { defaultMessage: 'Procedure' })}</td>
|
||||
{/if}
|
||||
{#if showLine}
|
||||
<td class="header">Line</td>
|
||||
<td class="header">{_t('messageView.line', { defaultMessage: 'Line' })}</td>
|
||||
{/if}
|
||||
{#if showCaller}
|
||||
<td class="header">Caller</td>
|
||||
<td class="header">{_t('messageView.caller', { defaultMessage: 'Caller' })}</td>
|
||||
{/if}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
import AllResultsTab from './AllResultsTab.svelte';
|
||||
import JslChart from '../charts/JslChart.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import { __t, _t } from '../translations';
|
||||
|
||||
export let tabs = [];
|
||||
export let sessionId;
|
||||
@@ -68,7 +69,7 @@
|
||||
...(oneTab && resultInfos.length > 0
|
||||
? [
|
||||
{
|
||||
label: 'Results',
|
||||
label: _t('resultTabs.results', { defaultMessage: 'Results' }),
|
||||
isResult: true,
|
||||
component: AllResultsTab,
|
||||
props: {
|
||||
@@ -77,14 +78,14 @@
|
||||
},
|
||||
]
|
||||
: resultInfos.map((info, index) => ({
|
||||
label: `Result ${index + 1}`,
|
||||
label: _t('resultTabs.resultNumber', { defaultMessage: 'Result {number}', values: { number: index + 1 } }),
|
||||
isResult: true,
|
||||
component: JslDataGrid,
|
||||
resultIndex: info.resultIndex,
|
||||
props: { jslid: info.jslid, driver, onOpenChart: () => handleOpenChart(info.resultIndex) },
|
||||
}))),
|
||||
...charts.map((info, index) => ({
|
||||
label: `Chart ${info.resultIndex + 1}`,
|
||||
label: _t('resultTabs.chartNumber', { defaultMessage: 'Chart {number}', values: { number: info.resultIndex + 1 } }),
|
||||
isChart: true,
|
||||
resultIndex: info.resultIndex,
|
||||
component: JslChart,
|
||||
@@ -174,8 +175,8 @@
|
||||
tabs={allTabs}
|
||||
menu={resultInfos.length > 0 && [
|
||||
oneTab
|
||||
? { text: 'Every result in single tab', onClick: () => setOneTabValue(false) }
|
||||
: { text: 'All results in one tab', onClick: () => setOneTabValue(true) },
|
||||
? { text: _t('resultTabs.everyResultInSingleTab', { defaultMessage: 'Every result in single tab' }), onClick: () => setOneTabValue(false) }
|
||||
: { text: _t('resultTabs.allResultsInOneTab', { defaultMessage: 'All results in one tab' }), onClick: () => setOneTabValue(true) },
|
||||
]}
|
||||
onUserChange={value => {
|
||||
if (allTabs[value].isChart) {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { downloadFromApi } from '../utility/exportFileTools';
|
||||
import useEffect from '../utility/useEffect';
|
||||
import Link from '../elements/Link.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let runnerId;
|
||||
export let executeNumber;
|
||||
@@ -40,28 +41,28 @@
|
||||
</script>
|
||||
|
||||
{#if !files || files.length == 0}
|
||||
<ErrorInfo message="No output files" icon="img alert" />
|
||||
<ErrorInfo message={_t('query.NoOutputFiles', { defaultMessage: 'No output files' })} icon="img alert" />
|
||||
{:else}
|
||||
<div class="flex1 scroll">
|
||||
<TableControl
|
||||
rows={files}
|
||||
stickyHeader
|
||||
columns={[
|
||||
{ fieldName: 'name', header: 'Name' },
|
||||
{ fieldName: 'size', header: 'Size', formatter: row => formatFileSize(row.size) },
|
||||
{ fieldName: 'name', header: _t('query.Name', { defaultMessage: 'Name' }) },
|
||||
{ fieldName: 'size', header: _t('query.Size', { defaultMessage: 'Size' }), formatter: row => formatFileSize(row.size) },
|
||||
!electron && {
|
||||
fieldName: 'download',
|
||||
header: 'Download',
|
||||
header: _t('query.Download', { defaultMessage: 'Download' }),
|
||||
slot: 0,
|
||||
},
|
||||
electron && {
|
||||
fieldName: 'copy',
|
||||
header: 'Copy',
|
||||
header: _t('query.Copy', { defaultMessage: 'Copy' }),
|
||||
slot: 1,
|
||||
},
|
||||
electron && {
|
||||
fieldName: 'show',
|
||||
header: 'Show',
|
||||
header: _t('query.Show', { defaultMessage: 'Show' }),
|
||||
slot: 2,
|
||||
},
|
||||
]}
|
||||
@@ -72,7 +73,7 @@
|
||||
downloadFromApi(`runners/data/${runnerId}/${row.name}`, row.name);
|
||||
}}
|
||||
>
|
||||
download
|
||||
{_t('query.download', { defaultMessage: 'download' })}
|
||||
</Link>
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -86,7 +87,7 @@
|
||||
}
|
||||
}}
|
||||
>
|
||||
save
|
||||
{_t('query.save', { defaultMessage: 'save' })}
|
||||
</Link>
|
||||
</svelte:fragment>
|
||||
|
||||
@@ -96,7 +97,7 @@
|
||||
electron.showItemInFolder(row.path);
|
||||
}}
|
||||
>
|
||||
show
|
||||
{_t('query.show', { defaultMessage: 'show' })}
|
||||
</Link>
|
||||
</svelte:fragment>
|
||||
</TableControl>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import WidgetTitle from '../widgets/WidgetTitle.svelte';
|
||||
import RunnerOutputFiles from './RunnerOutputFiles.svelte';
|
||||
import SocketMessageView from './SocketMessageView.svelte';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export let runnerId;
|
||||
export let executeNumber;
|
||||
@@ -10,7 +11,7 @@
|
||||
|
||||
<HorizontalSplitter>
|
||||
<div class="container" slot="1">
|
||||
<WidgetTitle>Messages</WidgetTitle>
|
||||
<WidgetTitle>{_t('query.Messages', { defaultMessage: 'Messages' })}</WidgetTitle>
|
||||
<SocketMessageView
|
||||
eventName={runnerId ? `runner-info-${runnerId}` : null}
|
||||
{executeNumber}
|
||||
@@ -19,7 +20,7 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="container" slot="2">
|
||||
<WidgetTitle>Output files</WidgetTitle>
|
||||
<WidgetTitle>{_t('query.OutputFiles', { defaultMessage: 'Output files' })}</WidgetTitle>
|
||||
<RunnerOutputFiles {runnerId} {executeNumber} />
|
||||
</div>
|
||||
</HorizontalSplitter>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||
import { apiOff, apiOn } from '../utility/api';
|
||||
import createRef from '../utility/createRef';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import useEffect from '../utility/useEffect';
|
||||
|
||||
@@ -75,7 +76,7 @@
|
||||
</script>
|
||||
|
||||
{#if showNoMessagesAlert && (!displayedMessages || displayedMessages.length == 0)}
|
||||
<ErrorInfo message="No messages" icon="img alert" />
|
||||
<ErrorInfo message={_t('message.NoMessages', { defaultMessage: 'No messages' })} icon="img alert" />
|
||||
{:else}
|
||||
<MessageView
|
||||
items={displayedMessages}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<div class="wrapper">
|
||||
<FormValues let:values>
|
||||
<div class="heading">{_t('settings.defaultActions', { defaultMessage: 'Default actions' })}</div>
|
||||
<div class="heading">{_t('settings.defaultActions', { defaultMessage: 'Default Actions' })}</div>
|
||||
|
||||
<FormSelectField
|
||||
label={_t('settings.defaultActions.connectionClick', { defaultMessage: 'Connection click' })}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
</script>
|
||||
|
||||
<div class="wrapper">
|
||||
<div class="heading">{_t('settings.externalTools', { defaultMessage: 'External tools' })}</div>
|
||||
<div class="heading">{_t('settings.externalTools', { defaultMessage: 'External Tools' })}</div>
|
||||
<FormTextField
|
||||
name="externalTools.mysqldump"
|
||||
label={_t('settings.other.externalTools.mysqldump', {
|
||||
|
||||
@@ -188,7 +188,7 @@
|
||||
|
||||
<ObjectListControl
|
||||
collection={columns?.map((x, index) => ({ ...x, ordinal: index + 1 }))}
|
||||
title={_t('tableEditor.columns', {
|
||||
title={_t('tableEditor.columnsCount', {
|
||||
defaultMessage: 'Columns ({columnCount})',
|
||||
values: { columnCount: columns?.length || 0 },
|
||||
})}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
import { onMount, tick } from 'svelte';
|
||||
import TargetApplicationSelect from '../forms/TargetApplicationSelect.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { _t } from '../translations';
|
||||
// import { apiCall } from '../utility/api';
|
||||
// import { saveDbToApp } from '../utility/appTools';
|
||||
|
||||
@@ -70,11 +71,11 @@
|
||||
|
||||
<FormProvider>
|
||||
<ModalBase {...$$restProps}>
|
||||
<svelte:fragment slot="header">Virtual foreign key</svelte:fragment>
|
||||
<svelte:fragment slot="header">{_t('virtualForeignKey.virtualForeignKey', { defaultMessage: 'Virtual foreign key' })}</svelte:fragment>
|
||||
|
||||
<div class="largeFormMarker">
|
||||
<div class="row">
|
||||
<div class="label col-3">Referenced table</div>
|
||||
<div class="label col-3">{_t('virtualForeignKey.referencedTable', { defaultMessage: 'Referenced table' })}</div>
|
||||
<div class="col-9">
|
||||
<SelectField
|
||||
value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })}
|
||||
@@ -105,10 +106,10 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col-5 mr-1">
|
||||
Base column - {$tableInfo?.pureName}
|
||||
{_t('virtualForeignKey.baseColumn', { defaultMessage: 'Base column' })} - {$tableInfo?.pureName}
|
||||
</div>
|
||||
<div class="col-5 ml-1">
|
||||
Ref column - {refTableName || '(table not set)'}
|
||||
{_t('virtualForeignKey.refColumn', { defaultMessage: 'Ref column' })} - {refTableName || _t('virtualForeignKey.tableNotSet', { defaultMessage: '(table not set)' })}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -152,7 +153,7 @@
|
||||
</div>
|
||||
<div class="col-2 button">
|
||||
<FormStyledButton
|
||||
value="Delete"
|
||||
value={_t('common.delete', { defaultMessage: 'Delete' })}
|
||||
on:click={e => {
|
||||
const x = [...columns];
|
||||
x.splice(index, 1);
|
||||
@@ -165,14 +166,14 @@
|
||||
|
||||
<FormStyledButton
|
||||
type="button"
|
||||
value="Add column"
|
||||
value={_t('virtualForeignKey.addColumn', { defaultMessage: 'Add column' })}
|
||||
on:click={() => {
|
||||
columns = [...columns, {}];
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="row">
|
||||
<div class="label col-3">Target application</div>
|
||||
<div class="label col-3">{_t('virtualForeignKey.targetApplication', { defaultMessage: 'Target application' })}</div>
|
||||
<div class="col-9">
|
||||
<TargetApplicationSelect bind:value={dstApp} {conid} {database} />
|
||||
</div>
|
||||
@@ -181,7 +182,7 @@
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value={'Save'}
|
||||
value={_t('common.save', { defaultMessage: 'Save' })}
|
||||
disabled={!dstApp}
|
||||
on:click={async () => {
|
||||
await apiCall('apps/save-virtual-reference', {
|
||||
@@ -196,7 +197,7 @@
|
||||
}}
|
||||
/>
|
||||
|
||||
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
|
||||
<FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
|
||||
</svelte:fragment>
|
||||
</ModalBase>
|
||||
</FormProvider>
|
||||
|
||||
@@ -169,6 +169,7 @@
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
import QueryAiAssistant from '../ai/QueryAiAssistant.svelte';
|
||||
import { getCurrentSettings } from '../stores';
|
||||
import { Messages } from 'openai/resources/chat/completions';
|
||||
|
||||
export let tabid;
|
||||
export let conid;
|
||||
@@ -765,7 +766,7 @@
|
||||
<svelte:fragment slot="2">
|
||||
<ResultTabs
|
||||
bind:this={domResultTabs}
|
||||
tabs={[{ label: 'Messages', slot: 0 }]}
|
||||
tabs={[{ label: _t('query.Messages', { defaultMessage: 'Messages' }), slot: 0 }]}
|
||||
{sessionId}
|
||||
{executeNumber}
|
||||
bind:resultCount
|
||||
|
||||
@@ -172,11 +172,11 @@
|
||||
const resp = await apiCall('database-connections/run-script', { conid, database, sql, useTransaction: true });
|
||||
const { errorMessage } = resp || {};
|
||||
if (errorMessage) {
|
||||
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage });
|
||||
showModal(ErrorMessageModal, { title: _t('tableData.errorWhenSaving', { defaultMessage: 'Error when saving' }), message: errorMessage });
|
||||
} else {
|
||||
dispatchChangeSet({ type: 'reset', value: createChangeSet() });
|
||||
cache.update(reloadDataCacheFunc);
|
||||
showSnackbarSuccess('Saved to database');
|
||||
showSnackbarSuccess(_t('tableData.savedToDatabase', { defaultMessage: 'Saved to database' }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,11 +192,11 @@
|
||||
});
|
||||
const { errorMessage } = resp || {};
|
||||
if (errorMessage) {
|
||||
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage });
|
||||
showModal(ErrorMessageModal, { title: _t('tableData.errorWhenSaving', { defaultMessage: 'Error when saving' }), message: errorMessage });
|
||||
} else {
|
||||
dispatchChangeSet({ type: 'reset', value: createChangeSet() });
|
||||
cache.update(reloadDataCacheFunc);
|
||||
showSnackbarSuccess('Saved to database');
|
||||
showSnackbarSuccess(_t('tableData.savedToDatabase', { defaultMessage: 'Saved to database' }));
|
||||
}
|
||||
} else {
|
||||
const script = driver.createSaveChangeSetScript($changeSetStore?.value, $dbinfo, () =>
|
||||
@@ -360,13 +360,13 @@
|
||||
>
|
||||
|
||||
<ToolStripCommandSplitButton
|
||||
buttonLabel={autoRefreshStarted ? `Refresh (every ${autoRefreshInterval}s)` : null}
|
||||
buttonLabel={autoRefreshStarted ? _t('tableData.refreshEvery', { defaultMessage: 'Refresh (every {autoRefreshInterval}s)', values: { autoRefreshInterval } }) : null}
|
||||
commands={['dataGrid.refresh', ...createAutoRefreshMenu()]}
|
||||
hideDisabled
|
||||
data-testid="TableDataTab_refreshGrid"
|
||||
/>
|
||||
<ToolStripCommandSplitButton
|
||||
buttonLabel={autoRefreshStarted ? `Refresh (every ${autoRefreshInterval}s)` : null}
|
||||
buttonLabel={autoRefreshStarted ? _t('tableData.refreshEvery', { defaultMessage: 'Refresh (every {autoRefreshInterval}s)', values: { autoRefreshInterval } }) : null}
|
||||
commands={['dataForm.refresh', ...createAutoRefreshMenu()]}
|
||||
hideDisabled
|
||||
data-testid="TableDataTab_refreshForm"
|
||||
|
||||
@@ -6,6 +6,7 @@ import { getExtensions } from '../stores';
|
||||
import { getConnectionInfo, getDatabaseInfo } from './metadataLoaders';
|
||||
import ConfirmSqlModal, { saveScriptToDatabase } from '../modals/ConfirmSqlModal.svelte';
|
||||
import { apiCall } from './api';
|
||||
import { _t } from '../translations';
|
||||
|
||||
export async function alterDatabaseDialog(conid, database, updateFunc) {
|
||||
const conn = await getConnectionInfo({ conid });
|
||||
@@ -30,8 +31,8 @@ export async function alterDatabaseDialog(conid, database, updateFunc) {
|
||||
export async function renameDatabaseObjectDialog(conid, database, oldName, updateFunc) {
|
||||
showModal(InputTextModal, {
|
||||
value: oldName,
|
||||
label: 'New name',
|
||||
header: 'Rename object',
|
||||
label: _t('renameDatabaseObject.newName', { defaultMessage: 'New name' }),
|
||||
header: _t('renameDatabaseObject.header', { defaultMessage: 'Rename object' }),
|
||||
onConfirm: newName => {
|
||||
alterDatabaseDialog(conid, database, db => updateFunc(db, newName));
|
||||
},
|
||||
|
||||
@@ -161,8 +161,8 @@
|
||||
const handleRename = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: folder,
|
||||
label: 'New folder name',
|
||||
header: 'Rename folder',
|
||||
label: _t('connection.newFolderName', { defaultMessage: 'New folder name' }),
|
||||
header: _t('connection.renameFolder', { defaultMessage: 'Rename folder' }),
|
||||
onConfirm: async newFolder => {
|
||||
emptyConnectionGroupNames.update(folders => _.uniq(folders.map(fld => (fld == folder ? newFolder : fld))));
|
||||
apiCall('connections/batch-change-folder', {
|
||||
@@ -175,7 +175,7 @@
|
||||
|
||||
const handleDelete = () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really delete folder ${folder}? Connections in folder will be moved into root folder.`,
|
||||
message: _t('connection.deleteFolderConfirm', { defaultMessage: 'Really delete folder {folder}? Connections in folder will be moved into root folder.', values: { folder } }),
|
||||
onConfirm: () => {
|
||||
emptyConnectionGroupNames.update(folders => folders.filter(fld => fld != folder));
|
||||
apiCall('connections/batch-change-folder', {
|
||||
@@ -187,8 +187,8 @@
|
||||
};
|
||||
|
||||
return [
|
||||
{ text: 'Rename', onClick: handleRename },
|
||||
{ text: 'Delete', onClick: handleDelete },
|
||||
{ text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
{ text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import _ from 'lodash';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
import { _t } from '../translations';
|
||||
|
||||
import DbKeysSubTree from './DbKeysSubTree.svelte';
|
||||
|
||||
@@ -43,10 +44,10 @@
|
||||
return [
|
||||
item.key != null &&
|
||||
!connection?.isReadOnly && {
|
||||
label: 'Delete key',
|
||||
label: _t('dbKeysTreeNode.deleteKey', { defaultMessage: 'Delete key' }),
|
||||
onClick: () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really delete key ${item.key}?`,
|
||||
message: _t('dbKeysTreeNode.deleteKeyConfirm', { defaultMessage: 'Really delete key {key}?', values: { key: item.key } }),
|
||||
onConfirm: async () => {
|
||||
await apiCall('database-connections/call-method', {
|
||||
conid,
|
||||
@@ -62,12 +63,12 @@
|
||||
},
|
||||
item.key != null &&
|
||||
!connection?.isReadOnly && {
|
||||
label: 'Rename key',
|
||||
label: _t('dbKeysTreeNode.renameKey', { defaultMessage: 'Rename key' }),
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
value: item.key,
|
||||
label: 'New name',
|
||||
header: 'Rename key',
|
||||
label: _t('dbKeysTreeNode.newName', { defaultMessage: 'New name' }),
|
||||
header: _t('dbKeysTreeNode.renameKey', { defaultMessage: 'Rename key' }),
|
||||
onConfirm: async newName => {
|
||||
await apiCall('database-connections/call-method', {
|
||||
conid,
|
||||
@@ -90,11 +91,11 @@
|
||||
// },
|
||||
item.type == 'dir' &&
|
||||
!connection?.isReadOnly && {
|
||||
label: 'Delete branch',
|
||||
label: _t('dbKeysTreeNode.deleteBranch', { defaultMessage: 'Delete branch' }),
|
||||
onClick: () => {
|
||||
const branch = `${item.key}:*`;
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really delete branch ${branch} with all keys?`,
|
||||
message: _t('dbKeysTreeNode.deleteBranchConfirm', { defaultMessage: 'Really delete branch {branch} with all keys?', values: { branch } }),
|
||||
onConfirm: async () => {
|
||||
await apiCall('database-connections/call-method', {
|
||||
conid,
|
||||
@@ -110,7 +111,7 @@
|
||||
},
|
||||
,
|
||||
{
|
||||
label: 'Generate script',
|
||||
label: _t('dbKeysTreeNode.generateScript', { defaultMessage: 'Generate script' }),
|
||||
onClick: async () => {
|
||||
const data = await apiCall('database-connections/export-keys', {
|
||||
conid,
|
||||
@@ -126,7 +127,7 @@
|
||||
}
|
||||
|
||||
newQuery({
|
||||
title: 'Export #',
|
||||
title: _t('dbKeysTreeNode.exportTitle', { defaultMessage: 'Export #' }),
|
||||
initialData: data,
|
||||
});
|
||||
},
|
||||
@@ -137,7 +138,7 @@
|
||||
|
||||
<AppObjectCore
|
||||
icon={getIconForRedisType(item.type)}
|
||||
title={item.text || '(no name)'}
|
||||
title={item.text || _t('dbKeysTreeNode.noName', { defaultMessage: '(no name)' })}
|
||||
expandIcon={item.type == 'dir' ? plusExpandIcon(isExpanded) : 'icon invisible-box'}
|
||||
on:expand={() => {
|
||||
if (item.type == 'dir') {
|
||||
@@ -150,7 +151,7 @@
|
||||
} else {
|
||||
openNewTab({
|
||||
tabComponent: 'DbKeyDetailTab',
|
||||
title: item.text || '(no name)',
|
||||
title: item.text || _t('dbKeysTreeNode.noName', { defaultMessage: '(no name)' }),
|
||||
icon: 'img keydb',
|
||||
props: {
|
||||
isDefaultBrowser: true,
|
||||
|
||||
@@ -115,7 +115,7 @@
|
||||
command: 'new.connectionOnCloud',
|
||||
},
|
||||
{
|
||||
text: 'New SQL script',
|
||||
text: _t('privateCloudWidget.newSqlScript', { defaultMessage: 'New SQL script' }),
|
||||
onClick: () => {
|
||||
const data = '';
|
||||
showModal(SaveFileModal, {
|
||||
@@ -145,11 +145,11 @@
|
||||
function createAddFolderMenu() {
|
||||
return [
|
||||
isProApp() && {
|
||||
text: 'Create shared folder',
|
||||
text: _t('privateCloudWidget.createSharedFolder', { defaultMessage: 'Create shared folder' }),
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
label: 'New folder name',
|
||||
header: 'New shared folder',
|
||||
label: _t('privateCloudWidget.newFolderName', { defaultMessage: 'New folder name' }),
|
||||
header: _t('privateCloudWidget.newSharedFolder', { defaultMessage: 'New shared folder' }),
|
||||
onConfirm: async newFolder => {
|
||||
apiCall('cloud/create-folder', {
|
||||
name: newFolder,
|
||||
@@ -159,11 +159,11 @@
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Add existing folder (from link)',
|
||||
text: _t('privateCloudWidget.addExistingFolder', { defaultMessage: 'Add existing folder (from link)' }),
|
||||
onClick: () => {
|
||||
showModal(InputTextModal, {
|
||||
label: 'Your invite link (in form dbgate://folder/xxx)',
|
||||
header: 'Add existing shared folder',
|
||||
label: _t('privateCloudWidget.yourInviteLink', { defaultMessage: 'Your invite link (in form dbgate://folder/xxx)' }),
|
||||
header: _t('privateCloudWidget.addExistingSharedFolder', { defaultMessage: 'Add existing shared folder' }),
|
||||
onConfirm: async newFolder => {
|
||||
apiCall('cloud/grant-folder', {
|
||||
inviteLink: newFolder,
|
||||
@@ -179,8 +179,8 @@
|
||||
const handleRename = () => {
|
||||
showModal(InputTextModal, {
|
||||
value: contentGroupMap[folder]?.name,
|
||||
label: 'New folder name',
|
||||
header: 'Rename folder',
|
||||
label: _t('privateCloudWidget.newFolderName', { defaultMessage: 'New folder name' }),
|
||||
header: _t('privateCloudWidget.renameFolder', { defaultMessage: 'Rename folder' }),
|
||||
onConfirm: async name => {
|
||||
apiCall('cloud/rename-folder', {
|
||||
folid: folder,
|
||||
@@ -192,8 +192,8 @@
|
||||
|
||||
const handleDelete = () => {
|
||||
showModal(ConfirmModal, {
|
||||
message: `Really delete folder ${contentGroupMap[folder]?.name}? All folder content will be deleted!`,
|
||||
header: 'Delete folder',
|
||||
message: _t('privateCloudWidget.deleteFolderConfirm', { defaultMessage: 'Really delete folder {folder}? All folder content will be deleted!', values: { folder: contentGroupMap[folder]?.name } }),
|
||||
header: _t('privateCloudWidget.deleteFolder', { defaultMessage: 'Delete folder' }),
|
||||
onConfirm: () => {
|
||||
apiCall('cloud/delete-folder', {
|
||||
folid: folder,
|
||||
@@ -204,13 +204,13 @@
|
||||
|
||||
return [
|
||||
contentGroupMap[folder]?.role == 'admin' && [
|
||||
{ text: 'Rename', onClick: handleRename },
|
||||
{ text: 'Delete', onClick: handleDelete },
|
||||
{ text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
|
||||
{ text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
|
||||
],
|
||||
isProApp() &&
|
||||
contentGroupMap[folder]?.role == 'admin' &&
|
||||
!contentGroupMap[folder]?.isPrivate && {
|
||||
text: 'Administrate access',
|
||||
text: _t('privateCloudWidget.administrateAccess', { defaultMessage: 'Administrate access' }),
|
||||
onClick: () => {
|
||||
showModal(ConfigureSharedFolderModal, {
|
||||
folid: folder,
|
||||
@@ -249,13 +249,13 @@
|
||||
skip={!$cloudSigninTokenHolder}
|
||||
>
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search cloud connections and files" bind:value={filter} />
|
||||
<SearchInput placeholder={_t('privateCloudWidget.searchPlaceholder', { defaultMessage: 'Search cloud connections and files' })} bind:value={filter} />
|
||||
<CloseSearchButton bind:filter />
|
||||
<DropDownButton icon="icon plus-thick" menu={createAddItemMenu} title="Add new connection or file" />
|
||||
<DropDownButton icon="icon add-folder" menu={createAddFolderMenu} title="Add new folder" />
|
||||
<DropDownButton icon="icon plus-thick" menu={createAddItemMenu} title={_t('privateCloudWidget.addNewConnectionOrFile', { defaultMessage: 'Add new connection or file' })} />
|
||||
<DropDownButton icon="icon add-folder" menu={createAddFolderMenu} title={_t('privateCloudWidget.addNewFolder', { defaultMessage: 'Add new folder' })} />
|
||||
<InlineButton
|
||||
on:click={handleRefreshContent}
|
||||
title="Refresh files"
|
||||
title={_t('privateCloudWidget.refreshFiles', { defaultMessage: 'Refresh files' })}
|
||||
data-testid="CloudItemsWidget_buttonRefreshContent"
|
||||
>
|
||||
<FontIcon icon="icon refresh" />
|
||||
@@ -289,11 +289,11 @@
|
||||
/>
|
||||
|
||||
{#if !cloudContentFlat?.length}
|
||||
<ErrorInfo message="You have no content on DbGate cloud" icon="img info" />
|
||||
<ErrorInfo message={_t('privateCloudWidget.noContent', { defaultMessage: 'You have no content on DbGate cloud' })} icon="img info" />
|
||||
<div class="error-info">
|
||||
<div class="m-1"></div>
|
||||
<FormStyledButton
|
||||
value="Create connection on DbGate Cloud"
|
||||
value={_t('privateCloudWidget.createConnection', { defaultMessage: 'Create connection on DbGate Cloud' })}
|
||||
skipWidth
|
||||
on:click={() => {
|
||||
runCommand('new.connectionOnCloud');
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Public Knowledge Base" name="publicCloud" storageName="publicCloudItems">
|
||||
<WidgetColumnBarItem title={_t('publicCloudWidget.publicKnowledgeBase', { defaultMessage: "Public Knowledge Base" })} name="publicCloud" storageName="publicCloudItems">
|
||||
<WidgetsInnerContainer>
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder={_t('publicCloudWidget.searchPublicFiles', { defaultMessage: "Search public files" })} bind:value={filter} />
|
||||
@@ -49,7 +49,7 @@
|
||||
/>
|
||||
|
||||
{#if !$publicFiles?.length}
|
||||
<ErrorInfo message="No files found for your configuration" />
|
||||
<ErrorInfo message={_t('publicCloudWidget.noFilesFound', { defaultMessage: "No files found for your configuration" })} />
|
||||
<div class="error-info">
|
||||
<div class="m-1">
|
||||
{_t('publicCloudWidget.onlyRelevantFilesListed', { defaultMessage: "Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first." })}
|
||||
|
||||
Reference in New Issue
Block a user