Merge pull request #1272 from dbgate/feature/translation4

Feature/translation4
This commit is contained in:
Jan Prochazka
2025-11-26 14:12:14 +01:00
committed by GitHub
20 changed files with 125 additions and 109 deletions

View File

@@ -5,6 +5,7 @@
import getElectron from '../utility/getElectron'; import getElectron from '../utility/getElectron';
import InlineButtonLabel from '../buttons/InlineButtonLabel.svelte'; import InlineButtonLabel from '../buttons/InlineButtonLabel.svelte';
import resolveApi, { resolveApiHeaders } from '../utility/resolveApi'; import resolveApi, { resolveApiHeaders } from '../utility/resolveApi';
import { _t } from '../translations';
import uuidv1 from 'uuid/v1'; import uuidv1 from 'uuid/v1';
@@ -49,11 +50,11 @@
</script> </script>
{#if electron} {#if electron}
<InlineButton on:click={handleOpenElectronFile} title="Open file" data-testid={$$props['data-testid']}> <InlineButton on:click={handleOpenElectronFile} title={_t('files.openFile', { defaultMessage: "Open file" })} data-testid={$$props['data-testid']}>
<FontIcon {icon} /> <FontIcon {icon} />
</InlineButton> </InlineButton>
{:else} {:else}
<InlineButtonLabel on:click={() => {}} title="Upload file" data-testid={$$props['data-testid']} htmlFor={inputId}> <InlineButtonLabel on:click={() => {}} title={_t('files.uploadFile', { defaultMessage: "Upload file" })} data-testid={$$props['data-testid']} htmlFor={inputId}>
<FontIcon {icon} /> <FontIcon {icon} />
</InlineButtonLabel> </InlineButtonLabel>
{/if} {/if}

View File

@@ -1,6 +1,7 @@
<script lang="ts"> <script lang="ts">
import FormStyledButtonLikeLabel from '../buttons/FormStyledButtonLikeLabel.svelte'; import FormStyledButtonLikeLabel from '../buttons/FormStyledButtonLikeLabel.svelte';
import uploadFiles from '../utility/uploadFiles'; import uploadFiles from '../utility/uploadFiles';
import { _t } from '../translations';
const handleChange = e => { const handleChange = e => {
const files = [...e.target.files]; const files = [...e.target.files];
@@ -9,6 +10,6 @@
</script> </script>
<div class="m-1"> <div class="m-1">
<FormStyledButtonLikeLabel htmlFor="uploadFileButton">Upload file</FormStyledButtonLikeLabel> <FormStyledButtonLikeLabel htmlFor="uploadFileButton">{_t('files.uploadFile', { defaultMessage: "Upload file" })}</FormStyledButtonLikeLabel>
<input type="file" id="uploadFileButton" hidden on:change={handleChange} /> <input type="file" id="uploadFileButton" hidden on:change={handleChange} />
</div> </div>

View File

@@ -121,7 +121,7 @@ registerCommand({
testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase, testEnabled: () => !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase,
onClick: () => { onClick: () => {
openNewTab({ openNewTab({
title: 'New Connection', title: _t('common.newConnection', { defaultMessage: 'New Connection' }),
icon: 'img connection', icon: 'img connection',
tabComponent: 'ConnectionTab', tabComponent: 'ConnectionTab',
}); });
@@ -140,7 +140,7 @@ registerCommand({
!getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase && !!getCloudSigninTokenHolder(), !getCurrentConfig()?.runAsPortal && !getCurrentConfig()?.storageDatabase && !!getCloudSigninTokenHolder(),
onClick: () => { onClick: () => {
openNewTab({ openNewTab({
title: 'New Connection on Cloud', title: _t('common.newConnectionCloud', { defaultMessage: 'New Connection on Cloud' }),
icon: 'img cloud-connection', icon: 'img cloud-connection',
tabComponent: 'ConnectionTab', tabComponent: 'ConnectionTab',
props: { props: {

View File

@@ -17,6 +17,7 @@
import moveDrag from '../utility/moveDrag'; import moveDrag from '../utility/moveDrag';
import ColumnLine from './ColumnLine.svelte'; import ColumnLine from './ColumnLine.svelte';
import DomTableRef from './DomTableRef'; import DomTableRef from './DomTableRef';
import { _t } from '../translations';
export let conid; export let conid;
export let database; export let database;
@@ -185,8 +186,8 @@
const handleSetTableAlias = () => { const handleSetTableAlias = () => {
showModal(InputTextModal, { showModal(InputTextModal, {
value: alias || '', value: alias || '',
label: 'New alias', label: _t('designerTable.newAlias', { defaultMessage: 'New alias' }),
header: 'Set table alias', header: _t('designerTable.setTableAlias', { defaultMessage: 'Set table alias' }),
onConfirm: newAlias => { onConfirm: newAlias => {
onChangeTable({ onChangeTable({
...table, ...table,
@@ -210,13 +211,13 @@
return settings?.tableMenu({ designer, designerId, onRemoveTable }); return settings?.tableMenu({ designer, designerId, onRemoveTable });
} }
return [ return [
{ text: 'Remove', onClick: () => onRemoveTable({ designerId }) }, { text: _t('common.remove', { defaultMessage: 'Remove' }), onClick: () => onRemoveTable({ designerId }) },
{ divider: true }, { divider: true },
settings?.allowTableAlias && settings?.allowTableAlias &&
!isMultipleTableSelection && [ !isMultipleTableSelection && [
{ text: 'Set table alias', onClick: handleSetTableAlias }, { text: _t('designerTable.setTableAlias', { defaultMessage: 'Set table alias' }), onClick: handleSetTableAlias },
alias && { alias && {
text: 'Remove table alias', text: _t('designerTable.removeTableAlias', { defaultMessage: 'Remove table alias' }),
onClick: () => onClick: () =>
onChangeTable({ onChangeTable({
...table, ...table,
@@ -225,11 +226,11 @@
}, },
], ],
settings?.allowAddAllReferences && settings?.allowAddAllReferences &&
!isMultipleTableSelection && { text: 'Add references', onClick: () => onAddAllReferences(table) }, !isMultipleTableSelection && { text: _t('designerTable.addReferences', { defaultMessage: 'Add references' }), onClick: () => onAddAllReferences(table) },
settings?.allowChangeColor && { text: 'Change color', onClick: () => onChangeTableColor(table) }, settings?.allowChangeColor && { text: _t('designerTable.changeColor', { defaultMessage: 'Change color' }), onClick: () => onChangeTableColor(table) },
settings?.allowDefineVirtualReferences && settings?.allowDefineVirtualReferences &&
!isMultipleTableSelection && { !isMultipleTableSelection && {
text: 'Define virtual foreign key', text: _t('designerTable.defineVirtualForeignKey', { defaultMessage: 'Define virtual foreign key' }),
onClick: () => handleDefineVirtualForeignKey(table), onClick: () => handleDefineVirtualForeignKey(table),
}, },
settings?.appendTableSystemMenu && settings?.appendTableSystemMenu &&

View File

@@ -7,6 +7,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 folderName; export let folderName;
export let name; export let name;
@@ -28,10 +29,10 @@
<div> <div>
<FormStyledButton <FormStyledButton
type="button" type="button"
value="All files" value={_t('common.allFiles', { defaultMessage: "All files" })}
on:click={() => setFieldValue(name, _.uniq([...($values[name] || []), ...($files && $files.map(x => x.name))]))} on:click={() => setFieldValue(name, _.uniq([...($values[name] || []), ...($files && $files.map(x => x.name))]))}
/> />
<FormStyledButton type="button" value="Remove all" on:click={() => setFieldValue(name, [])} /> <FormStyledButton type="button" value={_t('common.removeAll', { defaultMessage: "Remove all" })} on:click={() => setFieldValue(name, [])} />
</div> </div>
</div> </div>

View File

@@ -23,6 +23,7 @@
import ElectronFilesInput from './ElectronFilesInput.svelte'; import ElectronFilesInput from './ElectronFilesInput.svelte';
import { addFilesToSourceList } from './ImportExportConfigurator.svelte'; import { addFilesToSourceList } from './ImportExportConfigurator.svelte';
import UploadButton from '../buttons/UploadButton.svelte'; import UploadButton from '../buttons/UploadButton.svelte';
import { _t } from '../translations';
export let setPreviewSource = undefined; export let setPreviewSource = undefined;
@@ -55,10 +56,10 @@
{:else} {:else}
<UploadButton /> <UploadButton />
{/if} {/if}
<FormStyledButton value="Add web URL" on:click={handleAddUrl} /> <FormStyledButton value={_t('importExport.addWebUrl', { defaultMessage: "Add web URL" })} on:click={handleAddUrl} />
</div> </div>
<div class="wrapper">Drag &amp; drop imported files here</div> <div class="wrapper">{_t('importExport.dragDropImportedFilesHere', { defaultMessage: "Drag & drop imported files here" })}</div>
</div> </div>
<style> <style>

View File

@@ -6,6 +6,7 @@
import { getFormContext } from '../forms/FormProviderCore.svelte'; import { getFormContext } from '../forms/FormProviderCore.svelte';
import FormSelectField from '../forms/FormSelectField.svelte'; import FormSelectField from '../forms/FormSelectField.svelte';
import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders'; import { useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders';
import { _t } from '../translations';
export let conidName; export let conidName;
export let databaseName; export let databaseName;
@@ -41,7 +42,7 @@
{#if $dbinfo && $dbinfo[field]?.length > 0} {#if $dbinfo && $dbinfo[field]?.length > 0}
<FormStyledButton <FormStyledButton
type="button" type="button"
value={`All ${field}`} value={_t('common.allFields', { defaultMessage: 'All {field}', values: { field } })}
data-testid={`FormTablesSelect_buttonAll_${field}`} data-testid={`FormTablesSelect_buttonAll_${field}`}
on:click={() => on:click={() =>
setFieldValue( setFieldValue(
@@ -52,7 +53,7 @@
{/if} {/if}
{/each} {/each}
<FormStyledButton type="button" value="Remove all" on:click={() => setFieldValue(name, [])} /> <FormStyledButton type="button" value={_t('common.removeAll', { defaultMessage: "Remove all" })} on:click={() => setFieldValue(name, [])} />
</div> </div>
</div> </div>

View File

@@ -77,6 +77,7 @@
import createRef from '../utility/createRef'; import createRef from '../utility/createRef';
import DropDownButton from '../buttons/DropDownButton.svelte'; import DropDownButton from '../buttons/DropDownButton.svelte';
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte'; import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
import { _t } from '../translations';
// export let uploadedFile = undefined; // export let uploadedFile = undefined;
// export let openedFile = undefined; // export let openedFile = undefined;
@@ -211,7 +212,7 @@
</div> </div>
<div class="m-2"> <div class="m-2">
<div class="title"><FontIcon icon="icon tables" /> Map source tables/files</div> <div class="title"><FontIcon icon="icon tables" /> {_t('importExport.mapSourceTablesFiles', { defaultMessage: "Map source tables/files" })}</div>
{#key targetEditKey} {#key targetEditKey}
{#key progressHolder} {#key progressHolder}
@@ -220,34 +221,34 @@
columns={[ columns={[
{ {
fieldName: 'source', fieldName: 'source',
header: 'Source', header: _t('importExport.source', { defaultMessage: "Source" }),
component: SourceName, component: SourceName,
getProps: row => ({ name: row }), getProps: row => ({ name: row }),
}, },
{ {
fieldName: 'action', fieldName: 'action',
header: 'Action', header: _t('importExport.action', { defaultMessage: "Action" }),
component: SourceAction, component: SourceAction,
getProps: row => ({ name: row, targetDbinfo }), getProps: row => ({ name: row, targetDbinfo }),
}, },
{ {
fieldName: 'target', fieldName: 'target',
header: 'Target', header: _t('importExport.target', { defaultMessage: "Target" }),
slot: 1, slot: 1,
}, },
supportsPreview && { supportsPreview && {
fieldName: 'preview', fieldName: 'preview',
header: 'Preview', header: _t('importExport.preview', { defaultMessage: "Preview" }),
slot: 0, slot: 0,
}, },
!!progressHolder && { !!progressHolder && {
fieldName: 'status', fieldName: 'status',
header: 'Status', header: _t('importExport.status', { defaultMessage: "Status" }),
slot: 3, slot: 3,
}, },
{ {
fieldName: 'columns', fieldName: 'columns',
header: 'Columns', header: _t('importExport.columns', { defaultMessage: "Columns" }),
slot: 2, slot: 2,
}, },
]} ]}

View File

@@ -73,19 +73,19 @@
<div class="column"> <div class="column">
{#if direction == 'source'} {#if direction == 'source'}
<div class="title"> <div class="title">
<FontIcon icon="icon import" /> Source configuration <FontIcon icon="icon import" /> {_t('importExport.sourceConfiguration', { defaultMessage: 'Source configuration' })}
</div> </div>
{/if} {/if}
{#if direction == 'target'} {#if direction == 'target'}
<div class="title"> <div class="title">
<FontIcon icon="icon export" /> Target configuration <FontIcon icon="icon export" /> {_t('importExport.targetConfiguration', { defaultMessage: 'Target configuration' })}
</div> </div>
{/if} {/if}
<div class="buttons"> <div class="buttons">
{#if $currentDatabase} {#if $currentDatabase}
<FormStyledButton <FormStyledButton
value="Current DB" value={_t('importExport.currentDatabase', { defaultMessage: "Current DB" })}
on:click={() => { on:click={() => {
values.update(x => ({ values.update(x => ({
...x, ...x,
@@ -97,7 +97,7 @@
/> />
{/if} {/if}
<FormStyledButton <FormStyledButton
value="Current archive" value={_t('importExport.currentArchive', { defaultMessage: "Current archive" })}
data-testid={direction == 'source' data-testid={direction == 'source'
? 'SourceTargetConfig_buttonCurrentArchive_source' ? 'SourceTargetConfig_buttonCurrentArchive_source'
: 'SourceTargetConfig_buttonCurrentArchive_target'} : 'SourceTargetConfig_buttonCurrentArchive_target'}
@@ -111,7 +111,7 @@
/> />
{#if direction == 'target'} {#if direction == 'target'}
<FormStyledButton <FormStyledButton
value="New archive" value={_t('importExport.newArchive', { defaultMessage: "New archive" })}
on:click={() => { on:click={() => {
showModal(InputTextModal, { showModal(InputTextModal, {
header: 'Archive', header: 'Archive',
@@ -133,7 +133,7 @@
<FormSelectField <FormSelectField
options={types.filter(x => x.directions.includes(direction))} options={types.filter(x => x.directions.includes(direction))}
name={storageTypeField} name={storageTypeField}
label="Storage type" label={_t('importExport.storageType', { defaultMessage: "Storage type" })}
/> />
{#if format && isProApp()} {#if format && isProApp()}
@@ -172,9 +172,9 @@
{/if} {/if}
{#if storageType == 'database' || storageType == 'query'} {#if storageType == 'database' || storageType == 'query'}
<FormConnectionSelect name={connectionIdField} label="Server" {direction} /> <FormConnectionSelect name={connectionIdField} label={_t('common.server', { defaultMessage: 'Server' })} {direction} />
{#if !$connectionInfo?.singleDatabase} {#if !$connectionInfo?.singleDatabase}
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} label="Database" /> <FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} label={_t('common.database', { defaultMessage: 'Database' })} />
{/if} {/if}
{/if} {/if}
{#if storageType == 'database'} {#if storageType == 'database'}
@@ -210,7 +210,7 @@
{#if storageType == 'archive'} {#if storageType == 'archive'}
<FormArchiveFolderSelect <FormArchiveFolderSelect
label="Archive folder" label={_t('importExport.archiveFolder', { defaultMessage: "Archive folder" })}
name={archiveFolderField} name={archiveFolderField}
additionalFolders={_.compact([$values[archiveFolderField]])} additionalFolders={_.compact([$values[archiveFolderField]])}
allowCreateNew={direction == 'target'} allowCreateNew={direction == 'target'}

View File

@@ -8,6 +8,7 @@
import WidgetsInnerContainer from '../widgets/WidgetsInnerContainer.svelte'; import WidgetsInnerContainer from '../widgets/WidgetsInnerContainer.svelte';
import PluginsList from './PluginsList.svelte'; import PluginsList from './PluginsList.svelte';
import { filterName } from 'dbgate-tools'; import { filterName } from 'dbgate-tools';
import { _t } from '../translations';
let filter = ''; let filter = '';
// let search = ''; // let search = '';
@@ -20,7 +21,7 @@
</script> </script>
<SearchBoxWrapper> <SearchBoxWrapper>
<SearchInput placeholder="Search extensions on web" {filter} bind:value={filter} /> <SearchInput placeholder={_t('plugins.searchExtensionsOnWeb', { defaultMessage: 'Search extensions on web' })} {filter} bind:value={filter} />
</SearchBoxWrapper> </SearchBoxWrapper>
<WidgetsInnerContainer> <WidgetsInnerContainer>
{#if $plugins?.errorMessage} {#if $plugins?.errorMessage}

View File

@@ -24,6 +24,7 @@
createQuickExportHandlerRef, createQuickExportHandlerRef,
registerQuickExportHandler, registerQuickExportHandler,
} from '../buttons/ToolStripExportButton.svelte'; } from '../buttons/ToolStripExportButton.svelte';
import { _t } from '../translations';
let loadedRows = []; let loadedRows = [];
let loadedAll = false; let loadedAll = false;
@@ -191,8 +192,8 @@
<SelectField <SelectField
isNative isNative
options={[ options={[
{ label: 'Recent logs', value: 'recent' }, { label: _t('logs.recentLogs', { defaultMessage: 'Recent logs' }), value: 'recent' },
{ label: 'Choose date', value: 'date' }, { label: _t('logs.chooseDate', { defaultMessage: 'Choose date' }), value: 'date' },
]} ]}
value={mode} value={mode}
on:change={e => { on:change={e => {
@@ -202,7 +203,7 @@
/> />
{#if mode === 'recent'} {#if mode === 'recent'}
<div class="filter-label ml-2">Auto-scroll</div> <div class="filter-label ml-2">{_t('logs.autoScroll', { defaultMessage: 'Auto-scroll' })}</div>
<input <input
type="checkbox" type="checkbox"
checked={autoScroll} checked={autoScroll}
@@ -213,7 +214,7 @@
{/if} {/if}
{#if mode === 'date'} {#if mode === 'date'}
<div class="filter-label">Date:</div> <div class="filter-label">{_t('logs.date', { defaultMessage: 'Date:' })}</div>
<DateRangeSelector <DateRangeSelector
onChange={value => { onChange={value => {
dateFilter = value; dateFilter = value;
@@ -225,12 +226,12 @@
data-testid="AdminAuditLogTab_addFilter" data-testid="AdminAuditLogTab_addFilter"
icon="icon filter" icon="icon filter"
menu={[ menu={[
{ text: 'Connection ID', onClick: () => filterBy('conid') }, { text: _t('logs.connectionId', { defaultMessage: 'Connection ID' }), onClick: () => filterBy('conid') },
{ text: 'Database', onClick: () => filterBy('database') }, { text: _t('logs.database', { defaultMessage: 'Database' }), onClick: () => filterBy('database') },
{ text: 'Engine', onClick: () => filterBy('engine') }, { text: _t('logs.engine', { defaultMessage: 'Engine' }), onClick: () => filterBy('engine') },
{ text: 'Message code', onClick: () => filterBy('msgcode') }, { text: _t('logs.messageCode', { defaultMessage: 'Message code' }), onClick: () => filterBy('msgcode') },
{ text: 'Caller', onClick: () => filterBy('caller') }, { text: _t('logs.caller', { defaultMessage: 'Caller' }), onClick: () => filterBy('caller') },
{ text: 'Name', onClick: () => filterBy('name') }, { text: _t('logs.name', { defaultMessage: 'Name' }), onClick: () => filterBy('name') },
]} ]}
/> />
</div> </div>
@@ -259,15 +260,15 @@
<table> <table>
<thead> <thead>
<tr> <tr>
<th style="width:80px">Date</th> <th style="width:80px">{_t('logs.dateTab', { defaultMessage: 'Date' })}</th>
<th>Time</th> <th>{_t('logs.timeTab', { defaultMessage: 'Time' })}</th>
<th>Code</th> <th>{_t('logs.codeTab', { defaultMessage: 'Code' })}</th>
<th>Message</th> <th>{_t('logs.messageTab', { defaultMessage: 'Message' })}</th>
<th>Connection</th> <th>{_t('logs.connectionTab', { defaultMessage: 'Connection' })}</th>
<th>Database</th> <th>{_t('logs.databaseTab', { defaultMessage: 'Database' })}</th>
<th>Engine</th> <th>{_t('logs.engineTab', { defaultMessage: 'Engine' })}</th>
<th>Caller</th> <th>{_t('logs.callerTab', { defaultMessage: 'Caller' })}</th>
<th>Name</th> <th>{_t('logs.nameTab', { defaultMessage: 'Name' })}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -299,14 +300,14 @@
<TabControl <TabControl
isInline isInline
tabs={_.compact([ tabs={_.compact([
{ label: 'Details', slot: 1 }, { label: _t('logs.details', { defaultMessage: 'Details' }), slot: 1 },
{ label: 'JSON', slot: 2 }, { label: 'JSON', slot: 2 },
])} ])}
> >
<svelte:fragment slot="1"> <svelte:fragment slot="1">
<div class="details-wrap"> <div class="details-wrap">
<div class="row"> <div class="row">
<div>Message code:</div> <div>{_t('logs.messageCode', { defaultMessage: 'Message code:' })}</div>
{#if mode == 'date'} {#if mode == 'date'}
<Link onClick={() => doSetFilter('msgcode', [row.msgcode])}>{row.msgcode || 'N/A'}</Link> <Link onClick={() => doSetFilter('msgcode', [row.msgcode])}>{row.msgcode || 'N/A'}</Link>
{:else} {:else}
@@ -314,15 +315,15 @@
{/if} {/if}
</div> </div>
<div class="row"> <div class="row">
<div>Message:</div> <div>{_t('logs.message', { defaultMessage: 'Message:' })}</div>
{row.msg} {row.msg}
</div> </div>
<div class="row"> <div class="row">
<div>Time:</div> <div>{_t('logs.time', { defaultMessage: 'Time:' })}</div>
<b>{row.time ? format(new Date(parseInt(row.time)), 'yyyy-MM-dd HH:mm:ss') : ''}</b> <b>{row.time ? format(new Date(parseInt(row.time)), 'yyyy-MM-dd HH:mm:ss') : ''}</b>
</div> </div>
<div class="row"> <div class="row">
<div>Caller:</div> <div>{_t('logs.caller', { defaultMessage: 'Caller:' })}</div>
{#if mode == 'date'} {#if mode == 'date'}
<Link onClick={() => doSetFilter('caller', [row.caller])}>{row.caller || 'N/A'}</Link> <Link onClick={() => doSetFilter('caller', [row.caller])}>{row.caller || 'N/A'}</Link>
{:else} {:else}
@@ -330,7 +331,7 @@
{/if} {/if}
</div> </div>
<div class="row"> <div class="row">
<div>Name:</div> <div>{_t('logs.name', { defaultMessage: 'Name:' })}</div>
{#if mode == 'date'} {#if mode == 'date'}
<Link onClick={() => doSetFilter('name', [row.name])}>{row.name || 'N/A'}</Link> <Link onClick={() => doSetFilter('name', [row.name])}>{row.name || 'N/A'}</Link>
{:else} {:else}
@@ -339,7 +340,7 @@
</div> </div>
{#if row.conid} {#if row.conid}
<div class="row"> <div class="row">
<div>Connection ID:</div> <div>{_t('logs.connectionId', { defaultMessage: 'Connection ID:' })}</div>
{#if mode == 'date'} {#if mode == 'date'}
<Link onClick={() => doSetFilter('conid', [row.conid])} <Link onClick={() => doSetFilter('conid', [row.conid])}
>{formatPossibleUuid(row.conid)}</Link >{formatPossibleUuid(row.conid)}</Link
@@ -351,7 +352,7 @@
{/if} {/if}
{#if row.database} {#if row.database}
<div class="row"> <div class="row">
<div>Database:</div> <div>{_t('logs.database', { defaultMessage: 'Database:' })}</div>
{#if mode == 'date'} {#if mode == 'date'}
<Link onClick={() => doSetFilter('database', [row.database])}>{row.database}</Link> <Link onClick={() => doSetFilter('database', [row.database])}>{row.database}</Link>
{:else} {:else}
@@ -361,7 +362,7 @@
{/if} {/if}
{#if row.engine} {#if row.engine}
<div class="row"> <div class="row">
<div>Engine:</div> <div>{_t('logs.engine', { defaultMessage: 'Engine:' })}</div>
{#if mode == 'date'} {#if mode == 'date'}
<Link onClick={() => doSetFilter('engine', [row.engine])}>{row.engine}</Link> <Link onClick={() => doSetFilter('engine', [row.engine])}>{row.engine}</Link>
{:else} {:else}
@@ -381,13 +382,13 @@
{/each} {/each}
{#if !loadedRows?.length && mode === 'date'} {#if !loadedRows?.length && mode === 'date'}
<tr> <tr>
<td colspan="6">No data for selected date</td> <td colspan="6">{_t('logs.noDataForSelectedDate', { defaultMessage: "No data for selected date" })}</td>
</tr> </tr>
{/if} {/if}
{#if !loadedAll && mode === 'date'} {#if !loadedAll && mode === 'date'}
{#key loadedRows} {#key loadedRows}
<tr> <tr>
<td colspan="6" bind:this={domLoadNext}>Loading next rows... </td> <td colspan="6" bind:this={domLoadNext}>{_t('logs.loadingNextRows', { defaultMessage: "Loading next rows..." })}</td>
</tr> </tr>
{/key} {/key}
{/if} {/if}
@@ -402,7 +403,7 @@
data-testid="AdminAuditLogTab_refreshButton" data-testid="AdminAuditLogTab_refreshButton"
on:click={() => { on:click={() => {
reloadData(); reloadData();
}}>Refresh</ToolStripButton }}>{_t('logs.refresh', { defaultMessage: 'Refresh' })}</ToolStripButton
> >
<ToolStripExportButton {quickExportHandlerRef} /> <ToolStripExportButton {quickExportHandlerRef} />
</svelte:fragment> </svelte:fragment>

View File

@@ -54,6 +54,7 @@
import uuidv1 from 'uuid/v1'; import uuidv1 from 'uuid/v1';
import { tick } from 'svelte'; import { tick } from 'svelte';
import { showSnackbarError } from '../utility/snackbar'; import { showSnackbarError } from '../utility/snackbar';
import { _t } from '../translations';
let busy = false; let busy = false;
let executeNumber = 0; let executeNumber = 0;
@@ -289,21 +290,21 @@
/> />
{#if busy} {#if busy}
<LoadingInfo wrapper message="Processing import/export ..." /> <LoadingInfo wrapper message={_t('importExport.processingImportExport', { defaultMessage: "Processing import/export ..." })} />
{/if} {/if}
</div> </div>
<svelte:fragment slot="2"> <svelte:fragment slot="2">
<WidgetColumnBar> <WidgetColumnBar>
<WidgetColumnBarItem <WidgetColumnBarItem
title="Output files" title={_t('importExport.outputFiles', { defaultMessage: "Output files" })}
name="output" name="output"
height="20%" height="20%"
data-testid="ImportExportTab_outputFiles" data-testid="ImportExportTab_outputFiles"
> >
<RunnerOutputFiles {runnerId} {executeNumber} /> <RunnerOutputFiles {runnerId} {executeNumber} />
</WidgetColumnBarItem> </WidgetColumnBarItem>
<WidgetColumnBarItem title="Messages" name="messages"> <WidgetColumnBarItem title={_t('importExport.messages', { defaultMessage: "Messages" })} name="messages">
<SocketMessageView <SocketMessageView
eventName={runnerId ? `runner-info-${runnerId}` : null} eventName={runnerId ? `runner-info-${runnerId}` : null}
{executeNumber} {executeNumber}
@@ -312,16 +313,16 @@
/> />
</WidgetColumnBarItem> </WidgetColumnBarItem>
<WidgetColumnBarItem <WidgetColumnBarItem
title="Preview" title={_t('importExport.preview', { defaultMessage: "Preview" })}
name="preview" name="preview"
skip={!$previewReaderStore} skip={!$previewReaderStore}
data-testid="ImportExportTab_preview" data-testid="ImportExportTab_preview"
> >
<PreviewDataGrid reader={$previewReaderStore} /> <PreviewDataGrid reader={$previewReaderStore} />
</WidgetColumnBarItem> </WidgetColumnBarItem>
<WidgetColumnBarItem title="Advanced configuration" name="config" collapsed> <WidgetColumnBarItem title={_t('importExport.advancedConfiguration', { defaultMessage: "Advanced configuration" })} name="config" collapsed>
<FormTextField label="Schedule" name="schedule" /> <FormTextField label={_t('importExport.schedule', { defaultMessage: "Schedule" })} name="schedule" />
<FormTextField label="Start variable index" name="startVariableIndex" /> <FormTextField label={_t('importExport.startVariableIndex', { defaultMessage: "Start variable index" })} name="startVariableIndex" />
</WidgetColumnBarItem> </WidgetColumnBarItem>
</WidgetColumnBar> </WidgetColumnBar>
</svelte:fragment> </svelte:fragment>
@@ -330,15 +331,15 @@
<svelte:fragment slot="toolstrip"> <svelte:fragment slot="toolstrip">
{#if busy} {#if busy}
<ToolStripButton icon="icon stop" on:click={handleCancel} data-testid="ImportExportTab_stopButton" <ToolStripButton icon="icon stop" on:click={handleCancel} data-testid="ImportExportTab_stopButton"
>Stop</ToolStripButton >{_t('importExport.stop', { defaultMessage: "Stop" })}</ToolStripButton
> >
{:else} {:else}
<ToolStripButton on:click={handleExecute} icon="icon run" data-testid="ImportExportTab_executeButton" <ToolStripButton on:click={handleExecute} icon="icon run" data-testid="ImportExportTab_executeButton"
>Run</ToolStripButton >{_t('importExport.run', { defaultMessage: "Run" })}</ToolStripButton
> >
{/if} {/if}
<ToolStripButton icon="img shell" on:click={handleGenerateScript} data-testid="ImportExportTab_generateScriptButton" <ToolStripButton icon="img shell" on:click={handleGenerateScript} data-testid="ImportExportTab_generateScriptButton"
>Generate script</ToolStripButton >{_t('importExport.generateScript', { defaultMessage: "Generate script" })}</ToolStripButton
> >
<ToolStripSaveButton idPrefix="impexp" /> <ToolStripSaveButton idPrefix="impexp" />
</svelte:fragment> </svelte:fragment>

View File

@@ -101,6 +101,7 @@
import WidgetTitle from './WidgetTitle.svelte'; import WidgetTitle from './WidgetTitle.svelte';
import JsonExpandedCellView from '../celldata/JsonExpandedCellView.svelte'; import JsonExpandedCellView from '../celldata/JsonExpandedCellView.svelte';
import XmlCellView from '../celldata/XmlCellView.svelte'; import XmlCellView from '../celldata/XmlCellView.svelte';
import { _t } from '../translations';
let selectedFormatType = 'autodetect'; let selectedFormatType = 'autodetect';
@@ -116,7 +117,7 @@
</script> </script>
<div class="wrapper"> <div class="wrapper">
<WidgetTitle>Cell data view</WidgetTitle> <WidgetTitle>{_t('cellDataWidget.title', { defaultMessage: "Cell data view" })}</WidgetTitle>
<div class="main"> <div class="main">
<div class="toolbar"> <div class="toolbar">
Format:<span>&nbsp;</span> Format:<span>&nbsp;</span>
@@ -126,18 +127,18 @@
on:change={e => (selectedFormatType = e.detail)} on:change={e => (selectedFormatType = e.detail)}
data-testid="CellDataWidget_selectFormat" data-testid="CellDataWidget_selectFormat"
options={[ options={[
{ value: 'autodetect', label: `Autodetect - ${autodetectFormat.title}` }, { value: 'autodetect', label: _t('cellDataWidget.autodetect', { defaultMessage: "Autodetect - {autoDetectTitle}", values : { autoDetectTitle: autodetectFormat.title } }) },
...formats.map(fmt => ({ label: fmt.title, value: fmt.type })), ...formats.map(fmt => ({ label: fmt.title, value: fmt.type })),
]} ]}
/> />
</div> </div>
<div class="data"> <div class="data">
{#if usedFormat.single && selection?.length != 1} {#if usedFormat.single && selection?.length != 1}
<ErrorInfo message="Must be selected one cell" alignTop /> <ErrorInfo message={_t('cellDataWidget.mustSelectOneCell', { defaultMessage: "Must be selected one cell" })} alignTop />
{:else if usedFormat == null} {:else if usedFormat == null}
<ErrorInfo message="Format not selected" alignTop /> <ErrorInfo message={_t('cellDataWidget.formatNotSelected', { defaultMessage: "Format not selected" })} alignTop />
{:else if !selection || selection.length == 0} {:else if !selection || selection.length == 0}
<ErrorInfo message="No data selected" alignTop /> <ErrorInfo message={_t('cellDataWidget.noDataSelected', { defaultMessage: "No data selected" })} alignTop />
{:else} {:else}
<svelte:component this={usedFormat?.component} {selection} /> <svelte:component this={usedFormat?.component} {selection} />
{/if} {/if}

View File

@@ -19,12 +19,12 @@
</script> </script>
<WidgetColumnBar> <WidgetColumnBar>
<WidgetColumnBarItem title="Saved files" name="files" height="70%" storageName="savedFilesWidget"> <WidgetColumnBarItem title={_t('files.savedFiles', { defaultMessage: "Saved files" })} name="files" height="70%" storageName="savedFilesWidget">
<SavedFilesList /> <SavedFilesList />
</WidgetColumnBarItem> </WidgetColumnBarItem>
{#if hasPermission('files/favorites/read')} {#if hasPermission('files/favorites/read')}
<WidgetColumnBarItem title="Favorites" name="favorites" storageName="favoritesWidget"> <WidgetColumnBarItem title={_t('files.favorites', { defaultMessage: "Favorites" })} name="favorites" storageName="favoritesWidget">
<WidgetsInnerContainer> <WidgetsInnerContainer>
<AppObjectList list={$favorites || []} module={favoriteFileAppObject} /> <AppObjectList list={$favorites || []} module={favoriteFileAppObject} />
</WidgetsInnerContainer> </WidgetsInnerContainer>

View File

@@ -13,13 +13,14 @@
import WidgetColumnBar from './WidgetColumnBar.svelte'; import WidgetColumnBar from './WidgetColumnBar.svelte';
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte'; import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte'; import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
import { _t } from '../translations';
$: favorites = useFavorites(); $: favorites = useFavorites();
</script> </script>
<WidgetColumnBar> <WidgetColumnBar>
<WidgetColumnBarItem title="Recently closed tabs" name="closedTabs" storageName='closedTabsWidget'> <WidgetColumnBarItem title={_t('history.recentlyClosedTabs', { defaultMessage: "Recently closed tabs" })} name="closedTabs" storageName='closedTabsWidget'>
<WidgetsInnerContainer> <WidgetsInnerContainer>
<AppObjectList <AppObjectList
list={_.sortBy( list={_.sortBy(
@@ -30,7 +31,7 @@
/> />
</WidgetsInnerContainer> </WidgetsInnerContainer>
</WidgetColumnBarItem> </WidgetColumnBarItem>
<WidgetColumnBarItem title="Query history" name="queryHistory" storageName='queryHistoryWidget'> <WidgetColumnBarItem title={_t('history.queryHistory', { defaultMessage: "Query history" })} name="queryHistory" storageName='queryHistoryWidget'>
<QueryHistoryList /> <QueryHistoryList />
</WidgetColumnBarItem> </WidgetColumnBarItem>
</WidgetColumnBar> </WidgetColumnBar>

View File

@@ -4,13 +4,15 @@
import WidgetColumnBar from './WidgetColumnBar.svelte'; import WidgetColumnBar from './WidgetColumnBar.svelte';
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte'; import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
import { _t } from '../translations';
</script> </script>
<WidgetColumnBar> <WidgetColumnBar>
<WidgetColumnBarItem title="Installed extensions" name="installed" height="50%" storageName='installedPluginsWidget'> <WidgetColumnBarItem title={_t('widgets.installedExtensions', { defaultMessage: 'Installed extensions' })} name="installed" height="50%" storageName='installedPluginsWidget'>
<InstalledPluginsList /> <InstalledPluginsList />
</WidgetColumnBarItem> </WidgetColumnBarItem>
<WidgetColumnBarItem title="Available extensions" name="all" storageName='allPluginsWidget'> <WidgetColumnBarItem title={_t('widgets.availableExtensions', { defaultMessage: 'Available extensions' })} name="all" storageName='allPluginsWidget'>
<AvailablePluginsList /> <AvailablePluginsList />
</WidgetColumnBarItem> </WidgetColumnBarItem>
</WidgetColumnBar> </WidgetColumnBar>

View File

@@ -30,11 +30,11 @@
<WidgetColumnBarItem title="Public Knowledge Base" name="publicCloud" storageName="publicCloudItems"> <WidgetColumnBarItem title="Public Knowledge Base" name="publicCloud" storageName="publicCloudItems">
<WidgetsInnerContainer> <WidgetsInnerContainer>
<SearchBoxWrapper> <SearchBoxWrapper>
<SearchInput placeholder="Search public files" bind:value={filter} /> <SearchInput placeholder={_t('publicCloudWidget.searchPublicFiles', { defaultMessage: "Search public files" })} bind:value={filter} />
<CloseSearchButton bind:filter /> <CloseSearchButton bind:filter />
<InlineButton <InlineButton
on:click={handleRefreshPublic} on:click={handleRefreshPublic}
title="Refresh files" title={_t('publicCloudWidget.refreshFiles', { defaultMessage: "Refresh files" })}
data-testid="CloudItemsWidget_buttonRefreshPublic" data-testid="CloudItemsWidget_buttonRefreshPublic"
> >
<FontIcon icon="icon refresh" /> <FontIcon icon="icon refresh" />
@@ -52,9 +52,9 @@
<ErrorInfo message="No files found for your configuration" /> <ErrorInfo message="No files found for your configuration" />
<div class="error-info"> <div class="error-info">
<div class="m-1"> <div class="m-1">
Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first. {_t('publicCloudWidget.onlyRelevantFilesListed', { defaultMessage: "Only files relevant for your connections, platform and DbGate edition are listed. Please define connections at first." })}
</div> </div>
<FormStyledButton value={`Refresh list`} skipWidth on:click={handleRefreshPublic} /> <FormStyledButton value={_t('publicCloudWidget.refreshList', { defaultMessage: "Refresh list" })} skipWidth on:click={handleRefreshPublic} />
</div> </div>
{/if} {/if}
</WidgetsInnerContainer> </WidgetsInnerContainer>

View File

@@ -9,6 +9,7 @@
import openNewTab from '../utility/openNewTab'; import openNewTab from '../utility/openNewTab';
import CloseSearchButton from '../buttons/CloseSearchButton.svelte'; import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
import { apiCall, apiOff, apiOn } from '../utility/api'; import { apiCall, apiOff, apiOn } from '../utility/api';
import { _t } from '../translations';
let filter = ''; let filter = '';
let search = ''; let search = '';
@@ -38,7 +39,7 @@
</script> </script>
<SearchBoxWrapper> <SearchBoxWrapper>
<SearchInput placeholder="Search query history" {filter} bind:value={filter} /> <SearchInput placeholder={_t('history.searchQueryHistory', { defaultMessage: "Search query history" })} {filter} bind:value={filter} />
<CloseSearchButton <CloseSearchButton
bind:filter bind:filter
on:click={() => { on:click={() => {
@@ -54,7 +55,7 @@
on:click={() => { on:click={() => {
openNewTab( openNewTab(
{ {
title: 'Query #', title: _t('database.queryDesigner', { defaultMessage: "Query #" }),
icon: 'icon sql-file', icon: 'icon sql-file',
tabComponent: 'QueryTab', tabComponent: 'QueryTab',
focused: true, focused: true,

View File

@@ -13,6 +13,7 @@
import { isProApp } from '../utility/proTools'; import { isProApp } from '../utility/proTools';
import InlineUploadButton from '../buttons/InlineUploadButton.svelte'; import InlineUploadButton from '../buttons/InlineUploadButton.svelte';
import { DATA_FOLDER_NAMES } from 'dbgate-tools'; import { DATA_FOLDER_NAMES } from 'dbgate-tools';
import { _t } from '../translations';
let filter = ''; let filter = '';
@@ -65,19 +66,19 @@
</script> </script>
<SearchBoxWrapper> <SearchBoxWrapper>
<SearchInput placeholder="Search saved files" bind:value={filter} /> <SearchInput placeholder={_t('files.searchSavedFiles', { defaultMessage: "Search saved files" })} bind:value={filter} />
<CloseSearchButton bind:filter /> <CloseSearchButton bind:filter />
<InlineUploadButton <InlineUploadButton
filters={[ filters={[
{ {
name: `All supported files`, name: _t('files.allSupportedFiles', { defaultMessage: "All supported files" }),
extensions: ['sql'], extensions: ['sql'],
}, },
{ name: `SQL files`, extensions: ['sql'] }, { name: _t('files.sqlFiles', { defaultMessage: "SQL files" }), extensions: ['sql'] },
]} ]}
onProcessFile={handleUploadedFile} onProcessFile={handleUploadedFile}
/> />
<InlineButton on:click={handleRefreshFiles} title="Refresh files" data-testid="SavedFileList_buttonRefresh"> <InlineButton on:click={handleRefreshFiles} title={_t('files.refreshFiles', { defaultMessage: "Refresh files" })} data-testid="SavedFileList_buttonRefresh">
<FontIcon icon="icon refresh" /> <FontIcon icon="icon refresh" />
</InlineButton> </InlineButton>
</SearchBoxWrapper> </SearchBoxWrapper>
@@ -86,7 +87,7 @@
<AppObjectList <AppObjectList
list={files} list={files}
module={savedFileAppObject} module={savedFileAppObject}
groupFunc={data => (data.teamFileId ? 'Team files' : dataFolderTitle(data.folder))} groupFunc={data => (data.teamFileId ? _t('files.teamFiles', { defaultMessage: "Team files" }) : dataFolderTitle(data.folder))}
{filter} {filter}
/> />
</WidgetsInnerContainer> </WidgetsInnerContainer>

View File

@@ -35,16 +35,16 @@
getCurrentConfig().storageDatabase && { getCurrentConfig().storageDatabase && {
icon: 'icon admin', icon: 'icon admin',
name: 'admin', name: 'admin',
title: 'Administration', title: _t('widgets.administration', { defaultMessage: 'Administration' }),
}, },
{ {
icon: 'icon database', icon: 'icon database',
name: 'database', name: 'database',
title: 'Database connections', title: _t('widgets.databaseConnections', { defaultMessage: 'Database connections' }),
}, },
getCurrentConfig().allowPrivateCloud && { getCurrentConfig().allowPrivateCloud && {
name: 'cloud-private', name: 'cloud-private',
title: 'DbGate Cloud', title: _t('widgets.dbgateCloud', { defaultMessage: 'DbGate Cloud' }),
icon: 'icon cloud-private', icon: 'icon cloud-private',
}, },
@@ -55,17 +55,17 @@
{ {
icon: 'icon file', icon: 'icon file',
name: 'file', name: 'file',
title: 'Favorites & Saved files', title: _t('widgets.favoritesAndSavedFiles', { defaultMessage: 'Favorites & Saved files' }),
}, },
{ {
icon: 'icon history', icon: 'icon history',
name: 'history', name: 'history',
title: 'Query history & Closed tabs', title: _t('widgets.queryHistoryAndClosedTabs', { defaultMessage: 'Query history & Closed tabs' }),
}, },
isProApp() && { isProApp() && {
icon: 'icon archive', icon: 'icon archive',
name: 'archive', name: 'archive',
title: 'Archive (saved tabular data)', title: _t('widgets.archive', { defaultMessage: 'Archive (saved tabular data)' }),
}, },
// { // {
// icon: 'icon plugin', // icon: 'icon plugin',
@@ -75,17 +75,17 @@
{ {
icon: 'icon cell-data', icon: 'icon cell-data',
name: 'cell-data', name: 'cell-data',
title: 'Selected cell data detail view', title: _t('widgets.selectedCellDataDetailView', { defaultMessage: 'Selected cell data detail view' }),
}, },
{ {
name: 'cloud-public', name: 'cloud-public',
title: 'DbGate Cloud', title: _t('widgets.dbgateCloud', { defaultMessage: 'DbGate Cloud' }),
icon: 'icon cloud-public', icon: 'icon cloud-public',
}, },
{ {
icon: 'icon premium', icon: 'icon premium',
name: 'premium', name: 'premium',
title: 'Premium promo', title: _t('widgets.premiumPromo', { defaultMessage: 'Premium promo' }),
isPremiumPromo: true, isPremiumPromo: true,
}, },
// { // {
@@ -213,7 +213,7 @@
class="wrapper" class="wrapper"
on:click={() => showModal(NewObjectModal)} on:click={() => showModal(NewObjectModal)}
data-testid="WidgetIconPanel_addButton" data-testid="WidgetIconPanel_addButton"
title="Add New" title={_t('widgets.addNew', { defaultMessage: 'Add New' })}
> >
<FontIcon icon="icon add" /> <FontIcon icon="icon add" />
</div> </div>