Added translation tags for objects, widgets, forms

This commit is contained in:
Stela Augustinova
2025-12-01 12:54:42 +01:00
parent d94a67d0af
commit 4ee6d089d5
19 changed files with 142 additions and 134 deletions

View File

@@ -53,14 +53,15 @@
import InputTextModal from '../modals/InputTextModal.svelte'; import InputTextModal from '../modals/InputTextModal.svelte';
import ConfirmModal from '../modals/ConfirmModal.svelte'; import ConfirmModal from '../modals/ConfirmModal.svelte';
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { _t } from '../translations';
export let data; export let data;
const handleRename = () => { const handleRename = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: data.fileName, value: data.fileName,
label: 'New file name', label: _t('appFile.newFileName', { defaultMessage: 'New file name' }),
header: 'Rename file', header: _t('appFile.renameFile', { defaultMessage: 'Rename file' }),
onConfirm: newFile => { onConfirm: newFile => {
apiCall('apps/rename-file', { apiCall('apps/rename-file', {
file: data.fileName, file: data.fileName,
@@ -74,7 +75,7 @@
const handleDelete = () => { const handleDelete = () => {
showModal(ConfirmModal, { showModal(ConfirmModal, {
message: `Really delete file ${data.fileName}?`, message: _t('appFile.deleteFileConfirm', { defaultMessage: 'Really delete file {fileName}?', values: { fileName: data.fileName } }),
onConfirm: () => { onConfirm: () => {
apiCall('apps/delete-file', { apiCall('apps/delete-file', {
file: data.fileName, file: data.fileName,
@@ -101,10 +102,10 @@
function createMenu() { function createMenu() {
return [ return [
{ text: 'Delete', onClick: handleDelete }, { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
{ text: 'Rename', onClick: handleRename }, { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile }, data.fileType.endsWith('.sql') && { text: _t('common.openSql', { defaultMessage: 'Open SQL' }), onClick: handleOpenSqlFile },
data.fileType.endsWith('.json') && { text: 'Open JSON', onClick: handleOpenJsonFile }, data.fileType.endsWith('.json') && { text: _t('common.openJson', { defaultMessage: 'Open JSON' }), onClick: handleOpenJsonFile },
// data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile }, // data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile },
]; ];

View File

@@ -15,6 +15,7 @@
import InputTextModal from '../modals/InputTextModal.svelte'; import InputTextModal from '../modals/InputTextModal.svelte';
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { useConnectionList } from '../utility/metadataLoaders'; import { useConnectionList } from '../utility/metadataLoaders';
import { _t } from '../translations';
export let data; export let data;
@@ -34,8 +35,8 @@
showModal(InputTextModal, { showModal(InputTextModal, {
value: name, value: name,
label: 'New application name', label: _t('appFolder.newApplicationName', { defaultMessage: 'New application name' }),
header: 'Rename application', header: _t('appFolder.renameApplication', { defaultMessage: 'Rename application' }),
onConfirm: async newFolder => { onConfirm: async newFolder => {
await apiCall('apps/rename-folder', { await apiCall('apps/rename-folder', {
folder: data.name, folder: data.name,
@@ -60,16 +61,16 @@
function createMenu() { function createMenu() {
return [ return [
{ text: 'Delete', onClick: handleDelete }, { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
{ text: 'Rename', onClick: handleRename }, { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
$currentDatabase && [ $currentDatabase && [
!isOnCurrentDb($currentDatabase, $connections) && { !isOnCurrentDb($currentDatabase, $connections) && {
text: 'Enable on current database', text: _t('appFolder.enableOnCurrentDatabase', { defaultMessage: 'Enable on current database' }),
onClick: () => setOnCurrentDb(true), onClick: () => setOnCurrentDb(true),
}, },
isOnCurrentDb($currentDatabase, $connections) && { isOnCurrentDb($currentDatabase, $connections) && {
text: 'Disable on current database', text: _t('appFolder.disableOnCurrentDatabase', { defaultMessage: 'Disable on current database' }),
onClick: () => setOnCurrentDb(false), onClick: () => setOnCurrentDb(false),
}, },
], ],
@@ -90,7 +91,7 @@
title={data.name} title={data.name}
icon={'img app'} icon={'img app'}
statusIcon={isOnCurrentDb($currentDatabase, $connections) ? 'icon check' : null} 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} isBold={data.name == $currentApplication}
on:click={() => ($currentApplication = data.name)} on:click={() => ($currentApplication = data.name)}
menu={createMenu} menu={createMenu}

View File

@@ -82,6 +82,7 @@
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { openImportExportTab } from '../utility/importExportTools'; import { openImportExportTab } from '../utility/importExportTools';
import { isProApp } from '../utility/proTools'; import { isProApp } from '../utility/proTools';
import { _t } from '../translations';
export let data; export let data;
$: isZipped = data.folderName?.endsWith('.zip'); $: isZipped = data.folderName?.endsWith('.zip');
@@ -89,8 +90,8 @@
const handleRename = () => { const handleRename = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: data.fileName, value: data.fileName,
label: 'New file name', label: _t('archiveFile.newFileName', { defaultMessage: 'New file name' }),
header: 'Rename file', header: _t('archiveFile.renameFile', { defaultMessage: 'Rename file' }),
onConfirm: newFile => { onConfirm: newFile => {
apiCall('archive/rename-file', { apiCall('archive/rename-file', {
file: data.fileName, file: data.fileName,
@@ -104,7 +105,7 @@
const handleDelete = () => { const handleDelete = () => {
showModal(ConfirmModal, { showModal(ConfirmModal, {
message: `Really delete file ${data.fileName}?`, message: _t('archiveFile.deleteFileConfirm', { defaultMessage: 'Really delete file {fileName}?', values: { fileName: data.fileName } }),
onConfirm: () => { onConfirm: () => {
apiCall('archive/delete-file', { apiCall('archive/delete-file', {
file: data.fileName, file: data.fileName,
@@ -147,10 +148,10 @@
} }
return [ return [
data.fileType == 'jsonl' && { text: 'Open', onClick: handleOpenArchive }, data.fileType == 'jsonl' && { text: _t('common.open', { defaultMessage: 'Open' }), onClick: handleOpenArchive },
data.fileType == 'jsonl' && { text: 'Open in text editor', onClick: handleOpenJsonLinesText }, data.fileType == 'jsonl' && { text: _t('common.openInTextEditor', { defaultMessage: 'Open in text editor' }), onClick: handleOpenJsonLinesText },
!isZipped && { text: 'Delete', onClick: handleDelete }, !isZipped && { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
!isZipped && { text: 'Rename', onClick: handleRename }, !isZipped && { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
data.fileType == 'jsonl' && data.fileType == 'jsonl' &&
createQuickExportMenu( createQuickExportMenu(
fmt => async () => { fmt => async () => {
@@ -185,19 +186,19 @@
}, },
} }
), ),
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile }, data.fileType.endsWith('.sql') && { text: _t('common.openSql', { defaultMessage: 'Open SQL' }), onClick: handleOpenSqlFile },
data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile }, data.fileType.endsWith('.yaml') && { text: _t('common.openYaml', { defaultMessage: 'Open YAML' }), onClick: handleOpenYamlFile },
!isZipped && !isZipped &&
isProApp() && isProApp() &&
data.fileType == 'jsonl' && { data.fileType == 'jsonl' && {
text: 'Open in profiler', text: _t('common.openInProfiler', { defaultMessage: 'Open in profiler' }),
submenu: getExtensions() submenu: getExtensions()
.drivers.filter(eng => eng.profilerFormatterFunction) .drivers.filter(eng => eng.profilerFormatterFunction)
.map(eng => ({ .map(eng => ({
text: eng.title, text: eng.title,
onClick: () => { onClick: () => {
openNewTab({ openNewTab({
title: 'Profiler', title: _t('common.profiler', { defaultMessage: 'Profiler' }),
icon: 'img profiler', icon: 'img profiler',
tabComponent: 'ProfilerTab', tabComponent: 'ProfilerTab',
props: { props: {

View File

@@ -21,14 +21,15 @@
import { isProApp } from '../utility/proTools'; import { isProApp } from '../utility/proTools';
import { extractShellConnection } from '../impexp/createImpExpScript'; import { extractShellConnection } from '../impexp/createImpExpScript';
import { saveFileToDisk } from '../utility/exportFileTools'; import { saveFileToDisk } from '../utility/exportFileTools';
import { _t } from '../translations';
export let data; export let data;
const handleDelete = () => { const handleDelete = () => {
showModal(ConfirmModal, { showModal(ConfirmModal, {
message: data.name.endsWith('.link') message: data.name.endsWith('.link')
? `Really delete link to folder ${data.name}? Folder content remains untouched.` ? _t('archiveFolder.deleteLinkConfirm', { defaultMessage: 'Really delete link to folder {folderName}? Folder content remains untouched.', values: { folderName: data.name } })
: `Really delete folder ${data.name}?`, : _t('archiveFolder.deleteFolderConfirm', { defaultMessage: 'Really delete folder {folderName}?', values: { folderName: data.name } }),
onConfirm: () => { onConfirm: () => {
apiCall('archive/delete-folder', { folder: data.name }); apiCall('archive/delete-folder', { folder: data.name });
}, },
@@ -42,8 +43,8 @@
showModal(InputTextModal, { showModal(InputTextModal, {
value: name, value: name,
label: 'New folder name', label: _t('archiveFolder.newFolderName', { defaultMessage: 'New folder name' }),
header: 'Rename folder', header: _t('archiveFolder.renameFolder', { defaultMessage: 'Rename folder' }),
onConfirm: async newFolder => { onConfirm: async newFolder => {
await apiCall('archive/rename-folder', { await apiCall('archive/rename-folder', {
folder: data.name, folder: data.name,
@@ -95,7 +96,7 @@ await dbgateApi.deployDb(${JSON.stringify(
const handleCompareWithCurrentDb = () => { const handleCompareWithCurrentDb = () => {
openNewTab( openNewTab(
{ {
title: 'Compare', title: _t('common.compare', { defaultMessage: 'Compare' }),
icon: 'img compare', icon: 'img compare',
tabComponent: 'CompareModelTab', tabComponent: 'CompareModelTab',
props: { props: {
@@ -153,7 +154,7 @@ await dbgateApi.deployDb(${JSON.stringify(
}); });
}, },
{ {
formatLabel: 'ZIP files', formatLabel: _t('common.zipFiles', { defaultMessage: 'ZIP files' }),
formatExtension: 'zip', formatExtension: 'zip',
defaultFileName: data.name?.endsWith('.zip') ? data.name : data.name + '.zip', defaultFileName: data.name?.endsWith('.zip') ? data.name : data.name + '.zip',
} }
@@ -162,28 +163,28 @@ await dbgateApi.deployDb(${JSON.stringify(
function createMenu() { function createMenu() {
return [ return [
data.name != 'default' && { text: 'Delete', onClick: handleDelete }, data.name != 'default' && { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
data.name != 'default' && { text: 'Rename', onClick: handleRename }, data.name != 'default' && { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
isProApp() && { text: 'Data deployer', onClick: handleOpenDataDeployTab }, isProApp() && { text: _t('common.dataDeployer', { defaultMessage: 'Data deployer' }), onClick: handleOpenDataDeployTab },
$currentDatabase && [ $currentDatabase && [
{ text: 'Generate deploy DB SQL', onClick: handleGenerateDeploySql }, { text: _t('archiveFolder.generateDeployDbSql', { defaultMessage: 'Generate deploy DB SQL' }), onClick: handleGenerateDeploySql },
hasPermission(`run-shell-script`) && { text: 'Shell: Deploy DB', onClick: handleGenerateDeployScript }, hasPermission(`run-shell-script`) && { text: _t('archiveFolder.shellDeployDb', { defaultMessage: 'Shell: Deploy DB' }), onClick: handleGenerateDeployScript },
], ],
data.name != 'default' && data.name != 'default' &&
isProApp() && 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' && data.name != 'default' &&
isProApp() && 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' && data.name != 'default' &&
hasPermission('dbops/model/compare') && hasPermission('dbops/model/compare') &&
isProApp() && isProApp() &&
_.get($currentDatabase, 'connection._id') && { _.get($currentDatabase, 'connection._id') && {
onClick: handleCompareWithCurrentDb, onClick: handleCompareWithCurrentDb,
text: `Compare with ${_.get($currentDatabase, 'name')}`, text: _t('archiveFolder.compareWithCurrentDb', { defaultMessage: 'Compare with {name}', values: { name: _.get($currentDatabase, 'name') } }),
}, },
]; ];
} }

View File

@@ -407,8 +407,8 @@ await dbgateApi.executeQuery(${JSON.stringify(
const handleCreateNewApp = () => { const handleCreateNewApp = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
header: 'New application', header: _t('database.newApplication', { defaultMessage: 'New application' }),
label: 'Application name', label: _t('database.applicationName', { defaultMessage: 'Application name' }),
value: _.startCase(name), value: _.startCase(name),
onConfirm: async appName => { onConfirm: async appName => {
const newAppId = await apiCall('apps/create-app-from-db', { const newAppId = await apiCall('apps/create-app-from-db', {

View File

@@ -188,12 +188,12 @@
divider: true, divider: true,
}, },
hasPermission('dbops/export') && { hasPermission('dbops/export') && {
label: 'Export', label: _t('common.export', { defaultMessage: 'Export' }),
functionName: 'tableReader', functionName: 'tableReader',
isExport: true, isExport: true,
}, },
hasPermission('dbops/import') && { hasPermission('dbops/import') && {
label: 'Import', label: _t('common.import', { defaultMessage: 'Import' }),
isImport: true, isImport: true,
requiresWriteAccess: true, requiresWriteAccess: true,
}, },
@@ -249,7 +249,7 @@
divider: true, divider: true,
}, },
{ {
label: 'Export', label: _t('common.export', { defaultMessage: 'Export' }),
isExport: true, isExport: true,
functionName: 'tableReader', functionName: 'tableReader',
}, },
@@ -299,7 +299,7 @@
divider: true, divider: true,
}, },
{ {
label: 'Export', label: _t('common.export', { defaultMessage: 'Export' }),
isExport: true, isExport: true,
functionName: 'tableReader', functionName: 'tableReader',
}, },
@@ -391,7 +391,7 @@
icon: 'img perspective', icon: 'img perspective',
}, },
hasPermission('dbops/export') && { hasPermission('dbops/export') && {
label: 'Export', label: _t('common.export', { defaultMessage: 'Export' }),
isExport: true, isExport: true,
functionName: 'tableReader', functionName: 'tableReader',
}, },

View File

@@ -193,6 +193,7 @@
import { saveFileToDisk } from '../utility/exportFileTools'; import { saveFileToDisk } from '../utility/exportFileTools';
import { getConnectionInfo } from '../utility/metadataLoaders'; import { getConnectionInfo } from '../utility/metadataLoaders';
import { showSnackbarError } from '../utility/snackbar'; import { showSnackbarError } from '../utility/snackbar';
import { _t } from '../translations';
export let data; export let data;
@@ -214,27 +215,26 @@
function createMenu() { function createMenu() {
return [ 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: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: 'Create copy', onClick: handleCopy }, !data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: _t('common.createCopy', { defaultMessage: 'Create copy' }), onClick: handleCopy },
!data.teamFileId && hasPermission(`files/${data.folder}/write`) && { text: 'Delete', onClick: handleDelete }, !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.allowWrite && { text: 'Rename', onClick: handleRename },
data.teamFileId && data.teamFileId &&
data.allowRead && data.allowRead &&
hasPermission('all-team-files/create') && { text: 'Create copy', onClick: handleCopy }, hasPermission('all-team-files/create') && { text: _t('common.createCopy', { defaultMessage: 'Create copy' }), onClick: handleCopy },
data.teamFileId && data.allowWrite && { text: 'Delete', onClick: handleDelete }, data.teamFileId && data.allowWrite && { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
folder == 'markdown' && { text: 'Show page', onClick: showMarkdownPage }, folder == 'markdown' && { text: _t('common.showPage', { defaultMessage: 'Show page' }), onClick: showMarkdownPage },
!data.teamFileId && { text: 'Download', onClick: handleDownload }, !data.teamFileId && { text: _t('common.download', { defaultMessage: 'Download' }), onClick: handleDownload },
data.teamFileId && data.allowRead && { text: 'Download', onClick: handleDownload }, data.teamFileId && data.allowRead && { text: _t('common.download', { defaultMessage: 'Download' }), onClick: handleDownload },
]; ];
} }
const handleDelete = () => { const handleDelete = () => {
showModal(ConfirmModal, { showModal(ConfirmModal, {
message: `Really delete file ${data.file}?`, message: _t('common.reallyDeleteFile', { defaultMessage: 'Really delete file {file}?', values: { file: data.file } }),
onConfirm: () => { onConfirm: () => {
if (data.teamFileId) { if (data.teamFileId) {
apiCall('team-files/delete', { teamFileId: data.teamFileId }); apiCall('team-files/delete', { teamFileId: data.teamFileId });
@@ -253,8 +253,8 @@
const handleRename = () => { const handleRename = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: data.file, value: data.file,
label: 'New file name', label: _t('common.newFileName', { defaultMessage: 'New file name' }),
header: 'Rename file', header: _t('common.renameFile', { defaultMessage: 'Rename file' }),
onConfirm: newFile => { onConfirm: newFile => {
if (data.teamFileId) { if (data.teamFileId) {
apiCall('team-files/update', { teamFileId: data.teamFileId, name: newFile }); apiCall('team-files/update', { teamFileId: data.teamFileId, name: newFile });
@@ -274,8 +274,8 @@
const handleCopy = () => { const handleCopy = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: data.file, value: data.file,
label: 'New file name', label: _t('savedFile.newFileName', { defaultMessage: 'New file name' }),
header: 'Copy file', header: _t('savedFile.copyFile', { defaultMessage: 'Copy file' }),
onConfirm: newFile => { onConfirm: newFile => {
if (data.teamFileId) { if (data.teamFileId) {
apiCall('team-files/copy', { teamFileId: data.teamFileId, newName: newFile }); apiCall('team-files/copy', { teamFileId: data.teamFileId, newName: newFile });
@@ -323,12 +323,12 @@
if (data.teamFileId) { if (data.teamFileId) {
if (data?.metadata?.autoExecute) { if (data?.metadata?.autoExecute) {
if (!data.allowUse) { 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; return;
} }
} else { } else {
if (!data.allowRead) { 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; return;
} }
} }

View File

@@ -201,7 +201,7 @@
bind:this={domInput} bind:this={domInput}
bind:value={filter} bind:value={filter}
on:keydown={handleKeyDown} on:keydown={handleKeyDown}
placeholder={parentCommand?.text || placeholder={_tval(parentCommand?.text) ||
($visibleCommandPalette == 'database' ? _t('commandPalette.searchInDatabase', { defaultMessage: 'Search in database' }) : _t('commandPalette.searchInCommands', { defaultMessage: 'Search in commands' }))} ($visibleCommandPalette == 'database' ? _t('commandPalette.searchInDatabase', { defaultMessage: 'Search in database' }) : _t('commandPalette.searchInCommands', { defaultMessage: 'Search in commands' }))}
/> />
</div> </div>

View File

@@ -1,5 +1,5 @@
<script context="module" lang="ts"> <script context="module" lang="ts">
import { __t } from '../translations' import { __t, _t } from '../translations'
const getCurrentEditor = () => getActiveComponent('SqlDataGridCore'); const getCurrentEditor = () => getActiveComponent('SqlDataGridCore');
registerCommand({ registerCommand({
@@ -127,7 +127,7 @@
export function openQuery(sql?) { export function openQuery(sql?) {
openNewTab( openNewTab(
{ {
title: 'Query #', title: _t('common.queryNumber', { defaultMessage: 'Query #' }),
icon: 'img sql-file', icon: 'img sql-file',
tabComponent: 'QueryTab', tabComponent: 'QueryTab',
focused: true, focused: true,

View File

@@ -67,7 +67,7 @@
import { isProApp } from '../utility/proTools'; import { isProApp } from '../utility/proTools';
import dragScroll from '../utility/dragScroll'; import dragScroll from '../utility/dragScroll';
import FormStyledButton from '../buttons/FormStyledButton.svelte'; import FormStyledButton from '../buttons/FormStyledButton.svelte';
import { __t } from '../translations'; import { __t, _t } from '../translations';
export let value; export let value;
export let onChange; export let onChange;
@@ -849,45 +849,45 @@
settings?.customizeStyle && [ settings?.customizeStyle && [
{ divider: true }, { divider: true },
isProApp() && { isProApp() && {
text: 'Column properties', text: _t('designer.columnProperties', { defaultMessage: 'Column properties' }),
submenu: [ 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), 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), onClick: changeStyleFunc('showDataType', !value?.style?.showDataType),
}, },
], ],
}, },
isProApp() && { isProApp() && {
text: `Columns - ${_.startCase(value?.style?.filterColumns || 'all')}`, text: _t('designer.columns', { defaultMessage: 'Columns - { filterColumns }', values: { filterColumns: _.startCase(value?.style?.filterColumns || 'all') } }),
submenu: [ submenu: [
{ {
text: 'All', text: _t('designer.all', { defaultMessage: 'All' }),
onClick: changeStyleFunc('filterColumns', ''), onClick: changeStyleFunc('filterColumns', ''),
}, },
{ {
text: 'Primary Key', text: _t('designer.primaryKey', { defaultMessage: 'Primary Key' }),
onClick: changeStyleFunc('filterColumns', 'primaryKey'), onClick: changeStyleFunc('filterColumns', 'primaryKey'),
}, },
{ {
text: 'All Keys', text: _t('designer.allKeys', { defaultMessage: 'All Keys' }),
onClick: changeStyleFunc('filterColumns', 'allKeys'), onClick: changeStyleFunc('filterColumns', 'allKeys'),
}, },
{ {
text: 'Not Null', text: _t('designer.notNull', { defaultMessage: 'Not Null' }),
onClick: changeStyleFunc('filterColumns', 'notNull'), onClick: changeStyleFunc('filterColumns', 'notNull'),
}, },
{ {
text: 'Keys And Not Null', text: _t('designer.keysAndNotNull', { defaultMessage: 'Keys And Not Null' }),
onClick: changeStyleFunc('filterColumns', 'keysAndNotNull'), 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 => ({ submenu: DIAGRAM_ZOOMS.map(koef => ({
text: `${koef * 100} %`, text: `${koef * 100} %`,
onClick: changeStyleFunc('zoomKoef', koef.toString()), onClick: changeStyleFunc('zoomKoef', koef.toString()),
@@ -1016,11 +1016,11 @@
use:dragScroll={handleDragScroll} use:dragScroll={handleDragScroll}
> >
{#if !(tables?.length > 0)} {#if !(tables?.length > 0)}
<div class="empty">Drag &amp; 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} {#if allowAddTablesButton}
<div class="addAllTables"> <div class="addAllTables">
<FormStyledButton value="Add all tables" on:click={handleAddAllTables} /> <FormStyledButton value={_t('designer.addAllTables', { defaultMessage: 'Add all tables' })} on:click={handleAddAllTables} />
</div> </div>
{/if} {/if}
{/if} {/if}
@@ -1119,7 +1119,7 @@
<div class="panel"> <div class="panel">
<DragColumnMemory {settings} {sourceDragColumn$} {targetDragColumn$} /> <DragColumnMemory {settings} {sourceDragColumn$} {targetDragColumn$} />
<div class="searchbox"> <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} /> <CloseSearchButton bind:filter={columnFilter} />
</div> </div>
</div> </div>

View File

@@ -8,6 +8,7 @@
import { getFormContext } from './FormProviderCore.svelte'; import { getFormContext } from './FormProviderCore.svelte';
import FormSelectField from './FormSelectField.svelte'; import FormSelectField from './FormSelectField.svelte';
import { _t } from '../translations';
export let additionalFolders = []; export let additionalFolders = [];
export let name; export let name;
@@ -35,7 +36,7 @@
label: folder, label: folder,
})), })),
allowCreateNew && { allowCreateNew && {
label: '(Create new)', label: _t('archiveFolder.createNew', { defaultMessage: '(Create new)' }),
value: '@create', value: '@create',
}, },
]; ];
@@ -48,8 +49,8 @@
function handleChange(e) { function handleChange(e) {
if (e.detail == '@create') { if (e.detail == '@create') {
showModal(InputTextModal, { showModal(InputTextModal, {
header: 'Archive', header: _t('archiveFolder.archive', { defaultMessage: 'Archive' }),
label: 'Name of new archive folder', label: _t('archiveFolder.nameOfNewArchiveFolder', { defaultMessage: 'Name of new archive folder' }),
onConfirm: createOption, onConfirm: createOption,
}); });
} }

View File

@@ -11,6 +11,7 @@
import { showModal } from '../modals/modalTools'; import { showModal } from '../modals/modalTools';
import InputTextModal from '../modals/InputTextModal.svelte'; import InputTextModal from '../modals/InputTextModal.svelte';
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { _t } from '../translations';
export let value = ''; export let value = '';
export let conid; export let conid;
@@ -33,8 +34,8 @@
async function handleAddNewApplication() { async function handleAddNewApplication() {
showModal(InputTextModal, { showModal(InputTextModal, {
header: 'New application', header: _t('database.newApplication', { defaultMessage: 'New application' }),
label: 'Application name', label: _t('database.applicationName', { defaultMessage: 'Application name' }),
value: _.startCase(database), value: _.startCase(database),
onConfirm: async appName => { onConfirm: async appName => {
const newAppId = await apiCall('apps/create-app-from-db', { const newAppId = await apiCall('apps/create-app-from-db', {

View File

@@ -114,8 +114,8 @@
value={_t('importExport.newArchive', { defaultMessage: "New archive" })} value={_t('importExport.newArchive', { defaultMessage: "New archive" })}
on:click={() => { on:click={() => {
showModal(InputTextModal, { showModal(InputTextModal, {
header: 'Archive', header: _t('importExport.archive', { defaultMessage: 'Archive' }),
label: 'Name of new archive folder', label: _t('importExport.nameOfNewArchiveFolder', { defaultMessage: 'Name of new archive folder' }),
value: `import-${moment().format('YYYY-MM-DD-hh-mm-ss')}`, value: `import-${moment().format('YYYY-MM-DD-hh-mm-ss')}`,
onConfirm: value => { onConfirm: value => {
values.update(x => ({ values.update(x => ({

View File

@@ -102,7 +102,7 @@
{ {
icon: 'icon compare', icon: 'icon compare',
colorClass: 'color-icon-red', 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' }), description: _t('newObject.compareDescription', { defaultMessage: 'Compare database schemas' }),
command: 'database.compare', command: 'database.compare',
testid: 'NewObjectModal_databaseCompare', testid: 'NewObjectModal_databaseCompare',

View File

@@ -172,11 +172,11 @@
const resp = await apiCall('database-connections/run-script', { conid, database, sql, useTransaction: true }); const resp = await apiCall('database-connections/run-script', { conid, database, sql, useTransaction: true });
const { errorMessage } = resp || {}; const { errorMessage } = resp || {};
if (errorMessage) { if (errorMessage) {
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage }); showModal(ErrorMessageModal, { title: _t('tableData.errorWhenSaving', { defaultMessage: 'Error when saving' }), message: errorMessage });
} else { } else {
dispatchChangeSet({ type: 'reset', value: createChangeSet() }); dispatchChangeSet({ type: 'reset', value: createChangeSet() });
cache.update(reloadDataCacheFunc); cache.update(reloadDataCacheFunc);
showSnackbarSuccess('Saved to database'); showSnackbarSuccess(_t('tableData.savedToDatabase', { defaultMessage: 'Saved to database' }));
} }
} }
@@ -192,11 +192,11 @@
}); });
const { errorMessage } = resp || {}; const { errorMessage } = resp || {};
if (errorMessage) { if (errorMessage) {
showModal(ErrorMessageModal, { title: 'Error when saving', message: errorMessage }); showModal(ErrorMessageModal, { title: _t('tableData.errorWhenSaving', { defaultMessage: 'Error when saving' }), message: errorMessage });
} else { } else {
dispatchChangeSet({ type: 'reset', value: createChangeSet() }); dispatchChangeSet({ type: 'reset', value: createChangeSet() });
cache.update(reloadDataCacheFunc); cache.update(reloadDataCacheFunc);
showSnackbarSuccess('Saved to database'); showSnackbarSuccess(_t('tableData.savedToDatabase', { defaultMessage: 'Saved to database' }));
} }
} else { } else {
const script = driver.createSaveChangeSetScript($changeSetStore?.value, $dbinfo, () => const script = driver.createSaveChangeSetScript($changeSetStore?.value, $dbinfo, () =>
@@ -360,13 +360,13 @@
> >
<ToolStripCommandSplitButton <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()]} commands={['dataGrid.refresh', ...createAutoRefreshMenu()]}
hideDisabled hideDisabled
data-testid="TableDataTab_refreshGrid" data-testid="TableDataTab_refreshGrid"
/> />
<ToolStripCommandSplitButton <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()]} commands={['dataForm.refresh', ...createAutoRefreshMenu()]}
hideDisabled hideDisabled
data-testid="TableDataTab_refreshForm" data-testid="TableDataTab_refreshForm"

View File

@@ -6,6 +6,7 @@ import { getExtensions } from '../stores';
import { getConnectionInfo, getDatabaseInfo } from './metadataLoaders'; import { getConnectionInfo, getDatabaseInfo } from './metadataLoaders';
import ConfirmSqlModal, { saveScriptToDatabase } from '../modals/ConfirmSqlModal.svelte'; import ConfirmSqlModal, { saveScriptToDatabase } from '../modals/ConfirmSqlModal.svelte';
import { apiCall } from './api'; import { apiCall } from './api';
import { _t } from '../translations';
export async function alterDatabaseDialog(conid, database, updateFunc) { export async function alterDatabaseDialog(conid, database, updateFunc) {
const conn = await getConnectionInfo({ conid }); const conn = await getConnectionInfo({ conid });
@@ -30,8 +31,8 @@ export async function alterDatabaseDialog(conid, database, updateFunc) {
export async function renameDatabaseObjectDialog(conid, database, oldName, updateFunc) { export async function renameDatabaseObjectDialog(conid, database, oldName, updateFunc) {
showModal(InputTextModal, { showModal(InputTextModal, {
value: oldName, value: oldName,
label: 'New name', label: _t('renameDatabaseObject.newName', { defaultMessage: 'New name' }),
header: 'Rename object', header: _t('renameDatabaseObject.header', { defaultMessage: 'Rename object' }),
onConfirm: newName => { onConfirm: newName => {
alterDatabaseDialog(conid, database, db => updateFunc(db, newName)); alterDatabaseDialog(conid, database, db => updateFunc(db, newName));
}, },

View File

@@ -161,8 +161,8 @@
const handleRename = () => { const handleRename = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: folder, value: folder,
label: 'New folder name', label: _t('connection.newFolderName', { defaultMessage: 'New folder name' }),
header: 'Rename folder', header: _t('connection.renameFolder', { defaultMessage: 'Rename folder' }),
onConfirm: async newFolder => { onConfirm: async newFolder => {
emptyConnectionGroupNames.update(folders => _.uniq(folders.map(fld => (fld == folder ? newFolder : fld)))); emptyConnectionGroupNames.update(folders => _.uniq(folders.map(fld => (fld == folder ? newFolder : fld))));
apiCall('connections/batch-change-folder', { apiCall('connections/batch-change-folder', {
@@ -175,7 +175,7 @@
const handleDelete = () => { const handleDelete = () => {
showModal(ConfirmModal, { 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: () => { onConfirm: () => {
emptyConnectionGroupNames.update(folders => folders.filter(fld => fld != folder)); emptyConnectionGroupNames.update(folders => folders.filter(fld => fld != folder));
apiCall('connections/batch-change-folder', { apiCall('connections/batch-change-folder', {
@@ -187,8 +187,8 @@
}; };
return [ return [
{ text: 'Rename', onClick: handleRename }, { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
{ text: 'Delete', onClick: handleDelete }, { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
]; ];
} }

View File

@@ -19,6 +19,7 @@
import _ from 'lodash'; import _ from 'lodash';
import openNewTab from '../utility/openNewTab'; import openNewTab from '../utility/openNewTab';
import { showSnackbarError } from '../utility/snackbar'; import { showSnackbarError } from '../utility/snackbar';
import { _t } from '../translations';
import DbKeysSubTree from './DbKeysSubTree.svelte'; import DbKeysSubTree from './DbKeysSubTree.svelte';
@@ -43,10 +44,10 @@
return [ return [
item.key != null && item.key != null &&
!connection?.isReadOnly && { !connection?.isReadOnly && {
label: 'Delete key', label: _t('dbKeysTreeNode.deleteKey', { defaultMessage: 'Delete key' }),
onClick: () => { onClick: () => {
showModal(ConfirmModal, { showModal(ConfirmModal, {
message: `Really delete key ${item.key}?`, message: _t('dbKeysTreeNode.deleteKeyConfirm', { defaultMessage: 'Really delete key {key}?', values: { key: item.key } }),
onConfirm: async () => { onConfirm: async () => {
await apiCall('database-connections/call-method', { await apiCall('database-connections/call-method', {
conid, conid,
@@ -62,12 +63,12 @@
}, },
item.key != null && item.key != null &&
!connection?.isReadOnly && { !connection?.isReadOnly && {
label: 'Rename key', label: _t('dbKeysTreeNode.renameKey', { defaultMessage: 'Rename key' }),
onClick: () => { onClick: () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: item.key, value: item.key,
label: 'New name', label: _t('dbKeysTreeNode.newName', { defaultMessage: 'New name' }),
header: 'Rename key', header: _t('dbKeysTreeNode.renameKey', { defaultMessage: 'Rename key' }),
onConfirm: async newName => { onConfirm: async newName => {
await apiCall('database-connections/call-method', { await apiCall('database-connections/call-method', {
conid, conid,
@@ -90,11 +91,11 @@
// }, // },
item.type == 'dir' && item.type == 'dir' &&
!connection?.isReadOnly && { !connection?.isReadOnly && {
label: 'Delete branch', label: _t('dbKeysTreeNode.deleteBranch', { defaultMessage: 'Delete branch' }),
onClick: () => { onClick: () => {
const branch = `${item.key}:*`; const branch = `${item.key}:*`;
showModal(ConfirmModal, { 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 () => { onConfirm: async () => {
await apiCall('database-connections/call-method', { await apiCall('database-connections/call-method', {
conid, conid,
@@ -110,7 +111,7 @@
}, },
, ,
{ {
label: 'Generate script', label: _t('dbKeysTreeNode.generateScript', { defaultMessage: 'Generate script' }),
onClick: async () => { onClick: async () => {
const data = await apiCall('database-connections/export-keys', { const data = await apiCall('database-connections/export-keys', {
conid, conid,
@@ -126,7 +127,7 @@
} }
newQuery({ newQuery({
title: 'Export #', title: _t('dbKeysTreeNode.exportTitle', { defaultMessage: 'Export #' }),
initialData: data, initialData: data,
}); });
}, },
@@ -137,7 +138,7 @@
<AppObjectCore <AppObjectCore
icon={getIconForRedisType(item.type)} 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'} expandIcon={item.type == 'dir' ? plusExpandIcon(isExpanded) : 'icon invisible-box'}
on:expand={() => { on:expand={() => {
if (item.type == 'dir') { if (item.type == 'dir') {
@@ -150,7 +151,7 @@
} else { } else {
openNewTab({ openNewTab({
tabComponent: 'DbKeyDetailTab', tabComponent: 'DbKeyDetailTab',
title: item.text || '(no name)', title: item.text || _t('dbKeysTreeNode.noName', { defaultMessage: '(no name)' }),
icon: 'img keydb', icon: 'img keydb',
props: { props: {
isDefaultBrowser: true, isDefaultBrowser: true,

View File

@@ -115,7 +115,7 @@
command: 'new.connectionOnCloud', command: 'new.connectionOnCloud',
}, },
{ {
text: 'New SQL script', text: _t('privateCloudWidget.newSqlScript', { defaultMessage: 'New SQL script' }),
onClick: () => { onClick: () => {
const data = ''; const data = '';
showModal(SaveFileModal, { showModal(SaveFileModal, {
@@ -145,11 +145,11 @@
function createAddFolderMenu() { function createAddFolderMenu() {
return [ return [
isProApp() && { isProApp() && {
text: 'Create shared folder', text: _t('privateCloudWidget.createSharedFolder', { defaultMessage: 'Create shared folder' }),
onClick: () => { onClick: () => {
showModal(InputTextModal, { showModal(InputTextModal, {
label: 'New folder name', label: _t('privateCloudWidget.newFolderName', { defaultMessage: 'New folder name' }),
header: 'New shared folder', header: _t('privateCloudWidget.newSharedFolder', { defaultMessage: 'New shared folder' }),
onConfirm: async newFolder => { onConfirm: async newFolder => {
apiCall('cloud/create-folder', { apiCall('cloud/create-folder', {
name: newFolder, name: newFolder,
@@ -159,11 +159,11 @@
}, },
}, },
{ {
text: 'Add existing folder (from link)', text: _t('privateCloudWidget.addExistingFolder', { defaultMessage: 'Add existing folder (from link)' }),
onClick: () => { onClick: () => {
showModal(InputTextModal, { showModal(InputTextModal, {
label: 'Your invite link (in form dbgate://folder/xxx)', label: _t('privateCloudWidget.yourInviteLink', { defaultMessage: 'Your invite link (in form dbgate://folder/xxx)' }),
header: 'Add existing shared folder', header: _t('privateCloudWidget.addExistingSharedFolder', { defaultMessage: 'Add existing shared folder' }),
onConfirm: async newFolder => { onConfirm: async newFolder => {
apiCall('cloud/grant-folder', { apiCall('cloud/grant-folder', {
inviteLink: newFolder, inviteLink: newFolder,
@@ -179,8 +179,8 @@
const handleRename = () => { const handleRename = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: contentGroupMap[folder]?.name, value: contentGroupMap[folder]?.name,
label: 'New folder name', label: _t('privateCloudWidget.newFolderName', { defaultMessage: 'New folder name' }),
header: 'Rename folder', header: _t('privateCloudWidget.renameFolder', { defaultMessage: 'Rename folder' }),
onConfirm: async name => { onConfirm: async name => {
apiCall('cloud/rename-folder', { apiCall('cloud/rename-folder', {
folid: folder, folid: folder,
@@ -192,8 +192,8 @@
const handleDelete = () => { const handleDelete = () => {
showModal(ConfirmModal, { showModal(ConfirmModal, {
message: `Really delete folder ${contentGroupMap[folder]?.name}? All folder content will be deleted!`, message: _t('privateCloudWidget.deleteFolderConfirm', { defaultMessage: 'Really delete folder {folder}? All folder content will be deleted!', values: { folder: contentGroupMap[folder]?.name } }),
header: 'Delete folder', header: _t('privateCloudWidget.deleteFolder', { defaultMessage: 'Delete folder' }),
onConfirm: () => { onConfirm: () => {
apiCall('cloud/delete-folder', { apiCall('cloud/delete-folder', {
folid: folder, folid: folder,
@@ -204,13 +204,13 @@
return [ return [
contentGroupMap[folder]?.role == 'admin' && [ contentGroupMap[folder]?.role == 'admin' && [
{ text: 'Rename', onClick: handleRename }, { text: _t('common.rename', { defaultMessage: 'Rename' }), onClick: handleRename },
{ text: 'Delete', onClick: handleDelete }, { text: _t('common.delete', { defaultMessage: 'Delete' }), onClick: handleDelete },
], ],
isProApp() && isProApp() &&
contentGroupMap[folder]?.role == 'admin' && contentGroupMap[folder]?.role == 'admin' &&
!contentGroupMap[folder]?.isPrivate && { !contentGroupMap[folder]?.isPrivate && {
text: 'Administrate access', text: _t('privateCloudWidget.administrateAccess', { defaultMessage: 'Administrate access' }),
onClick: () => { onClick: () => {
showModal(ConfigureSharedFolderModal, { showModal(ConfigureSharedFolderModal, {
folid: folder, folid: folder,
@@ -249,13 +249,13 @@
skip={!$cloudSigninTokenHolder} skip={!$cloudSigninTokenHolder}
> >
<SearchBoxWrapper> <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 /> <CloseSearchButton bind:filter />
<DropDownButton icon="icon plus-thick" menu={createAddItemMenu} title="Add new connection or file" /> <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="Add new folder" /> <DropDownButton icon="icon add-folder" menu={createAddFolderMenu} title={_t('privateCloudWidget.addNewFolder', { defaultMessage: 'Add new folder' })} />
<InlineButton <InlineButton
on:click={handleRefreshContent} on:click={handleRefreshContent}
title="Refresh files" title={_t('privateCloudWidget.refreshFiles', { defaultMessage: 'Refresh files' })}
data-testid="CloudItemsWidget_buttonRefreshContent" data-testid="CloudItemsWidget_buttonRefreshContent"
> >
<FontIcon icon="icon refresh" /> <FontIcon icon="icon refresh" />
@@ -289,11 +289,11 @@
/> />
{#if !cloudContentFlat?.length} {#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="error-info">
<div class="m-1"></div> <div class="m-1"></div>
<FormStyledButton <FormStyledButton
value="Create connection on DbGate Cloud" value={_t('privateCloudWidget.createConnection', { defaultMessage: 'Create connection on DbGate Cloud' })}
skipWidth skipWidth
on:click={() => { on:click={() => {
runCommand('new.connectionOnCloud'); runCommand('new.connectionOnCloud');