files widget

This commit is contained in:
Jan Prochazka
2021-03-11 09:42:14 +01:00
parent a93aff1bb7
commit d5ebea3764
20 changed files with 296 additions and 33 deletions

View File

@@ -1,7 +1,7 @@
<script context="module">
const getContextMenu = (data, $openedConnections) => () => {
const handleRefresh = () => {
axios.post('server-connections/refresh', { conid: data._id });
axiosInstance.post('server-connections/refresh', { conid: data._id });
};
const handleDisconnect = () => {
openedConnections.update(list => list.filter(x => x != data._id));
@@ -42,7 +42,7 @@
import _ from 'lodash';
import AppObjectCore from './AppObjectCore.svelte';
import { currentDatabase, extensions, openedConnections } from '../stores';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import { filterName } from 'dbgate-datalib';
import { showModal } from '../modals/modalTools';
import ConnectionModal from '../modals/ConnectionModal.svelte';

View File

@@ -0,0 +1,140 @@
<script lang="ts" context="module">
interface FileTypeHandler {
icon: string;
format: string;
tabComponent: string;
folder: string;
currentConnection: boolean;
}
const sql: FileTypeHandler = {
icon: 'img sql-file',
format: 'text',
tabComponent: 'QueryTab',
folder: 'sql',
currentConnection: true,
};
const shell: FileTypeHandler = {
icon: 'img shell',
format: 'text',
tabComponent: 'ShellTab',
folder: 'shell',
currentConnection: false,
};
const markdown: FileTypeHandler = {
icon: 'img markdown',
format: 'text',
tabComponent: 'MarkdownEditorTab',
folder: 'markdown',
currentConnection: false,
};
const charts: FileTypeHandler = {
icon: 'img chart',
format: 'json',
tabComponent: 'ChartTab',
folder: 'charts',
currentConnection: true,
};
const query: FileTypeHandler = {
icon: 'img query-design',
format: 'json',
tabComponent: 'QueryDesignTab',
folder: 'query',
currentConnection: true,
};
const HANDLERS = {
sql,
shell,
markdown,
charts,
query,
};
export const extractKey = data => data.file;
</script>
<script lang="ts">
import _ from 'lodash';
import ConfirmModal from '../modals/ConfirmModal.svelte';
import InputTextModal from '../modals/InputTextModal.svelte';
import { showModal } from '../modals/modalTools';
import { currentDatabase } from '../stores';
import axiosInstance from '../utility/axiosInstance';
import hasPermission from '../utility/hasPermission';
import openNewTab from '../utility/openNewTab';
import AppObjectCore from './AppObjectCore.svelte';
export let data;
$: folder = data?.folder;
$: handler = HANDLERS[folder] as FileTypeHandler;
function createMenu() {
return [
{ text: 'Open', onClick: openTab },
hasPermission(`files/${data.folder}/write`) && { text: 'Rename', onClick: handleRename },
hasPermission(`files/${data.folder}/write`) && { text: 'Delete', onClick: handleDelete },
];
}
const handleDelete = () => {
showModal(ConfirmModal, {
message: `Really delete file ${data.file}?`,
onConfirm: () => {
axiosInstance.post('files/delete', data);
},
});
};
const handleRename = () => {
showModal(InputTextModal, {
value: data.file,
label: 'New file name',
header: 'Rename file',
onConfirm: newFile => {
axiosInstance.post('files/rename', { ...data, newFile });
},
});
};
async function openTab() {
const resp = await axiosInstance.post('files/load', { folder, file: data.file, format: handler.format });
const connProps: any = {};
let tooltip = undefined;
if (handler.currentConnection) {
const connection = _.get($currentDatabase, 'connection') || {};
const database = _.get($currentDatabase, 'name');
connProps.conid = connection._id;
connProps.database = database;
tooltip = `${connection.displayName || connection.server}\n${database}`;
}
openNewTab(
{
title: data.file,
icon: handler.icon,
tabComponent: handler.tabComponent,
tooltip,
props: {
savedFile: data.file,
savedFolder: handler.folder,
savedFormat: handler.format,
...connProps,
},
},
{ editor: resp.data }
);
}
</script>
<AppObjectCore {...$$restProps} {data} icon={handler?.icon} title={data?.file} menu={createMenu()} on:click={openTab} />

View File

@@ -165,7 +165,7 @@
import keycodes from '../utility/keycodes';
import { activeTabId, nullStore } from '../stores';
import memberStore from '../utility/memberStore';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import { copyTextToClipboard } from '../utility/clipboard';
export let onLoadNextData = undefined;
@@ -280,7 +280,7 @@
}
export async function reconnect() {
await axios.post('database-connections/refresh', { conid, database });
await axiosInstance.post('database-connections/refresh', { conid, database });
display.reload();
}

View File

@@ -2,7 +2,7 @@
async function loadDataPage(props, offset, limit) {
const { jslid, display } = props;
const response = await axios.post('jsldata/get-rows', {
const response = await axiosInstance.post('jsldata/get-rows', {
jslid,
offset,
limit,
@@ -19,7 +19,7 @@
async function loadRowCount(props) {
const { jslid } = props;
const response = await axios.request({
const response = await axiosInstance.request({
url: 'jsldata/get-stats',
method: 'get',
params: {
@@ -33,7 +33,7 @@
<script lang="ts">
import _ from 'lodash';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import socket from '../utility/socket';
import useEffect from '../utility/useEffect';

View File

@@ -4,7 +4,7 @@
const sql = display.getPageQuery(offset, limit);
const response = await axios.request({
const response = await axiosInstance.request({
url: 'database-connections/query-data',
method: 'post',
params: {
@@ -29,7 +29,7 @@
const sql = display.getCountQuery();
const response = await axios.request({
const response = await axiosInstance.request({
url: 'database-connections/query-data',
method: 'post',
params: {
@@ -50,7 +50,7 @@
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
import { showModal } from '../modals/modalTools';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import ChangeSetGrider from './ChangeSetGrider';
import LoadingDataGridCore from './LoadingDataGridCore.svelte';
@@ -71,7 +71,7 @@
// $: console.log('GRIDER', grider);
async function handleConfirmSql(sql) {
const resp = await axios.request({
const resp = await axiosInstance.request({
url: 'database-connections/query-data',
method: 'post',
params: {

View File

@@ -1,9 +1,10 @@
<script lang="ts">
import { writable } from 'svelte/store';
import FormFieldTemplateLarge from '../modals/FormFieldTemplateLarge.svelte';
import FormProviderCore from './FormProviderCore.svelte';
export let initialValues = {};
export let template;
export let template = FormFieldTemplateLarge;
const values = writable(initialValues);
</script>

View File

@@ -0,0 +1,28 @@
<script lang="ts">
import FormStyledButton from '../elements/FormStyledButton.svelte';
import FormProvider from '../forms/FormProvider.svelte';
import FormSubmit from '../forms/FormSubmit.svelte';
import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools';
export let message;
export let onConfirm;
</script>
<FormProvider>
<ModalBase {...$$restProps}>
{message}
<svelte:fragment slot="footer">
<FormSubmit
value="OK"
on:click={() => {
closeCurrentModal();
onConfirm();
}}
/>
<FormStyledButton type="button" value="Close" on:click={closeCurrentModal} />
</svelte:fragment>
</ModalBase>
</FormProvider>

View File

@@ -4,7 +4,7 @@
import FormProvider from '../forms/FormProvider.svelte';
import FormSubmit from '../forms/FormSubmit.svelte';
import FontIcon from '../icons/FontIcon.svelte';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import TabControl from '../elements/TabControl.svelte';
import ConnectionModalDriverFields from './ConnectionModalDriverFields.svelte';
import ConnectionModalSshTunnelFields from './ConnectionModalSshTunnelFields.svelte';
@@ -25,7 +25,7 @@
isTesting = true;
testIdRef.current += 1;
const testid = testIdRef.current;
const resp = await axios.post('connections/test', e.detail);
const resp = await axiosInstance.post('connections/test', e.detail);
if (testIdRef.current != testid) return;
isTesting = false;
@@ -38,7 +38,7 @@
}
async function handleSubmit(e) {
axios.post('connections/save', e.detail);
axiosInstance.post('connections/save', e.detail);
closeCurrentModal();
}
</script>

View File

@@ -0,0 +1,35 @@
<script lang="ts">
import FormStyledButton from '../elements/FormStyledButton.svelte';
import FormProvider from '../forms/FormProvider.svelte';
import FormSubmit from '../forms/FormSubmit.svelte';
import FormTextField from '../forms/FormTextField.svelte';
import ModalBase from './ModalBase.svelte';
import { closeCurrentModal } from './modalTools';
export let header;
export let value;
export let label;
export let onConfirm;
const handleSubmit = async values => {
const { value } = values;
closeCurrentModal();
onConfirm(value);
};
</script>
<FormProvider initialValues={{ value }}>
<ModalBase {...$$restProps}>
<svelte:fragment slot="header">
{header}
</svelte:fragment>
<FormTextField {label} name="value" focused />
<svelte:fragment slot="footer">
<FormSubmit value="OK" on:click={e => handleSubmit(e.detail)} />
<FormStyledButton type="button" value="Cancel" on:click={closeCurrentModal} />
</svelte:fragment>
</ModalBase>
</FormProvider>

View File

@@ -1,6 +1,6 @@
<script lang="ts" context="module">
const dbgateEnv = {
axios,
axios: axiosInstance,
};
async function loadPlugins(pluginsDict, installedPlugins) {
@@ -8,7 +8,7 @@
for (const installed of installedPlugins || []) {
if (!_.keys(pluginsDict).includes(installed.name)) {
console.log('Loading module', installed.name);
const resp = await axios.request({
const resp = await axiosInstance.request({
method: 'get',
url: 'plugins/script',
params: {
@@ -48,7 +48,7 @@
<script lang="ts">
import _ from 'lodash';
import { extensions } from '../stores';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import { useInstalledPlugins } from '../utility/metadataLoaders';
import { buildFileFormats } from './fileformats';
import { buildThemes } from './themes';

View File

@@ -61,7 +61,7 @@
import useEditorData from '../query/useEditorData';
import { activeTabId, extensions, nullStore } from '../stores';
import applySqlTemplate from '../utility/applySqlTemplate';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import { changeTab } from '../utility/common';
import { useConnectionInfo } from '../utility/metadataLoaders';
import socket from '../utility/socket';
@@ -133,7 +133,7 @@
let sesid = sessionId;
if (!sesid) {
const resp = await axios.post('sessions/create', {
const resp = await axiosInstance.post('sessions/create', {
conid,
database,
});
@@ -142,14 +142,14 @@
}
busy = true;
// timerLabel.start();
await axios.post('sessions/execute-query', {
await axiosInstance.post('sessions/execute-query', {
sesid,
sql: selectedText || $editorValue,
});
}
export async function kill() {
await axios.post('sessions/kill', {
await axiosInstance.post('sessions/kill', {
sesid: sessionId,
});
sessionId = null;

View File

@@ -1,16 +1,16 @@
import _ from 'lodash';
import { openedConnections, currentDatabase } from '../stores';
import axios from './axios';
import axiosInstance from './axiosInstance';
const doServerPing = value => {
axios.post('server-connections/ping', { connections: value });
axiosInstance.post('server-connections/ping', { connections: value });
};
const doDatabasePing = value => {
const database = _.get(value, 'name');
const conid = _.get(value, 'connection._id');
if (conid && database) {
axios.post('database-connections/ping', { conid, database });
axiosInstance.post('database-connections/ping', { conid, database });
}
};

View File

@@ -0,0 +1,15 @@
import { compilePermissions, testPermission } from 'dbgate-tools';
import { useConfig } from './metadataLoaders';
let compiled = null;
const config = useConfig();
config.subscribe(value => {
if (!value) return;
const { permissions } = value;
compiled = compilePermissions(permissions);
});
export default function hasPermission(tested) {
return testPermission(tested, compiled);
}

View File

@@ -1,4 +1,4 @@
import axios from './axios';
import axiosInstance from './axiosInstance';
import _ from 'lodash';
import { cacheGet, cacheSet, getCachedPromise } from './cache';
import stableStringify from 'json-stable-stringify';
@@ -130,7 +130,7 @@ async function getCore(loader, args) {
const key = stableStringify({ url, ...params });
async function doLoad() {
const resp = await axios.request({
const resp = await axiosInstance.request({
method: 'get',
url,
params,
@@ -154,7 +154,7 @@ function useCore(loader, args) {
subscribe: onChange => {
async function handleReload() {
async function doLoad() {
const resp = await axios.request({
const resp = await axiosInstance.request({
method: 'get',
params,
url,
@@ -331,7 +331,7 @@ export function getConfig() {
return getCore(configLoader, {}) || {};
}
export function useConfig() {
return useCore(configLoader, {}) || {};
return useCore(configLoader, {});
}
export function getPlatformInfo() {

View File

@@ -1,11 +1,11 @@
import _ from 'lodash';
import axios from './axios';
import axiosInstance from './axiosInstance';
import { writable } from 'svelte/store';
export default function useFetch({ url, data = undefined, params = undefined, defaultValue = undefined, ...config }) {
const result = writable(defaultValue);
axios
axiosInstance
.request({
method: 'get',
params,

View File

@@ -0,0 +1,12 @@
<script lang="ts">
import SavedFilesList from './SavedFilesList.svelte';
import WidgetColumnBar from './WidgetColumnBar.svelte';
import WidgetColumnBarItem from './WidgetColumnBarItem.svelte';
</script>
<WidgetColumnBar>
<WidgetColumnBarItem title="Saved files" name="files">
<SavedFilesList />
</WidgetColumnBarItem>
</WidgetColumnBar>

View File

@@ -0,0 +1,28 @@
<script lang="ts">
import _ from 'lodash';
import AppObjectList from '../appobj/AppObjectList.svelte';
import * as savedFileAppObject from '../appobj/SavedFileAppObject.svelte';
import { useFiles } from '../utility/metadataLoaders';
import WidgetsInnerContainer from './WidgetsInnerContainer.svelte';
const sqlFiles = useFiles({ folder: 'sql' });
const shellFiles = useFiles({ folder: 'shell' });
const markdownFiles = useFiles({ folder: 'markdown' });
const chartFiles = useFiles({ folder: 'charts' });
const queryFiles = useFiles({ folder: 'query' });
$: files = [
...($sqlFiles || []),
...($shellFiles || []),
...($markdownFiles || []),
...($chartFiles || []),
...($queryFiles || []),
];
</script>
<WidgetsInnerContainer>
<AppObjectList list={files} module={savedFileAppObject} groupFunc={data => _.startCase(data.folder)} />
</WidgetsInnerContainer>

View File

@@ -10,7 +10,7 @@
import SubColumnParamList from '../appobj/SubColumnParamList.svelte';
import { chevronExpandIcon } from '../icons/expandIcons';
import ErrorInfo from '../elements/ErrorInfo.svelte';
import axios from '../utility/axios';
import axiosInstance from '../utility/axiosInstance';
import LoadingInfo from '../elements/LoadingInfo.svelte';
export let conid;
@@ -31,7 +31,7 @@
);
const handleRefreshDatabase = () => {
axios.post('database-connections/refresh', { conid, database });
axiosInstance.post('database-connections/refresh', { conid, database });
};
</script>

View File

@@ -1,6 +1,7 @@
<script lang="ts">
import { selectedWidget } from '../stores';
import DatabaseWidget from './DatabaseWidget.svelte';
import FilesWidget from './FilesWidget.svelte';
</script>
@@ -8,3 +9,6 @@
{#if $selectedWidget == 'database'}
<DatabaseWidget />
{/if}
{#if $selectedWidget == 'file'}
<FilesWidget />
{/if}