Added translation tags for modals

This commit is contained in:
Stela Augustinova
2025-12-01 10:25:43 +01:00
parent e14f59256d
commit d94a67d0af
25 changed files with 185 additions and 172 deletions

View File

@@ -307,21 +307,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> </Link>
</svelte:fragment> </svelte:fragment>
<svelte:fragment slot="3" let:row> <svelte:fragment slot="3" let:row>
{#if progressHolder[row]?.status == 'running' && isRunning} {#if progressHolder[row]?.status == 'running' && isRunning}
<FontIcon icon="icon loading" /> <FontIcon icon="icon loading" />
{#if progressHolder[row]?.writtenRowCount} {#if progressHolder[row]?.writtenRowCount}
{progressHolder[row]?.writtenRowCount} rows writtem {progressHolder[row]?.writtenRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
{:else if progressHolder[row]?.readRowCount} {:else if progressHolder[row]?.readRowCount}
{progressHolder[row]?.readRowCount} rows read {progressHolder[row]?.readRowCount} {_t('importExport.rowsRead', { defaultMessage: 'rows read' })}
{:else} {:else}
Running {_t('importExport.running', { defaultMessage: 'Running' })}
{/if} {/if}
{:else if progressHolder[row]?.status == 'error'} {:else if progressHolder[row]?.status == 'error'}
<FontIcon icon="img error" /> Error <FontIcon icon="img error" /> {_t('common.error', { defaultMessage: 'Error' })}
{#if progressHolder[row]?.errorMessage} {#if progressHolder[row]?.errorMessage}
<FontIcon <FontIcon
icon="img info" icon="img info"
@@ -334,20 +334,20 @@
{:else if progressHolder[row]?.status == 'done'} {:else if progressHolder[row]?.status == 'done'}
<FontIcon icon="img ok" /> <FontIcon icon="img ok" />
{#if progressHolder[row]?.writtenRowCount} {#if progressHolder[row]?.writtenRowCount}
{progressHolder[row]?.writtenRowCount} rows written {progressHolder[row]?.writtenRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
{:else if progressHolder[row]?.readRowCount} {:else if progressHolder[row]?.readRowCount}
{progressHolder[row]?.readRowCount} rows written {progressHolder[row]?.readRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
{:else} {:else}
Done {_t('common.done', { defaultMessage: 'Done' })}
{/if} {/if}
{:else} {:else}
<FontIcon icon="icon wait" /> <FontIcon icon="icon wait" />
{#if progressHolder[row]?.writtenRowCount} {#if progressHolder[row]?.writtenRowCount}
{progressHolder[row]?.writtenRowCount} rows writtem {progressHolder[row]?.writtenRowCount} {_t('importExport.rowsWritten', { defaultMessage: 'rows written' })}
{:else if progressHolder[row]?.readRowCount} {:else if progressHolder[row]?.readRowCount}
{progressHolder[row]?.readRowCount} rows read {progressHolder[row]?.readRowCount} {_t('importExport.rowsRead', { defaultMessage: 'rows read' })}
{:else} {:else}
Queued {_t('importExport.queued', { defaultMessage: 'Queued' })}
{/if} {/if}
{/if} {/if}
</svelte:fragment> </svelte:fragment>

View File

@@ -137,7 +137,7 @@
<Link <Link
onClick={() => { onClick={() => {
value = value.filter((x, i) => i != index); value = value.filter((x, i) => i != index);
}}>Remove</Link }}>{_t('common.Remove', { defaultMessage: 'Remove' })}</Link
> >
</svelte:fragment> </svelte:fragment>
</TableControl> </TableControl>

View File

@@ -168,7 +168,7 @@
<FormProvider> <FormProvider>
<ModalBase {...$$restProps} fullScreen> <ModalBase {...$$restProps} fullScreen>
<div slot="header"> <div slot="header">
{mode == 'export' ? 'Export' : 'Import'} connections &amp; settings {mode == 'export' ? 'Export' : 'Import'} {_t('importExport.connectionsSettings', { defaultMessage: 'connections & settings' })}
<span class="check-uncheck"> <span class="check-uncheck">
<Link onClick={() => handleCheckAll(true)}>{_t('common.checkAll', { defaultMessage: 'Check all' })}</Link> <Link onClick={() => handleCheckAll(true)}>{_t('common.checkAll', { defaultMessage: 'Check all' })}</Link>
| |
@@ -180,16 +180,16 @@
<TabControl <TabControl
tabs={_.compact([ tabs={_.compact([
connections?.length && { 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, slot: 1,
}, },
users?.length && { label: `Users (${checkedUsers?.length}/${users?.length})`, slot: 2 }, users?.length && { label: _t('importExport.usersNum', { defaultMessage:'Users ({checkedUsers}/{users})', values: { checkedUsers: checkedUsers?.length, users: users?.length } }), slot: 2 },
roles?.length && { label: `Roles (${checkedRoles?.length}/${roles?.length})`, slot: 3 }, roles?.length && { label: _t('importExport.rolesNum', { defaultMessage:'Roles ({checkedRoles}/{roles})', values: { checkedRoles: checkedRoles?.length, roles: roles?.length } }), slot: 3 },
authMethods?.length && { 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, 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"> <svelte:fragment slot="1">
@@ -199,10 +199,10 @@
stickyHeader stickyHeader
columns={[ columns={[
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true }, { header: 'ID', fieldName: 'id', sortable: true, filterable: true },
{ header: 'Display name', fieldName: 'displayName', sortable: true, filterable: true }, { header: _t('importExport.displayName', { defaultMessage: 'Display name' }), fieldName: 'displayName', sortable: true, filterable: true },
{ header: 'Engine', fieldName: 'engine', sortable: true, filterable: true }, { header: _t('importExport.engine', { defaultMessage: 'Engine' }), fieldName: 'engine', sortable: true, filterable: true },
{ header: 'Server', fieldName: 'server', sortable: true, filterable: true }, { header: _t('importExport.server', { defaultMessage: 'Server' }), fieldName: 'server', sortable: true, filterable: true },
{ header: 'User', fieldName: 'user', sortable: true, filterable: true }, { header: _t('importExport.user', { defaultMessage: 'User' }), fieldName: 'user', sortable: true, filterable: true },
]} ]}
clickable clickable
rows={connections} rows={connections}
@@ -225,8 +225,8 @@
stickyHeader stickyHeader
columns={[ columns={[
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true }, { header: 'ID', fieldName: 'id', sortable: true, filterable: true },
{ header: 'Login', fieldName: 'login', sortable: true, filterable: true }, { header: _t('importExport.login', { defaultMessage: 'Login' }), fieldName: 'login', sortable: true, filterable: true },
{ header: 'E-mail', fieldName: 'email', sortable: true, filterable: true }, { header: _t('importExport.email', { defaultMessage: 'E-mail' }), fieldName: 'email', sortable: true, filterable: true },
]} ]}
clickable clickable
rows={users} rows={users}
@@ -249,7 +249,7 @@
stickyHeader stickyHeader
columns={[ columns={[
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true }, { 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 clickable
rows={roles} rows={roles}
@@ -272,8 +272,8 @@
stickyHeader stickyHeader
columns={[ columns={[
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true }, { 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 },
{ header: 'Type', fieldName: 'type', sortable: true, filterable: true }, { header: _t('importExport.type', { defaultMessage: 'Type' }), fieldName: 'type', sortable: true, filterable: true },
]} ]}
clickable clickable
rows={authMethods} rows={authMethods}
@@ -296,9 +296,9 @@
stickyHeader stickyHeader
columns={[ columns={[
{ header: 'ID', fieldName: 'id', sortable: true, filterable: true }, { header: 'ID', fieldName: 'id', sortable: true, filterable: true },
{ header: 'Group', fieldName: 'group', sortable: true, filterable: true }, { header: _t('importExport.group', { defaultMessage: 'Group' }), fieldName: 'group', sortable: true, filterable: true },
{ header: 'Key', fieldName: 'key', sortable: true, filterable: true }, { header: _t('importExport.key', { defaultMessage: 'Key' }), fieldName: 'key', sortable: true, filterable: true },
{ header: 'Value', fieldName: 'value', sortable: true, filterable: true }, { header: _t('importExport.value', { defaultMessage: 'Value' }), fieldName: 'value', sortable: true, filterable: true },
]} ]}
clickable clickable
rows={config} rows={config}
@@ -340,7 +340,7 @@
> >
{/if} {/if}
<LargeButton icon="icon close" on:click={closeCurrentModal} data-testid="EditJsonModal_closeButton" <LargeButton icon="icon close" on:click={closeCurrentModal} data-testid="EditJsonModal_closeButton"
>Close</LargeButton >{_t('common.close', { defaultMessage: 'Close' })}</LargeButton
> >
</div> </div>
</div> </div>

View File

@@ -16,6 +16,7 @@
import FormSubmit from '../forms/FormSubmit.svelte'; import FormSubmit from '../forms/FormSubmit.svelte';
import FormButton from '../forms/FormButton.svelte'; import FormButton from '../forms/FormButton.svelte';
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { _t } from '../translations';
export let editingData; export let editingData;
export let savingTab; export let savingTab;
@@ -113,28 +114,28 @@
<FormProvider {initialValues}> <FormProvider {initialValues}>
<ModalBase {...$$restProps}> <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={_t('favorite.title', { defaultMessage: 'Title' })} name="title" focused />
<FormTextField label="Icon" name="icon" /> <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} {#if !!savingTab && !electron && canWriteFavorite}
<FormCheckboxField label="Share as link" name="shareAsLink" /> <FormCheckboxField label={_t('favorite.shareAsLink', { defaultMessage: 'Share as link' })} name="shareAsLink" />
{/if} {/if}
<FormValues let:values> <FormValues let:values>
{#if !values.shareAsLink && canWriteFavorite} {#if !values.shareAsLink && canWriteFavorite}
<FormCheckboxField label="Show in toolbar" name="showInToolbar" /> <FormCheckboxField label={_t('favorite.showInToolbar', { defaultMessage: 'Show in toolbar' })} name="showInToolbar" />
<FormCheckboxField label="Open on startup" name="openOnStartup" /> <FormCheckboxField label={_t('favorite.openOnStartup', { defaultMessage: 'Open on startup' })} name="openOnStartup" />
{/if} {/if}
</FormValues> </FormValues>
{#if !!savingTab && !!savedFile} {#if !!savingTab && !!savedFile}
<FormSelectField <FormSelectField
label="What to save" label={_t('favorite.whatToSave', { defaultMessage: 'What to save' })}
name="whatToSave" name="whatToSave"
options={[ options={[
{ label: 'Link to file', value: 'fileName' }, { label: _t('favorite.linkToFile', { defaultMessage: 'Link to file' }), value: 'fileName' },
{ label: 'Content', value: 'content' }, { label: _t('favorite.content', { defaultMessage: 'Content' }), value: 'content' },
]} ]}
/> />
{/if} {/if}
@@ -142,12 +143,12 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormValues let:values> <FormValues let:values>
{#if !values.shareAsLink && canWriteFavorite} {#if !values.shareAsLink && canWriteFavorite}
<FormSubmit value="OK" on:click={handleSubmit} /> <FormSubmit value={_t('common.ok', { defaultMessage: 'OK' })} on:click={handleSubmit} />
{/if} {/if}
{#if values.shareAsLink || !canWriteFavorite} {#if values.shareAsLink || !canWriteFavorite}
<FormButton value="Copy link" on:click={handleCopyLink} /> <FormButton value={_t('common.copyLink', { defaultMessage: 'Copy link' })} on:click={handleCopyLink} />
{/if} {/if}
<FormButton value="Cancel" on:click={closeCurrentModal} /> <FormButton value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
</FormValues> </FormValues>
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>

View File

@@ -3,6 +3,7 @@
import FormStyledButton from '../buttons/FormStyledButton.svelte'; import FormStyledButton from '../buttons/FormStyledButton.svelte';
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools'; import { closeCurrentModal } from './modalTools';
import { _t } from '../translations';
export let onFilter; export let onFilter;
@@ -16,35 +17,35 @@
</script> </script>
<ModalBase {...$$restProps}> <ModalBase {...$$restProps}>
<div slot="header">Filter multiple values</div> <div slot="header">{_t('filterMultipleValues.filterMultipleValues', { defaultMessage: 'Filter multiple values' })}</div>
<div class="flex"> <div class="flex">
<TextAreaField rows={10} bind:value focused /> <TextAreaField rows={10} bind:value focused />
<div> <div>
<div> <div>
<input type="radio" bind:group value="is" id="__is" /> <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>
<div> <div>
<input type="radio" bind:group value="is_not" id="__is_not" /> <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>
<div> <div>
<input type="radio" bind:group value="contains" id="__contains" /> <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>
<div> <div>
<input type="radio" bind:group value="begins" id="__begins" /> <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>
<div> <div>
<input type="radio" bind:group value="ends" id="__ends" /> <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>
</div> </div>
<div slot="footer"> <div slot="footer">
<FormStyledButton value="OK" on:click={handleOk} /> <FormStyledButton value={_t('common.ok', { defaultMessage: 'OK' })} on:click={handleOk} />
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} /> <FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
</div> </div>
</ModalBase> </ModalBase>

View File

@@ -9,6 +9,7 @@
import newQuery from '../query/newQuery'; import newQuery from '../query/newQuery';
import SqlEditor from '../query/SqlEditor.svelte'; import SqlEditor from '../query/SqlEditor.svelte';
import keycodes from '../utility/keycodes'; import keycodes from '../utility/keycodes';
import { _t } from '../translations';
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools'; import { closeCurrentModal } from './modalTools';
@@ -77,24 +78,23 @@
<FormProvider> <FormProvider>
<ModalBase {...$$restProps}> <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="flex mb-3">
<div class="m-1 col-4"> <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 <TableControl
rows={QUERY_TYPES.map(name => ({ name }))} rows={QUERY_TYPES.map(name => ({ name }))}
bind:selectedIndex={queryTypeIndex} bind:selectedIndex={queryTypeIndex}
bind:domTable={domQueryType} bind:domTable={domQueryType}
focusOnCreate focusOnCreate
selectable selectable
columns={[{ fieldName: 'name', header: 'Query type' }]} columns={[{ fieldName: 'name', header: _t('generateSqlFromData.queryType', { defaultMessage: 'Query type' }) }]}
/> />
</div> </div>
<div class="m-1 col-4"> <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 <CheckableColumnList
{allColumns} {allColumns}
@@ -120,13 +120,13 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormSubmit <FormSubmit
value="OK" value={_t('common.ok', { defaultMessage: 'OK' })}
on:click={() => { on:click={() => {
newQuery({ initialData: sqlPreview }); newQuery({ initialData: sqlPreview });
closeCurrentModal(); closeCurrentModal();
}} }}
/> />
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} /> <FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -29,7 +29,7 @@
<FormTextField {label} name="value" focused data-testid="InputTextModal_value" /> <FormTextField {label} name="value" focused data-testid="InputTextModal_value" />
<svelte:fragment slot="footer"> <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" /> <FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} data-testid="InputTextModal_cancel" />
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>

View File

@@ -9,6 +9,8 @@
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools'; import { closeCurrentModal } from './modalTools';
import { _t } from '../translations';
import _ from 'lodash';
export let sql; export let sql;
export let onInsert; export let onInsert;
@@ -104,12 +106,11 @@
</script> </script>
<ModalBase {...$$restProps}> <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="flex mb-3">
<div class="m-1 col-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 <TableControl
rows={sources} rows={sources}
focusOnCreate focusOnCreate
@@ -118,14 +119,14 @@
selectable selectable
on:keydown={sourceKeyDown} on:keydown={sourceKeyDown}
columns={[ columns={[
{ fieldName: 'alias', header: 'Alias' }, { fieldName: 'alias', header: _t('insertJoin.alias', { defaultMessage: 'Alias' }) },
{ fieldName: 'name', header: 'Name' }, { fieldName: 'name', header: _t('insertJoin.name', { defaultMessage: 'Name' }) },
]} ]}
/> />
</div> </div>
<div class="m-1 col-6"> <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 <TableControl
rows={targets} rows={targets}
@@ -134,15 +135,15 @@
selectable selectable
on:keydown={targetKeyDown} on:keydown={targetKeyDown}
columns={[ columns={[
{ fieldName: 'baseColumns', header: 'Column from' }, { fieldName: 'baseColumns', header: _t('insertJoin.columnFrom', { defaultMessage: 'Column from' }) },
{ fieldName: 'refTable', header: 'Table to' }, { fieldName: 'refTable', header: _t('insertJoin.tableTo', { defaultMessage: 'Table to' }) },
{ fieldName: 'refColumns', header: 'Column to' }, { fieldName: 'refColumns', header: _t('insertJoin.columnTo', { defaultMessage: 'Column to' }) },
]} ]}
/> />
</div> </div>
<div class="m-1 col-3"> <div class="m-1 col-3">
<div class="m-1">Join</div> <div class="m-1">{_t('insertJoin.join', { defaultMessage: 'Join' })}</div>
<TableControl <TableControl
rows={JOIN_TYPES.map(name => ({ name }))} rows={JOIN_TYPES.map(name => ({ name }))}
@@ -150,10 +151,10 @@
bind:domTable={domJoin} bind:domTable={domJoin}
selectable selectable
on:keydown={joinKeyDown} 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 <TextField
value={alias} value={alias}
on:input={e => { on:input={e => {
@@ -171,13 +172,13 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormStyledButton <FormStyledButton
value="OK" value={_t('common.ok', { defaultMessage: 'OK' })}
on:click={() => { on:click={() => {
closeCurrentModal(); closeCurrentModal();
onInsert(sqlPreview); onInsert(sqlPreview);
}} }}
/> />
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} /> <FormStyledButton type="button" value={_t('common.close', { defaultMessage: 'Close' })} on:click={closeCurrentModal} />
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>

View File

@@ -5,6 +5,7 @@
import FontIcon from '../icons/FontIcon.svelte'; import FontIcon from '../icons/FontIcon.svelte';
import { isProApp } from '../utility/proTools'; import { isProApp } from '../utility/proTools';
import { openWebLink } from '../utility/simpleTools'; import { openWebLink } from '../utility/simpleTools';
import { _t } from '../translations';
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools'; import { closeCurrentModal } from './modalTools';
@@ -15,7 +16,7 @@
<FormProvider> <FormProvider>
<ModalBase {...$$restProps}> <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="wrapper">
<div class="icon"> <div class="icon">
@@ -23,15 +24,15 @@
</div> </div>
<div data-testid="LicenseLimitMessageModal_message"> <div data-testid="LicenseLimitMessageModal_message">
<p> <p>
Cloud operation ended with error:<br /> {_t('licenseLimit.cloudOperationEndedWithError', { defaultMessage: 'Cloud operation ended with error:' })}<br />
{message} {message}
</p> </p>
<p> <p>
This is a limitation of the free version of DbGate. To continue using cloud operations, please {#if !isProApp()}download {_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' })}
and{/if} purchase DbGate Premium. {/if} {_t('licenseLimit.purchase', { defaultMessage: 'purchase DbGate Premium.' })}
</p> </p>
<p>Free version limit:</p> <p>{_t('licenseLimit.freeVersionLimit', { defaultMessage: 'Free version limit:' })}</p>
<ul> <ul>
{#each licenseLimits || [] as limit} {#each licenseLimits || [] as limit}
<li>{limit}</li> <li>{limit}</li>
@@ -41,16 +42,16 @@
</div> </div>
<div slot="footer"> <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()} {#if !isProApp()}
<FormStyledButton <FormStyledButton
value="Download DbGate Premium" value={_t('licenseLimit.downloadDbGatePremium', { defaultMessage: 'Download DbGate Premium' })}
on:click={() => openWebLink('https://www.dbgate.io/download/')} on:click={() => openWebLink('https://www.dbgate.io/download/')}
skipWidth skipWidth
/> />
{/if} {/if}
<FormStyledButton <FormStyledButton
value="Purchase DbGate Premium" value={_t('licenseLimit.purchaseDbGatePremium', { defaultMessage: 'Purchase DbGate Premium' })}
on:click={() => openWebLink('https://www.dbgate.io/purchase/premium/')} on:click={() => openWebLink('https://www.dbgate.io/purchase/premium/')}
skipWidth skipWidth
/> />

View File

@@ -30,9 +30,9 @@
const { errorMessage } = resp || {}; const { errorMessage } = resp || {};
if (errorMessage) { 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 { } else {
showSnackbarSuccess('Saved to database'); showSnackbarSuccess(_t('common.savedToDatabase', { defaultMessage: 'Saved to database' }));
apiCall('database-connections/sync-model', dbid); apiCall('database-connections/sync-model', dbid);
closeCurrentModal(); closeCurrentModal();
} }
@@ -51,7 +51,7 @@
<FormArgumentList args={driver?.newCollectionFormParams} /> <FormArgumentList args={driver?.newCollectionFormParams} />
<svelte:fragment slot="footer"> <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} /> <FormStyledButton type="button" value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>

View File

@@ -5,6 +5,7 @@
import FormSubmit from '../forms/FormSubmit.svelte'; import FormSubmit from '../forms/FormSubmit.svelte';
import FormTextField from '../forms/FormTextField.svelte'; import FormTextField from '../forms/FormTextField.svelte';
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { _t } from '../translations';
import getElectron from '../utility/getElectron'; import getElectron from '../utility/getElectron';
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
@@ -26,7 +27,7 @@
<FormProvider initialValues={parameterValues}> <FormProvider initialValues={parameterValues}>
<ModalBase {...$$restProps}> <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"> <div class="params">
{#each parameterNames as parameterName, index} {#each parameterNames as parameterName, index}
@@ -34,11 +35,11 @@
{/each} {/each}
</div> </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"> <svelte:fragment slot="footer">
<FormSubmit value="Run query" on:click={handleSubmit} /> <FormSubmit value={_t('queryParameters.runQuery', { defaultMessage: 'Run query' })} on:click={handleSubmit} />
<FormStyledButton value="Close" on:click={handleClose} /> <FormStyledButton value={_t('common.close', { defaultMessage: 'Close' })} on:click={handleClose} />
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -10,6 +10,7 @@
import { showSnackbarError } from '../utility/snackbar'; import { showSnackbarError } from '../utility/snackbar';
import ModalBase from './ModalBase.svelte'; import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools'; import { closeCurrentModal } from './modalTools';
import { _t } from '../translations';
export let script; export let script;
export let header; export let header;
@@ -77,14 +78,14 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
{#if isRunning} {#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} {: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}
{#if onOpenResult && !isRunning} {#if onOpenResult && !isRunning}
<FormStyledButton <FormStyledButton
value={openResultLabel || 'Open result'} value={openResultLabel || _t('script.openResult', { defaultMessage: 'Open result' })}
on:click={() => { on:click={() => {
closeCurrentModal(); closeCurrentModal();
onOpenResult(); onOpenResult();

View File

@@ -24,10 +24,10 @@
<FormProvider initialValues={{ file, folder }}> <FormProvider initialValues={{ file, folder }}>
<ModalBase {...$$restProps}> <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 /> <FormArchiveFolderSelect label={_t('archive.folder', { defaultMessage: 'Folder' })} name="folder" isNative allowCreateNew skipZipFiles />
<FormTextField label="File name" name="file" disabled={fileIsReadOnly} /> <FormTextField label={_t('archive.fileName', { defaultMessage: 'File name' })} name="file" disabled={fileIsReadOnly} />
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormSubmit value={_t('common.save', { defaultMessage: 'Save' })} on:click={handleSubmit} /> <FormSubmit value={_t('common.save', { defaultMessage: 'Save' })} on:click={handleSubmit} />

View File

@@ -125,7 +125,7 @@
<FormTextField label="File name" name="name" focused /> <FormTextField label="File name" name="name" focused />
{#if $cloudSigninTokenHolder && !$values['saveToTeamFolder']} {#if $cloudSigninTokenHolder && !$values['saveToTeamFolder']}
<FormCloudFolderSelect <FormCloudFolderSelect
label="Choose cloud folder" label={_t('cloud.chooseCloudFolder', { defaultMessage: "Choose cloud folder" })}
name="cloudFolder" name="cloudFolder"
isNative isNative
requiredRoleVariants={['write', 'admin']} requiredRoleVariants={['write', 'admin']}
@@ -134,13 +134,13 @@
: [ : [
{ {
folid: '__local', folid: '__local',
name: "Local folder (don't store on cloud)", name: _t('cloud.localFolder', { defaultMessage: "Local folder (don't store on cloud)" }),
}, },
]} ]}
/> />
{/if} {/if}
{#if $configValue?.storageDatabase} {#if $configValue?.storageDatabase}
<FormCheckboxField label="Save to team folder" name="saveToTeamFolder" /> <FormCheckboxField label={_t('cloud.saveToTeamFolder', { defaultMessage: "Save to team folder" })} name="saveToTeamFolder" />
{/if} {/if}
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
@@ -148,12 +148,12 @@
{#if electron} {#if electron}
<FormStyledButton <FormStyledButton
type="button" type="button"
value="Save to disk" value={_t('common.saveToDisk', { defaultMessage: 'Save to disk' })}
on:click={async () => { on:click={async () => {
const file = await electron.showSaveDialog({ const file = await electron.showSaveDialog({
filters: [ filters: [
{ name: `${fileExtension.toUpperCase()} files`, extensions: [fileExtension] }, { name: _t('common.fileType', { defaultMessage: '{extension} files', values: {extension: fileExtension.toUpperCase()} }), extensions: [fileExtension] },
{ name: `All files`, extensions: ['*'] }, { name: _t('common.allFiles', { defaultMessage: 'All files' }), extensions: ['*'] },
], ],
defaultPath: filePath || `${name}.${fileExtension}`, defaultPath: filePath || `${name}.${fileExtension}`,
properties: ['showOverwriteConfirmation'], properties: ['showOverwriteConfirmation'],

View File

@@ -84,7 +84,7 @@
</div> </div>
<div slot="footer"> <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} /> <FormButton type="button" value={_t('common.close', {defaultMessage: 'Close'})} on:click={closeCurrentModal} />
</div> </div>
</ModalBase> </ModalBase>

View File

@@ -14,7 +14,7 @@
</script> </script>
<ModalBase {...$$restProps}> <ModalBase {...$$restProps}>
<div slot="header">SQL Script</div> <div slot="header">{_t('script.sqlScript', { defaultMessage: 'SQL Script' })}</div>
<div class="editor"> <div class="editor">
<SqlEditor {engine} value={sql} readOnly /> <SqlEditor {engine} value={sql} readOnly />
@@ -29,7 +29,7 @@
/> />
<FormStyledButton <FormStyledButton
type="button" type="button"
value="Open script" value={_t('common.openScript', { defaultMessage: "Open script" })}
on:click={() => { on:click={() => {
newQuery({ newQuery({
initialData: sql, initialData: sql,

View File

@@ -32,6 +32,7 @@
import LoadingInfo from '../elements/LoadingInfo.svelte'; import LoadingInfo from '../elements/LoadingInfo.svelte';
import { getObjectTypeFieldLabel } from '../utility/common'; import { getObjectTypeFieldLabel } from '../utility/common';
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { _t } from '../translations';
export let conid; export let conid;
export let database; export let database;
@@ -113,7 +114,7 @@
function editSql() { function editSql() {
openNewTab( openNewTab(
{ {
title: 'Query #', title: _t('query.queryNumber', { defaultMessage: 'Query #' }),
icon: 'img sql-file', icon: 'img sql-file',
tabComponent: 'QueryTab', tabComponent: 'QueryTab',
focused: true, focused: true,
@@ -133,7 +134,7 @@
<FormProviderCore values={valuesStore} template={FormFieldTemplateTiny}> <FormProviderCore values={valuesStore} template={FormFieldTemplateTiny}>
<ModalBase {...$$restProps} fullScreen> <ModalBase {...$$restProps} fullScreen>
<svelte:fragment slot="header"> <svelte:fragment slot="header">
SQL Generator {_t('sqlGenerator.sqlGenerator', { defaultMessage: 'SQL Generator' })}
<span class="dbname"> <span class="dbname">
<FontIcon icon="icon database" /> <FontIcon icon="icon database" />
{database} {database}
@@ -146,9 +147,9 @@
<HorizontalSplitter initialValue="300px" bind:size={managerSize}> <HorizontalSplitter initialValue="300px" bind:size={managerSize}>
<svelte:fragment slot="1"> <svelte:fragment slot="1">
<div class="flexcol flex1"> <div class="flexcol flex1">
<WidgetTitle>Choose objects</WidgetTitle> <WidgetTitle>{_t('sqlGenerator.chooseObjects', { defaultMessage: 'Choose objects' })}</WidgetTitle>
<SearchBoxWrapper> <SearchBoxWrapper>
<SearchInput placeholder="Search tables or objects" bind:value={objectsFilter} /> <SearchInput placeholder={_t('sqlGenerator.searchTablesOrObjects', { defaultMessage: 'Search tables or objects' })} bind:value={objectsFilter} />
</SearchBoxWrapper> </SearchBoxWrapper>
<WidgetsInnerContainer> <WidgetsInnerContainer>
@@ -174,54 +175,53 @@
{:else} {:else}
<div class="flexcol flex1"> <div class="flexcol flex1">
{#if truncated} {#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} {/if}
<div class="relative flex1"> <div class="relative flex1">
<SqlEditor readOnly value={sqlPreview} /> <SqlEditor readOnly value={sqlPreview} />
</div> </div>
</div> </div>
{#if busy} {#if busy}
<LoadingInfo wrapper message="Loading SQL preview" /> <LoadingInfo wrapper message={_t('sqlGenerator.loadingSqlPreview', { defaultMessage: "Loading SQL preview" })} />
{/if} {/if}
{/if} {/if}
</svelte:fragment> </svelte:fragment>
<svelte:fragment slot="2"> <svelte:fragment slot="2">
<div class="flexcol flex1"> <div class="flexcol flex1">
<WidgetTitle>Generator settings</WidgetTitle> <WidgetTitle>{_t('sqlGenerator.generatorSettings', { defaultMessage: 'Generator settings' })}</WidgetTitle>
<WidgetsInnerContainer> <WidgetsInnerContainer>
<FormValues let:values> <FormValues let:values>
<div class="obj-heading">Tables</div> <div class="obj-heading">{_t('sqlGenerator.tables', { defaultMessage: 'Tables' })}</div>
<FormCheckboxField label="Drop tables" name="dropTables" /> <FormCheckboxField label={_t('sqlGenerator.dropTables', { defaultMessage: 'Drop tables' })} name="dropTables" />
{#if values.dropTables} {#if values.dropTables}
<div class="ml-2"> <div class="ml-2">
<FormCheckboxField label="Test if exists" name="checkIfTableExists" /> <FormCheckboxField label={_t('sqlGenerator.testIfExists', { defaultMessage: 'Test if exists' })} name="checkIfTableExists" />
</div> </div>
{/if} {/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={_t('sqlGenerator.createTables', { defaultMessage: 'Create tables' })} name="createTables" />
<FormCheckboxField label="Create references" name="createReferences" /> <FormCheckboxField label={_t('sqlGenerator.createReferences', { defaultMessage: 'Create references' })} name="createReferences" />
<FormCheckboxField label="Create foreign keys" name="createForeignKeys" /> <FormCheckboxField label={_t('sqlGenerator.createForeignKeys', { defaultMessage: 'Create foreign keys' })} name="createForeignKeys" />
<FormCheckboxField label="Create indexes" name="createIndexes" /> <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} {#if values.insert}
<div class="ml-2"> <div class="ml-2">
<FormCheckboxField label="Skip autoincrement column" name="skipAutoincrementColumn" /> <FormCheckboxField label={_t('sqlGenerator.skipAutoincrementColumn', { defaultMessage: 'Skip autoincrement column' })} name="skipAutoincrementColumn" />
<FormCheckboxField label="Disable constraints" name="disableConstraints" /> <FormCheckboxField label={_t('sqlGenerator.disableConstraints', { defaultMessage: 'Disable constraints' })} name="disableConstraints" />
<FormCheckboxField label="Omit NULL values" name="omitNulls" /> <FormCheckboxField label={_t('sqlGenerator.omitNulls', { defaultMessage: 'Omit NULL values' })} name="omitNulls" />
</div> </div>
{/if} {/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} {#each ['View', 'Matview', 'Procedure', 'Function', 'Trigger', 'SchedulerEvent'] as objtype}
<div class="obj-heading">{getObjectTypeFieldLabel(objtype + 's')}</div> <div class="obj-heading">{getObjectTypeFieldLabel(objtype + 's')}</div>
<FormCheckboxField label="Create" name={`create${objtype}s`} /> <FormCheckboxField label={_t('sqlGenerator.create', { defaultMessage: 'Create {objtype}s', values: {objtype} })} name={`create${objtype}s`} />
<FormCheckboxField label="Drop" name={`drop${objtype}s`} /> <FormCheckboxField label={_t('sqlGenerator.drop', { defaultMessage: `Drop ${objtype}s` })} name={`drop${objtype}s`} />
{#if values[`drop${objtype}s`]} {#if values[`drop${objtype}s`]}
<div class="ml-2"> <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> </div>
{/if} {/if}
{/each} {/each}
@@ -241,8 +241,8 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<div class="flex m-2"> <div class="flex m-2">
<LargeButton on:click={editSql} icon="icon sql-file">Edit SQL</LargeButton> <LargeButton on:click={editSql} icon="icon sql-file">{_t('sqlGenerator.editSql', { defaultMessage: 'Edit SQL' })}</LargeButton>
<LargeButton on:click={closeCurrentModal} icon="icon close">Close</LargeButton> <LargeButton on:click={closeCurrentModal} icon="icon close">{_t('common.close', { defaultMessage: 'Close' })}</LargeButton>
</div> </div>
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>

View File

@@ -19,6 +19,7 @@
import FormConnectionSelect from '../impexp/FormConnectionSelect.svelte'; import FormConnectionSelect from '../impexp/FormConnectionSelect.svelte';
import FormDatabaseSelect from '../impexp/FormDatabaseSelect.svelte'; import FormDatabaseSelect from '../impexp/FormDatabaseSelect.svelte';
import { changeTab } from '../utility/common'; import { changeTab } from '../utility/common';
import { _t } from '../translations';
export let editingData; export let editingData;
export let callingTab; export let callingTab;
@@ -46,15 +47,15 @@
<FormProvider {initialValues}> <FormProvider {initialValues}>
<ModalBase {...$$restProps}> <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 /> <FormConnectionSelect name="conid" label={_t('switchDatabase.server', { defaultMessage: 'Server' })} direction="source" isNative />
<FormDatabaseSelect conidName="conid" name="database" label="Database" isNative /> <FormDatabaseSelect conidName="conid" name="database" label={_t('common.database', { defaultMessage: 'Database' })} isNative />
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormValues let:values> <FormValues let:values>
<FormSubmit value="OK" on:click={handleSubmit} /> <FormSubmit value={_t('common.ok', { defaultMessage: 'OK' })} on:click={handleSubmit} />
<FormButton value="Cancel" on:click={closeCurrentModal} /> <FormButton value={_t('common.cancel', { defaultMessage: 'Cancel' })} on:click={closeCurrentModal} />
</FormValues> </FormValues>
</svelte:fragment> </svelte:fragment>
</ModalBase> </ModalBase>

View File

@@ -141,7 +141,7 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
{#if multiselect} {#if multiselect}
<FormSubmit <FormSubmit
value="OK" value={_t('common.ok', { defaultMessage: 'OK' })}
on:click={() => { on:click={() => {
closeCurrentModal(); closeCurrentModal();
onConfirm(checkedKeys); onConfirm(checkedKeys);

View File

@@ -20,6 +20,7 @@
import type { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveCustomJoinConfig } from 'dbgate-datalib'; import type { ChangePerspectiveConfigFunc, PerspectiveConfig, PerspectiveCustomJoinConfig } from 'dbgate-datalib';
import uuidv1 from 'uuid/v1'; import uuidv1 from 'uuid/v1';
import TextField from '../forms/TextField.svelte'; import TextField from '../forms/TextField.svelte';
import { _t } from '../translations';
export let conid; export let conid;
export let database; export let database;
@@ -90,7 +91,7 @@
$: connections = useConnectionList(); $: connections = useConnectionList();
$: connectionOptions = [ $: connectionOptions = [
{ value: null, label: 'The same as root' }, { value: null, label: _t('customJoin.theSameAsRoot', { defaultMessage: 'The same as root' }) },
..._.sortBy( ..._.sortBy(
($connections || []) ($connections || [])
// .filter(x => !x.unsaved) // .filter(x => !x.unsaved)
@@ -107,7 +108,7 @@
$: databases = useDatabaseList({ conid: conidOverride || conid }); $: databases = useDatabaseList({ conid: conidOverride || conid });
$: databaseOptions = [ $: databaseOptions = [
{ value: null, label: 'The same as root' }, { value: null, label: _t('customJoin.theSameAsRoot', { defaultMessage: 'The same as root' }) },
..._.sortBy( ..._.sortBy(
($databases || []).map(db => ({ ($databases || []).map(db => ({
value: db.name, value: db.name,
@@ -147,11 +148,11 @@
<FormProvider> <FormProvider>
<ModalBase {...$$restProps}> <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="largeFormMarker">
<div class="row"> <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"> <div class="col-9">
<TextField <TextField
value={joinName} value={joinName}
@@ -164,7 +165,7 @@
</div> </div>
<div class="row"> <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"> <div class="col-9">
<SelectField <SelectField
value={fromDesignerId} value={fromDesignerId}
@@ -181,7 +182,7 @@
</div> </div>
<div class="row"> <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"> <div class="col-9">
<SelectField <SelectField
value={conidOverride} value={conidOverride}
@@ -195,7 +196,7 @@
</div> </div>
<div class="row"> <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"> <div class="col-9">
<SelectField <SelectField
value={databaseOverride} value={databaseOverride}
@@ -212,7 +213,7 @@
<FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} label="Database" /> --> <FormDatabaseSelect conidName={connectionIdField} name={databaseNameField} label="Database" /> -->
<div class="row"> <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"> <div class="col-9">
<SelectField <SelectField
value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })} value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })}
@@ -239,10 +240,10 @@
<div class="row"> <div class="row">
<div class="col-5 mr-1"> <div class="col-5 mr-1">
Base column - {fromTableInfo?.pureName} {_t('customJoin.baseColumn', { defaultMessage: 'Base column' })} - {fromTableInfo?.pureName}
</div> </div>
<div class="col-5 ml-1"> <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>
</div> </div>
@@ -286,7 +287,7 @@
</div> </div>
<div class="col-2 button"> <div class="col-2 button">
<FormStyledButton <FormStyledButton
value="Delete" value={_t('common.delete', { defaultMessage: 'Delete' })}
on:click={e => { on:click={e => {
const x = [...columns]; const x = [...columns];
x.splice(index, 1); x.splice(index, 1);
@@ -299,7 +300,7 @@
<FormStyledButton <FormStyledButton
type="button" type="button"
value="Add column" value={_t('customJoin.addColumn', { defaultMessage: 'Add column' })}
on:click={() => { on:click={() => {
columns = [ columns = [
...columns, ...columns,
@@ -314,7 +315,7 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormSubmit <FormSubmit
value={'Save'} value={_t('common.save', { defaultMessage: 'Save' })}
on:click={() => { on:click={() => {
setConfig(cfg => { setConfig(cfg => {
const newNode = createPerspectiveNodeConfig({ pureName: refTableName, schemaName: refSchemaName }); 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> </svelte:fragment>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -8,6 +8,7 @@
import { downloadFromApi } from '../utility/exportFileTools'; import { downloadFromApi } from '../utility/exportFileTools';
import useEffect from '../utility/useEffect'; import useEffect from '../utility/useEffect';
import Link from '../elements/Link.svelte'; import Link from '../elements/Link.svelte';
import { _t } from '../translations';
export let runnerId; export let runnerId;
export let executeNumber; export let executeNumber;
@@ -40,28 +41,28 @@
</script> </script>
{#if !files || files.length == 0} {#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} {:else}
<div class="flex1 scroll"> <div class="flex1 scroll">
<TableControl <TableControl
rows={files} rows={files}
stickyHeader stickyHeader
columns={[ columns={[
{ fieldName: 'name', header: 'Name' }, { fieldName: 'name', header: _t('query.Name', { defaultMessage: 'Name' }) },
{ fieldName: 'size', header: 'Size', formatter: row => formatFileSize(row.size) }, { fieldName: 'size', header: _t('query.Size', { defaultMessage: 'Size' }), formatter: row => formatFileSize(row.size) },
!electron && { !electron && {
fieldName: 'download', fieldName: 'download',
header: 'Download', header: _t('query.Download', { defaultMessage: 'Download' }),
slot: 0, slot: 0,
}, },
electron && { electron && {
fieldName: 'copy', fieldName: 'copy',
header: 'Copy', header: _t('query.Copy', { defaultMessage: 'Copy' }),
slot: 1, slot: 1,
}, },
electron && { electron && {
fieldName: 'show', fieldName: 'show',
header: 'Show', header: _t('query.Show', { defaultMessage: 'Show' }),
slot: 2, slot: 2,
}, },
]} ]}
@@ -72,7 +73,7 @@
downloadFromApi(`runners/data/${runnerId}/${row.name}`, row.name); downloadFromApi(`runners/data/${runnerId}/${row.name}`, row.name);
}} }}
> >
download {_t('query.download', { defaultMessage: 'download' })}
</Link> </Link>
</svelte:fragment> </svelte:fragment>
@@ -86,7 +87,7 @@
} }
}} }}
> >
save {_t('query.save', { defaultMessage: 'save' })}
</Link> </Link>
</svelte:fragment> </svelte:fragment>
@@ -96,7 +97,7 @@
electron.showItemInFolder(row.path); electron.showItemInFolder(row.path);
}} }}
> >
show {_t('query.show', { defaultMessage: 'show' })}
</Link> </Link>
</svelte:fragment> </svelte:fragment>
</TableControl> </TableControl>

View File

@@ -3,6 +3,7 @@
import WidgetTitle from '../widgets/WidgetTitle.svelte'; import WidgetTitle from '../widgets/WidgetTitle.svelte';
import RunnerOutputFiles from './RunnerOutputFiles.svelte'; import RunnerOutputFiles from './RunnerOutputFiles.svelte';
import SocketMessageView from './SocketMessageView.svelte'; import SocketMessageView from './SocketMessageView.svelte';
import { _t } from '../translations';
export let runnerId; export let runnerId;
export let executeNumber; export let executeNumber;
@@ -10,7 +11,7 @@
<HorizontalSplitter> <HorizontalSplitter>
<div class="container" slot="1"> <div class="container" slot="1">
<WidgetTitle>Messages</WidgetTitle> <WidgetTitle>{_t('query.Messages', { defaultMessage: 'Messages' })}</WidgetTitle>
<SocketMessageView <SocketMessageView
eventName={runnerId ? `runner-info-${runnerId}` : null} eventName={runnerId ? `runner-info-${runnerId}` : null}
{executeNumber} {executeNumber}
@@ -19,7 +20,7 @@
/> />
</div> </div>
<div class="container" slot="2"> <div class="container" slot="2">
<WidgetTitle>Output files</WidgetTitle> <WidgetTitle>{_t('query.OutputFiles', { defaultMessage: 'Output files' })}</WidgetTitle>
<RunnerOutputFiles {runnerId} {executeNumber} /> <RunnerOutputFiles {runnerId} {executeNumber} />
</div> </div>
</HorizontalSplitter> </HorizontalSplitter>

View File

@@ -3,6 +3,7 @@
import ErrorInfo from '../elements/ErrorInfo.svelte'; import ErrorInfo from '../elements/ErrorInfo.svelte';
import { apiOff, apiOn } from '../utility/api'; import { apiOff, apiOn } from '../utility/api';
import createRef from '../utility/createRef'; import createRef from '../utility/createRef';
import { _t } from '../translations';
import useEffect from '../utility/useEffect'; import useEffect from '../utility/useEffect';
@@ -75,7 +76,7 @@
</script> </script>
{#if showNoMessagesAlert && (!displayedMessages || displayedMessages.length == 0)} {#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} {:else}
<MessageView <MessageView
items={displayedMessages} items={displayedMessages}

View File

@@ -12,6 +12,7 @@
import { onMount, tick } from 'svelte'; import { onMount, tick } from 'svelte';
import TargetApplicationSelect from '../forms/TargetApplicationSelect.svelte'; import TargetApplicationSelect from '../forms/TargetApplicationSelect.svelte';
import { apiCall } from '../utility/api'; import { apiCall } from '../utility/api';
import { _t } from '../translations';
// import { apiCall } from '../utility/api'; // import { apiCall } from '../utility/api';
// import { saveDbToApp } from '../utility/appTools'; // import { saveDbToApp } from '../utility/appTools';
@@ -70,11 +71,11 @@
<FormProvider> <FormProvider>
<ModalBase {...$$restProps}> <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="largeFormMarker">
<div class="row"> <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"> <div class="col-9">
<SelectField <SelectField
value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })} value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })}
@@ -105,10 +106,10 @@
<div class="row"> <div class="row">
<div class="col-5 mr-1"> <div class="col-5 mr-1">
Base column - {$tableInfo?.pureName} {_t('virtualForeignKey.baseColumn', { defaultMessage: 'Base column' })} - {$tableInfo?.pureName}
</div> </div>
<div class="col-5 ml-1"> <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>
</div> </div>
@@ -152,7 +153,7 @@
</div> </div>
<div class="col-2 button"> <div class="col-2 button">
<FormStyledButton <FormStyledButton
value="Delete" value={_t('common.delete', { defaultMessage: 'Delete' })}
on:click={e => { on:click={e => {
const x = [...columns]; const x = [...columns];
x.splice(index, 1); x.splice(index, 1);
@@ -165,14 +166,14 @@
<FormStyledButton <FormStyledButton
type="button" type="button"
value="Add column" value={_t('virtualForeignKey.addColumn', { defaultMessage: 'Add column' })}
on:click={() => { on:click={() => {
columns = [...columns, {}]; columns = [...columns, {}];
}} }}
/> />
<div class="row"> <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"> <div class="col-9">
<TargetApplicationSelect bind:value={dstApp} {conid} {database} /> <TargetApplicationSelect bind:value={dstApp} {conid} {database} />
</div> </div>
@@ -181,7 +182,7 @@
<svelte:fragment slot="footer"> <svelte:fragment slot="footer">
<FormSubmit <FormSubmit
value={'Save'} value={_t('common.save', { defaultMessage: 'Save' })}
disabled={!dstApp} disabled={!dstApp}
on:click={async () => { on:click={async () => {
await apiCall('apps/save-virtual-reference', { 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> </svelte:fragment>
</ModalBase> </ModalBase>
</FormProvider> </FormProvider>

View File

@@ -169,6 +169,7 @@
import hasPermission from '../utility/hasPermission'; import hasPermission from '../utility/hasPermission';
import QueryAiAssistant from '../ai/QueryAiAssistant.svelte'; import QueryAiAssistant from '../ai/QueryAiAssistant.svelte';
import { getCurrentSettings } from '../stores'; import { getCurrentSettings } from '../stores';
import { Messages } from 'openai/resources/chat/completions';
export let tabid; export let tabid;
export let conid; export let conid;
@@ -765,7 +766,7 @@
<svelte:fragment slot="2"> <svelte:fragment slot="2">
<ResultTabs <ResultTabs
bind:this={domResultTabs} bind:this={domResultTabs}
tabs={[{ label: 'Messages', slot: 0 }]} tabs={[{ label: _t('query.Messages', { defaultMessage: 'Messages' }), slot: 0 }]}
{sessionId} {sessionId}
{executeNumber} {executeNumber}
bind:resultCount bind:resultCount