mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-19 18:56:00 +00:00
SYNC: Merge pull request #9 from dbgate/feature/apps
This commit is contained in:
@@ -1,120 +0,0 @@
|
||||
<script lang="ts" context="module">
|
||||
const APP_LABELS = {
|
||||
'command.sql': 'SQL commands',
|
||||
'query.sql': 'SQL queries',
|
||||
};
|
||||
|
||||
const COMMAND_TEMPLATE = `-- Write SQL command here
|
||||
-- After save, you can execute it from database context menu, for all databases, which use this application
|
||||
`;
|
||||
|
||||
const QUERY_TEMPLATE = `-- Write SQL query here
|
||||
-- After save, you can view it in tables list, for all databases, which use this application
|
||||
`;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { createFreeTableModel } from 'dbgate-datalib';
|
||||
|
||||
import _ from 'lodash';
|
||||
|
||||
import AppObjectList from '../appobj/AppObjectList.svelte';
|
||||
import * as appFileAppObject from '../appobj/AppFileAppObject.svelte';
|
||||
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
|
||||
import DropDownButton from '../buttons/DropDownButton.svelte';
|
||||
|
||||
import InlineButton from '../buttons/InlineButton.svelte';
|
||||
|
||||
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
|
||||
import SearchInput from '../elements/SearchInput.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import newQuery from '../query/newQuery';
|
||||
import { currentApplication } from '../stores';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { useAppFiles, useArchiveFolders } from '../utility/metadataLoaders';
|
||||
import openNewTab from '../utility/openNewTab';
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
import { showSnackbarError } from '../utility/snackbar';
|
||||
|
||||
let filter = '';
|
||||
|
||||
$: folder = $currentApplication;
|
||||
$: files = useAppFiles({ folder });
|
||||
|
||||
const handleRefreshFiles = () => {
|
||||
apiCall('apps/refresh-files', { folder });
|
||||
};
|
||||
|
||||
function handleNewSqlFile(fileType, header, initialData) {
|
||||
showModal(InputTextModal, {
|
||||
value: '',
|
||||
label: 'New file name',
|
||||
header,
|
||||
onConfirm: async file => {
|
||||
newQuery({
|
||||
title: file,
|
||||
initialData,
|
||||
// @ts-ignore
|
||||
savedFile: file + '.' + fileType,
|
||||
savedFolder: 'app:' + $currentApplication,
|
||||
savedFormat: 'text',
|
||||
appFolder: $currentApplication,
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function handleNewConfigFile(fileName, content) {
|
||||
if (!(await apiCall('apps/create-config-file', { fileName, content, appFolder: $currentApplication }))) {
|
||||
showSnackbarError('File not created, probably already exists');
|
||||
}
|
||||
}
|
||||
|
||||
function createAddMenu() {
|
||||
return [
|
||||
{
|
||||
text: 'New SQL command',
|
||||
onClick: () => handleNewSqlFile('command.sql', 'Create new SQL command', COMMAND_TEMPLATE),
|
||||
},
|
||||
{
|
||||
text: 'New SQL query',
|
||||
onClick: () => handleNewSqlFile('query.sql', 'Create new SQL query', QUERY_TEMPLATE),
|
||||
},
|
||||
{
|
||||
text: 'New virtual references file',
|
||||
onClick: () => handleNewConfigFile('virtual-references.config.json', []),
|
||||
},
|
||||
{
|
||||
text: 'New dictionary descriptions file',
|
||||
onClick: () => handleNewConfigFile('dictionary-descriptions.config.json', []),
|
||||
},
|
||||
|
||||
// { text: 'New query view', onClick: () => handleNewSqlFile('query.sql', 'Create new SQL query', QUERY_TEMPLATE) },
|
||||
];
|
||||
}
|
||||
</script>
|
||||
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search application files" bind:value={filter} />
|
||||
|
||||
<CloseSearchButton bind:filter />
|
||||
<DropDownButton icon="icon plus-thick" menu={createAddMenu} />
|
||||
<InlineButton on:click={handleRefreshFiles} title="Refresh files of selected application">
|
||||
<FontIcon icon="icon refresh" />
|
||||
</InlineButton>
|
||||
</SearchBoxWrapper>
|
||||
<WidgetsInnerContainer>
|
||||
<AppObjectList
|
||||
list={($files || []).map(file => ({
|
||||
fileName: file.name,
|
||||
folderName: folder,
|
||||
fileType: file.type,
|
||||
fileLabel: file.label,
|
||||
}))}
|
||||
groupFunc={data => APP_LABELS[data.fileType] || 'App config'}
|
||||
module={appFileAppObject}
|
||||
{filter}
|
||||
/>
|
||||
</WidgetsInnerContainer>
|
||||
@@ -1,39 +0,0 @@
|
||||
<script lang="ts">
|
||||
import _ from 'lodash';
|
||||
|
||||
import AppObjectList from '../appobj/AppObjectList.svelte';
|
||||
import * as appFolderAppObject from '../appobj/AppFolderAppObject.svelte';
|
||||
import runCommand from '../commands/runCommand';
|
||||
import CloseSearchButton from '../buttons/CloseSearchButton.svelte';
|
||||
|
||||
import InlineButton from '../buttons/InlineButton.svelte';
|
||||
|
||||
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
|
||||
import SearchInput from '../elements/SearchInput.svelte';
|
||||
import FontIcon from '../icons/FontIcon.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import { useAppFolders } from '../utility/metadataLoaders';
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
|
||||
let filter = '';
|
||||
|
||||
$: folders = useAppFolders();
|
||||
|
||||
const handleRefreshFolders = () => {
|
||||
apiCall('apps/refresh-folders');
|
||||
};
|
||||
</script>
|
||||
|
||||
<SearchBoxWrapper>
|
||||
<SearchInput placeholder="Search applications" bind:value={filter} />
|
||||
<CloseSearchButton bind:filter />
|
||||
<InlineButton on:click={() => runCommand('new.application')} title="Create new application">
|
||||
<FontIcon icon="icon plus-thick" />
|
||||
</InlineButton>
|
||||
<InlineButton on:click={handleRefreshFolders} title="Refresh application list">
|
||||
<FontIcon icon="icon refresh" />
|
||||
</InlineButton>
|
||||
</SearchBoxWrapper>
|
||||
<WidgetsInnerContainer>
|
||||
<AppObjectList list={_.sortBy($folders, 'name')} module={appFolderAppObject} {filter} />
|
||||
</WidgetsInnerContainer>
|
||||
@@ -1,19 +0,0 @@
|
||||
<script lang="ts">
|
||||
import AppFilesList from './AppFilesList.svelte';
|
||||
|
||||
import WidgetColumnBar from './WidgetColumnBar.svelte';
|
||||
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
|
||||
|
||||
import { useFavorites } from '../utility/metadataLoaders';
|
||||
import AppFolderList from './AppFolderList.svelte';
|
||||
</script>
|
||||
|
||||
<WidgetColumnBar>
|
||||
<WidgetColumnBarItem title="Applications" name="apps" height="30%" storageName="appsWidget">
|
||||
<AppFolderList />
|
||||
</WidgetColumnBarItem>
|
||||
|
||||
<WidgetColumnBarItem title="Application files" name="files" storageName="appFilesWidget">
|
||||
<AppFilesList />
|
||||
</WidgetColumnBarItem>
|
||||
</WidgetColumnBar>
|
||||
@@ -12,6 +12,7 @@
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
import { isProApp } from '../utility/proTools';
|
||||
import InlineUploadButton from '../buttons/InlineUploadButton.svelte';
|
||||
import { DATA_FOLDER_NAMES } from 'dbgate-tools';
|
||||
|
||||
let filter = '';
|
||||
|
||||
@@ -27,6 +28,7 @@
|
||||
const dbCompareJobFiles = useFiles({ folder: 'dbcompare' });
|
||||
const perspectiveFiles = useFiles({ folder: 'perspectives' });
|
||||
const modelTransformFiles = useFiles({ folder: 'modtrans' });
|
||||
const appFiles = useFiles({ folder: 'apps' });
|
||||
|
||||
$: files = [
|
||||
...($sqlFiles || []),
|
||||
@@ -41,32 +43,18 @@
|
||||
...($modelTransformFiles || []),
|
||||
...((isProApp() && $dataDeployJobFiles) || []),
|
||||
...((isProApp() && $dbCompareJobFiles) || []),
|
||||
...((isProApp() && $appFiles) || []),
|
||||
];
|
||||
|
||||
function handleRefreshFiles() {
|
||||
apiCall('files/refresh', {
|
||||
folders: [
|
||||
'sql',
|
||||
'shell',
|
||||
'markdown',
|
||||
'charts',
|
||||
'query',
|
||||
'sqlite',
|
||||
'diagrams',
|
||||
'perspectives',
|
||||
'impexp',
|
||||
'modtrans',
|
||||
'datadeploy',
|
||||
'dbcompare',
|
||||
],
|
||||
folders: DATA_FOLDER_NAMES.map(folder => folder.name),
|
||||
});
|
||||
}
|
||||
|
||||
function dataFolderTitle(folder) {
|
||||
if (folder == 'modtrans') return 'Model transforms';
|
||||
if (folder == 'datadeploy') return 'Data deploy jobs';
|
||||
if (folder == 'dbcompare') return 'Database compare jobs';
|
||||
return _.startCase(folder);
|
||||
const foundFolder = DATA_FOLDER_NAMES.find(f => f.name === folder);
|
||||
return foundFolder ? foundFolder.label : _.startCase(folder);
|
||||
}
|
||||
|
||||
async function handleUploadedFile(filePath, fileName) {
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
import SearchInput from '../elements/SearchInput.svelte';
|
||||
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
|
||||
import {
|
||||
useAllApps,
|
||||
useConnectionInfo,
|
||||
useDatabaseInfo,
|
||||
useDatabaseStatus,
|
||||
useSchemaList,
|
||||
useUsedApps,
|
||||
} from '../utility/metadataLoaders';
|
||||
import SearchBoxWrapper from '../elements/SearchBoxWrapper.svelte';
|
||||
import AppObjectList from '../appobj/AppObjectList.svelte';
|
||||
@@ -73,9 +73,8 @@
|
||||
$: connection = useConnectionInfo({ conid });
|
||||
$: driver = findEngineDriver($connection, $extensions);
|
||||
|
||||
$: apps = useUsedApps();
|
||||
|
||||
$: dbApps = filterAppsForDatabase($currentDatabase?.connection, $currentDatabase?.name, $apps || []);
|
||||
$: apps = useAllApps();
|
||||
$: appsForDb = filterAppsForDatabase($connection, database, $apps || [], $objects);
|
||||
|
||||
// $: console.log('OBJECTS', $objects);
|
||||
|
||||
@@ -87,13 +86,14 @@
|
||||
['schemaName', 'pureName']
|
||||
)
|
||||
),
|
||||
...dbApps.map(app =>
|
||||
app.queries.map(query => ({
|
||||
objectTypeField: 'queries',
|
||||
pureName: query.name,
|
||||
schemaName: app.name,
|
||||
sql: query.sql,
|
||||
}))
|
||||
...appsForDb.map(app =>
|
||||
Object.values(app.files || {})
|
||||
.filter(x => x.type == 'query')
|
||||
.map(query => ({
|
||||
objectTypeField: 'queries',
|
||||
pureName: query.label,
|
||||
sql: query.sql,
|
||||
}))
|
||||
),
|
||||
]);
|
||||
|
||||
@@ -281,7 +281,7 @@
|
||||
>
|
||||
<AppObjectList
|
||||
list={objectList
|
||||
.filter(x => ($appliedCurrentSchema ? x.schemaName == $appliedCurrentSchema : true))
|
||||
.filter(x => x.schemaName == null || ($appliedCurrentSchema ? x.schemaName == $appliedCurrentSchema : true))
|
||||
.map(x => ({ ...x, conid, database }))}
|
||||
module={databaseObjectAppObject}
|
||||
groupFunc={data => getObjectTypeFieldLabel(data.objectTypeField, driver)}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
import PluginsWidget from './PluginsWidget.svelte';
|
||||
import CellDataWidget from './CellDataWidget.svelte';
|
||||
import HistoryWidget from './HistoryWidget.svelte';
|
||||
import AppWidget from './AppWidget.svelte';
|
||||
import AdminMenuWidget from './AdminMenuWidget.svelte';
|
||||
import AdminPremiumPromoWidget from './AdminPremiumPromoWidget.svelte';
|
||||
import PublicCloudWidget from './PublicCloudWidget.svelte';
|
||||
@@ -14,8 +13,9 @@
|
||||
import hasPermission from '../utility/hasPermission';
|
||||
</script>
|
||||
|
||||
<DatabaseWidget hidden={$visibleSelectedWidget != 'database'} />
|
||||
|
||||
{#if hasPermission('widgets/database')}
|
||||
<DatabaseWidget hidden={$visibleSelectedWidget != 'database'} />
|
||||
{/if}
|
||||
{#if $visibleSelectedWidget == 'file' && hasPermission('widgets/file')}
|
||||
<FilesWidget />
|
||||
{/if}
|
||||
@@ -31,9 +31,6 @@
|
||||
{#if $visibleSelectedWidget == 'cell-data' && hasPermission('widgets/cell-data')}
|
||||
<CellDataWidget />
|
||||
{/if}
|
||||
{#if $visibleSelectedWidget == 'app' && hasPermission('widgets/app')}
|
||||
<AppWidget />
|
||||
{/if}
|
||||
{#if $visibleSelectedWidget == 'admin' && hasPermission('widgets/admin')}
|
||||
<AdminMenuWidget />
|
||||
{/if}
|
||||
|
||||
@@ -110,13 +110,6 @@
|
||||
hasPermission('settings/change') && { command: 'settings.show' },
|
||||
{ command: 'theme.changeTheme' },
|
||||
hasPermission('settings/change') && { command: 'settings.commands' },
|
||||
hasPermission('widgets/app') && {
|
||||
text: 'View applications',
|
||||
onClick: () => {
|
||||
$selectedWidget = 'app';
|
||||
$visibleWidgetSideBar = true;
|
||||
},
|
||||
},
|
||||
hasPermission('widgets/plugins') && {
|
||||
text: 'Manage plugins',
|
||||
onClick: () => {
|
||||
|
||||
Reference in New Issue
Block a user