define virtual fk

This commit is contained in:
Jan Prochazka
2022-01-28 17:36:40 +01:00
parent 20938fb6ce
commit a47973d58d
8 changed files with 220 additions and 37 deletions

View File

@@ -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 },
];

View File

@@ -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,
})),

View File

@@ -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),
}))}

View File

@@ -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();
}}
/>

View 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"
/>

View File

@@ -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' },

View File

@@ -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,