mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-21 02:25:59 +00:00
define virtual fk
This commit is contained in:
@@ -3,9 +3,11 @@
|
||||
const connProps: any = {};
|
||||
let tooltip = undefined;
|
||||
|
||||
const savedFile = fileType == 'vfk.json' ? fileName : fileName + '.' + fileType;
|
||||
|
||||
const resp = await apiCall('files/load', {
|
||||
folder: 'app:' + folderName,
|
||||
file: fileName + '.' + fileType,
|
||||
file: savedFile,
|
||||
format: 'text',
|
||||
});
|
||||
|
||||
@@ -16,7 +18,7 @@
|
||||
tabComponent,
|
||||
tooltip,
|
||||
props: {
|
||||
savedFile: fileName + '.' + fileType,
|
||||
savedFile,
|
||||
savedFolder: 'app:' + folderName,
|
||||
savedFormat: 'text',
|
||||
appFolder: folderName,
|
||||
@@ -30,6 +32,7 @@
|
||||
export const extractKey = data => data.fileName;
|
||||
export const createMatcher = ({ fileName }) => filter => filterName(filter, fileName);
|
||||
const APP_ICONS = {
|
||||
'vfk.json': 'img json',
|
||||
'command.sql': 'img app-command',
|
||||
'query.sql': 'img app-query',
|
||||
};
|
||||
@@ -85,12 +88,15 @@
|
||||
if (data.fileType.endsWith('.sql')) {
|
||||
handleOpenSqlFile();
|
||||
}
|
||||
if (data.fileType.endsWith('.json')) {
|
||||
handleOpenJsonFile();
|
||||
}
|
||||
};
|
||||
const handleOpenSqlFile = () => {
|
||||
openTextFile(data.fileName, data.fileType, data.folderName, 'QueryTab', 'img sql-file');
|
||||
};
|
||||
const handleOpenYamlFile = () => {
|
||||
openTextFile(data.fileName, data.fileType, data.folderName, 'YamlEditorTab', 'img yaml');
|
||||
const handleOpenJsonFile = () => {
|
||||
openTextFile(data.fileName, data.fileType, data.folderName, 'JsonEditorTab', 'img json');
|
||||
};
|
||||
|
||||
function createMenu() {
|
||||
@@ -98,6 +104,7 @@
|
||||
{ text: 'Delete', onClick: handleDelete },
|
||||
{ text: 'Rename', onClick: handleRename },
|
||||
data.fileType.endsWith('.sql') && { text: 'Open SQL', onClick: handleOpenSqlFile },
|
||||
data.fileType.endsWith('.json') && { text: 'Open JSON', onClick: handleOpenJsonFile },
|
||||
|
||||
// data.fileType.endsWith('.yaml') && { text: 'Open YAML', onClick: handleOpenYamlFile },
|
||||
];
|
||||
|
||||
@@ -1,18 +1,69 @@
|
||||
<script lang="ts" context="module">
|
||||
export async function saveDbToApp(conid, database, app) {
|
||||
if (app == '#new') {
|
||||
const folder = await apiCall('apps/create-folder', { folder: database });
|
||||
|
||||
await apiCall('connections/update-database', {
|
||||
conid,
|
||||
database,
|
||||
values: {
|
||||
[`useApp:${folder}`]: true,
|
||||
},
|
||||
});
|
||||
|
||||
return folder;
|
||||
}
|
||||
|
||||
await apiCall('connections/update-database', {
|
||||
conid,
|
||||
database,
|
||||
values: {
|
||||
[`useApp:${app}`]: true,
|
||||
},
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { map } from 'lodash';
|
||||
import _ from 'lodash';
|
||||
import { filterAppsForDatabase } from '../appobj/DatabaseAppObject.svelte';
|
||||
|
||||
import SelectField from '../forms/SelectField.svelte';
|
||||
import { useAppFolders } from '../utility/metadataLoaders';
|
||||
import { currentDatabase } from '../stores';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { useAppFolders, useUsedApps } from '../utility/metadataLoaders';
|
||||
|
||||
$: apps = useAppFolders();
|
||||
export let value = '#new';
|
||||
|
||||
$: appFolders = useAppFolders();
|
||||
$: usedApps = useUsedApps();
|
||||
|
||||
$: {
|
||||
if (value == '#new' && $currentDatabase) {
|
||||
const filtered = filterAppsForDatabase($currentDatabase.connection, $currentDatabase.name, $usedApps || []);
|
||||
const common = _.intersection(
|
||||
($appFolders || []).map(x => x.name),
|
||||
filtered.map(x => x.name)
|
||||
);
|
||||
if (common.length > 0) {
|
||||
value = common[0] as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<SelectField
|
||||
isNative
|
||||
{...$$restProps}
|
||||
{value}
|
||||
on:change={e => {
|
||||
value = e.detail;
|
||||
}}
|
||||
options={[
|
||||
{ label: '(New application linked to current DB)', value: 'new' },
|
||||
...($apps || []).map(app => ({
|
||||
{ label: '(New application linked to current DB)', value: '#new' },
|
||||
...($appFolders || []).map(app => ({
|
||||
label: app.name,
|
||||
value: app.name,
|
||||
})),
|
||||
|
||||
@@ -81,7 +81,7 @@
|
||||
value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })}
|
||||
isNative
|
||||
notSelected
|
||||
options={(dbInfo?.tables || []).map(tbl => ({
|
||||
options={_.sortBy(dbInfo?.tables || [], ['schemaName', 'pureName']).map(tbl => ({
|
||||
label: fullNameToLabel(tbl),
|
||||
value: fullNameToString(tbl),
|
||||
}))}
|
||||
|
||||
@@ -1,32 +1,17 @@
|
||||
<script lang="ts">
|
||||
import FormStyledButton from '../elements/FormStyledButton.svelte';
|
||||
import uuidv1 from 'uuid/v1';
|
||||
|
||||
import FormSelectField from '../forms/FormSelectField.svelte';
|
||||
import FormTextField from '../forms/FormTextField.svelte';
|
||||
import FormCheckboxField from '../forms/FormCheckboxField.svelte';
|
||||
|
||||
import FormProvider from '../forms/FormProvider.svelte';
|
||||
import FormSubmit from '../forms/FormSubmit.svelte';
|
||||
import ModalBase from '../modals/ModalBase.svelte';
|
||||
import { closeCurrentModal } from '../modals/modalTools';
|
||||
import ElectronFilesInput from '../impexp/ElectronFilesInput.svelte';
|
||||
import DropDownButton from '../elements/DropDownButton.svelte';
|
||||
import DataTypeEditor from './DataTypeEditor.svelte';
|
||||
import {
|
||||
editorAddConstraint,
|
||||
editorDeleteConstraint,
|
||||
editorModifyConstraint,
|
||||
fullNameFromString,
|
||||
fullNameToLabel,
|
||||
fullNameToString,
|
||||
} from 'dbgate-tools';
|
||||
import TextField from '../forms/TextField.svelte';
|
||||
import { fullNameFromString, fullNameToLabel, fullNameToString } from 'dbgate-tools';
|
||||
import SelectField from '../forms/SelectField.svelte';
|
||||
import _ from 'lodash';
|
||||
import { useDatabaseInfo, useTableInfo } from '../utility/metadataLoaders';
|
||||
import { onMount } from 'svelte';
|
||||
import TargetApplicationSelect from '../elements/TargetApplicationSelect.svelte';
|
||||
import TargetApplicationSelect, { saveDbToApp } from '../elements/TargetApplicationSelect.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
|
||||
export let conid;
|
||||
export let database;
|
||||
@@ -34,6 +19,8 @@
|
||||
export let pureName;
|
||||
export let columnName;
|
||||
|
||||
let dstApp;
|
||||
|
||||
const dbInfo = useDatabaseInfo({ conid, database });
|
||||
const tableInfo = useTableInfo({ conid, database, schemaName, pureName });
|
||||
|
||||
@@ -69,7 +56,10 @@
|
||||
value={fullNameToString({ pureName: refTableName, schemaName: refSchemaName })}
|
||||
isNative
|
||||
notSelected
|
||||
options={[...($dbInfo?.tables || []), ...($dbInfo?.views || [])].map(tbl => ({
|
||||
options={[
|
||||
..._.sortBy($dbInfo?.tables || [], ['schemaName', 'pureName']),
|
||||
..._.sortBy($dbInfo?.views || [], ['schemaName', 'pureName']),
|
||||
].map(tbl => ({
|
||||
label: fullNameToLabel(tbl),
|
||||
value: fullNameToString(tbl),
|
||||
}))}
|
||||
@@ -155,7 +145,7 @@
|
||||
<div class="row">
|
||||
<div class="label col-3">Target application</div>
|
||||
<div class="col-9">
|
||||
<TargetApplicationSelect />
|
||||
<TargetApplicationSelect bind:value={dstApp} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -163,7 +153,16 @@
|
||||
<svelte:fragment slot="footer">
|
||||
<FormSubmit
|
||||
value={'Save'}
|
||||
on:click={() => {
|
||||
on:click={async () => {
|
||||
const appFolder = await saveDbToApp(conid, database, dstApp);
|
||||
await apiCall('apps/save-vfk', {
|
||||
appFolder,
|
||||
schemaName,
|
||||
pureName,
|
||||
refSchemaName,
|
||||
refTableName,
|
||||
columns,
|
||||
});
|
||||
closeCurrentModal();
|
||||
}}
|
||||
/>
|
||||
|
||||
83
packages/web/src/tabs/JsonEditorTab.svelte
Normal file
83
packages/web/src/tabs/JsonEditorTab.svelte
Normal file
@@ -0,0 +1,83 @@
|
||||
<script lang="ts" context="module">
|
||||
const getCurrentEditor = () => getActiveComponent('JsonEditorTab');
|
||||
|
||||
registerFileCommands({
|
||||
idPrefix: 'json',
|
||||
category: 'Json',
|
||||
getCurrentEditor,
|
||||
folder: 'yaml',
|
||||
format: 'text',
|
||||
fileExtension: 'json',
|
||||
|
||||
toggleComment: true,
|
||||
findReplace: true,
|
||||
});
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import { registerFileCommands } from '../commands/stdCommands';
|
||||
|
||||
import AceEditor from '../query/AceEditor.svelte';
|
||||
import useEditorData from '../query/useEditorData';
|
||||
import invalidateCommands from '../commands/invalidateCommands';
|
||||
import createActivator, { getActiveComponent } from '../utility/createActivator';
|
||||
|
||||
export let tabid;
|
||||
|
||||
const tabVisible: any = getContext('tabVisible');
|
||||
|
||||
export const activator = createActivator('JsonEditorTab', false);
|
||||
|
||||
let domEditor;
|
||||
|
||||
$: if ($tabVisible && domEditor) {
|
||||
domEditor?.getEditor()?.focus();
|
||||
}
|
||||
|
||||
export function getData() {
|
||||
return $editorState.value || '';
|
||||
}
|
||||
|
||||
export function toggleComment() {
|
||||
domEditor.getEditor().execCommand('togglecomment');
|
||||
}
|
||||
|
||||
export function find() {
|
||||
domEditor.getEditor().execCommand('find');
|
||||
}
|
||||
|
||||
export function replace() {
|
||||
domEditor.getEditor().execCommand('replace');
|
||||
}
|
||||
|
||||
export function getTabId() {
|
||||
return tabid;
|
||||
}
|
||||
|
||||
const { editorState, editorValue, setEditorData, saveToStorage } = useEditorData({ tabid });
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
{ command: 'json.toggleComment' },
|
||||
{ divider: true },
|
||||
{ command: 'json.save' },
|
||||
{ command: 'json.saveAs' },
|
||||
{ divider: true },
|
||||
{ command: 'json.find' },
|
||||
{ command: 'json.replace' },
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<AceEditor
|
||||
value={$editorState.value || ''}
|
||||
menu={createMenu()}
|
||||
on:input={e => setEditorData(e.detail)}
|
||||
on:focus={() => {
|
||||
activator.activate();
|
||||
invalidateCommands();
|
||||
}}
|
||||
bind:this={domEditor}
|
||||
mode="json"
|
||||
/>
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
const tabVisible: any = getContext('tabVisible');
|
||||
|
||||
export const activator = createActivator('MarkdownEditorTab', false);
|
||||
export const activator = createActivator('YamlEditorTab', false);
|
||||
|
||||
let domEditor;
|
||||
|
||||
@@ -63,8 +63,6 @@
|
||||
|
||||
function createMenu() {
|
||||
return [
|
||||
{ command: 'yaml.preview' },
|
||||
{ divider: true },
|
||||
{ command: 'yaml.toggleComment' },
|
||||
{ divider: true },
|
||||
{ command: 'yaml.save' },
|
||||
|
||||
@@ -15,6 +15,7 @@ import * as FavoriteEditorTab from './FavoriteEditorTab.svelte';
|
||||
import * as QueryDesignTab from './QueryDesignTab.svelte';
|
||||
import * as CommandListTab from './CommandListTab.svelte';
|
||||
import * as YamlEditorTab from './YamlEditorTab.svelte';
|
||||
import * as JsonEditorTab from './JsonEditorTab.svelte';
|
||||
import * as CompareModelTab from './CompareModelTab.svelte';
|
||||
import * as JsonTab from './JsonTab.svelte';
|
||||
import * as ChangelogTab from './ChangelogTab.svelte';
|
||||
@@ -38,6 +39,7 @@ export default {
|
||||
QueryDesignTab,
|
||||
CommandListTab,
|
||||
YamlEditorTab,
|
||||
JsonEditorTab,
|
||||
CompareModelTab,
|
||||
JsonTab,
|
||||
ChangelogTab,
|
||||
|
||||
Reference in New Issue
Block a user