remove web

This commit is contained in:
Jan Prochazka
2021-02-20 19:15:11 +01:00
parent dd7db5904c
commit daf9e9d18b
240 changed files with 0 additions and 22572 deletions

View File

@@ -1,97 +0,0 @@
// @ts-nocheck
import _ from 'lodash';
import React from 'react';
import styled from 'styled-components';
import { FontIcon } from '../icons';
import { useShowMenu } from '../modals/showMenu';
import useTheme from '../theme/useTheme';
const AppObjectDiv = styled.div`
padding: 5px;
${props =>
!props.disableHover &&
`
&:hover {
background-color: ${props.theme.left_background_blue[1]};
}
`}
cursor: pointer;
white-space: nowrap;
font-weight: ${props => (props.isBold ? 'bold' : 'normal')};
`;
const IconWrap = styled.span`
margin-right: 5px;
`;
const StatusIconWrap = styled.span`
margin-left: 5px;
`;
const ExtInfoWrap = styled.span`
font-weight: normal;
margin-left: 5px;
color: ${props => props.theme.left_font3};
`;
export function AppObjectCore({
title,
icon,
data,
onClick = undefined,
onClick2 = undefined,
onClick3 = undefined,
isBold = undefined,
isBusy = undefined,
prefix = undefined,
statusIcon = undefined,
extInfo = undefined,
statusTitle = undefined,
disableHover = false,
children = null,
Menu = undefined,
...other
}) {
const theme = useTheme();
const showMenu = useShowMenu();
const handleContextMenu = event => {
if (!Menu) return;
event.preventDefault();
showMenu(event.pageX, event.pageY, <Menu data={data} />);
};
return (
<>
<AppObjectDiv
onContextMenu={handleContextMenu}
onClick={() => {
if (onClick) onClick(data);
if (onClick2) onClick2(data);
if (onClick3) onClick3(data);
}}
theme={theme}
isBold={isBold}
draggable
onDragStart={e => {
e.dataTransfer.setData('app_object_drag_data', JSON.stringify(data));
}}
disableHover={disableHover}
{...other}
>
{prefix}
<IconWrap>{isBusy ? <FontIcon icon="icon loading" /> : <FontIcon icon={icon} />}</IconWrap>
{title}
{statusIcon && (
<StatusIconWrap>
<FontIcon icon={statusIcon} title={statusTitle} />
</StatusIconWrap>
)}
{extInfo && <ExtInfoWrap theme={theme}>{extInfo}</ExtInfoWrap>}
</AppObjectDiv>
{children}
</>
);
}

View File

@@ -1,164 +0,0 @@
import React from 'react';
import _ from 'lodash';
import styled from 'styled-components';
import { ExpandIcon } from '../icons';
import useTheme from '../theme/useTheme';
const SubItemsDiv = styled.div`
margin-left: 28px;
`;
const ExpandIconHolder2 = styled.span`
margin-right: 3px;
// position: relative;
// top: -3px;
`;
const ExpandIconHolder = styled.span`
margin-right: 5px;
`;
const GroupDiv = styled.div`
user-select: none;
padding: 5px;
&:hover {
background-color: ${props => props.theme.left_background_blue[1]};
}
cursor: pointer;
white-space: nowrap;
font-weight: bold;
`;
function AppObjectListItem({
AppObjectComponent,
data,
filter,
onObjectClick,
isExpandable,
SubItems,
getCommonProps,
expandOnClick,
ExpandIconComponent,
}) {
const [isExpanded, setIsExpanded] = React.useState(false);
const expandable = data && isExpandable && isExpandable(data);
React.useEffect(() => {
if (!expandable) {
setIsExpanded(false);
}
}, [expandable]);
let commonProps = {
prefix: SubItems ? (
<ExpandIconHolder2>
{expandable ? (
<ExpandIconComponent
isExpanded={isExpanded}
onClick={e => {
setIsExpanded(v => !v);
e.stopPropagation();
}}
/>
) : (
<ExpandIconComponent isBlank />
)}
</ExpandIconHolder2>
) : null,
};
if (SubItems && expandOnClick) {
commonProps.onClick2 = () => setIsExpanded(v => !v);
}
if (onObjectClick) {
commonProps.onClick3 = onObjectClick;
}
if (getCommonProps) {
commonProps = { ...commonProps, ...getCommonProps(data) };
}
let res = <AppObjectComponent data={data} commonProps={commonProps} />;
if (SubItems && isExpanded) {
res = (
<>
{res}
<SubItemsDiv>
<SubItems data={data} filter={filter} />
</SubItemsDiv>
</>
);
}
return res;
}
function AppObjectGroup({ group, items }) {
const [isExpanded, setIsExpanded] = React.useState(true);
const theme = useTheme();
const filtered = items.filter(x => x.component);
let countText = filtered.length.toString();
if (filtered.length < items.length) countText += `/${items.length}`;
return (
<>
<GroupDiv onClick={() => setIsExpanded(!isExpanded)} theme={theme}>
<ExpandIconHolder>
<ExpandIcon isExpanded={isExpanded} />
</ExpandIconHolder>
{group} {items && `(${countText})`}
</GroupDiv>
{isExpanded && filtered.map(x => x.component)}
</>
);
}
export function AppObjectList({
list,
AppObjectComponent,
SubItems = undefined,
onObjectClick = undefined,
filter = undefined,
groupFunc = undefined,
groupOrdered = undefined,
isExpandable = undefined,
getCommonProps = undefined,
expandOnClick = false,
ExpandIconComponent = ExpandIcon,
}) {
const createComponent = data => (
<AppObjectListItem
key={AppObjectComponent.extractKey(data)}
AppObjectComponent={AppObjectComponent}
data={data}
filter={filter}
onObjectClick={onObjectClick}
SubItems={SubItems}
isExpandable={isExpandable}
getCommonProps={getCommonProps}
expandOnClick={expandOnClick}
ExpandIconComponent={ExpandIconComponent}
/>
);
if (groupFunc) {
const listGrouped = _.compact(
(list || []).map(data => {
const matcher = AppObjectComponent.createMatcher && AppObjectComponent.createMatcher(data);
const component = matcher && !matcher(filter) ? null : createComponent(data);
const group = groupFunc(data);
return { group, data, component };
})
);
const groups = _.groupBy(listGrouped, 'group');
return (groupOrdered || _.keys(groups)).map(group => (
<AppObjectGroup key={group} group={group} items={groups[group]} />
));
}
return (list || []).map(data => {
const matcher = AppObjectComponent.createMatcher && AppObjectComponent.createMatcher(data);
if (matcher && !matcher(filter)) return null;
return createComponent(data);
});
}

View File

@@ -1,75 +0,0 @@
import React from 'react';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import { filterName } from 'dbgate-datalib';
import axios from '../utility/axios';
import { AppObjectCore } from './AppObjectCore';
import useOpenNewTab from '../utility/useOpenNewTab';
function openArchive(openNewTab, fileName, folderName) {
openNewTab({
title: fileName,
icon: 'img archive',
tooltip: `${folderName}\n${fileName}`,
tabComponent: 'ArchiveFileTab',
props: {
archiveFile: fileName,
archiveFolder: folderName,
},
});
}
function Menu({ data }) {
const openNewTab = useOpenNewTab();
const handleDelete = () => {
axios.post('archive/delete-file', { file: data.fileName, folder: data.folderName });
// setOpenedTabs((tabs) => tabs.filter((x) => x.tabid != data.tabid));
};
const handleOpenRead = () => {
openArchive(openNewTab, data.fileName, data.folderName);
};
const handleOpenWrite = async () => {
// const resp = await axios.post('archive/load-free-table', { file: data.fileName, folder: data.folderName });
openNewTab({
title: data.fileName,
icon: 'img archive',
tabComponent: 'FreeTableTab',
props: {
initialArgs: {
functionName: 'archiveReader',
props: {
fileName: data.fileName,
folderName: data.folderName,
},
},
archiveFile: data.fileName,
archiveFolder: data.folderName,
},
});
};
return (
<>
<DropDownMenuItem onClick={handleOpenRead}>Open (readonly)</DropDownMenuItem>
<DropDownMenuItem onClick={handleOpenWrite}>Open in free table editor</DropDownMenuItem>
<DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem>
</>
);
}
function ArchiveFileAppObject({ data, commonProps }) {
const { fileName, folderName } = data;
const openNewTab = useOpenNewTab();
const onClick = () => {
openArchive(openNewTab, fileName, folderName);
};
return (
<AppObjectCore {...commonProps} data={data} title={fileName} icon="img archive" onClick={onClick} Menu={Menu} />
);
}
ArchiveFileAppObject.extractKey = data => data.fileName;
ArchiveFileAppObject.createMatcher = ({ fileName }) => filter => filterName(filter, fileName);
export default ArchiveFileAppObject;

View File

@@ -1,34 +0,0 @@
import React from 'react';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import axios from '../utility/axios';
import { filterName } from 'dbgate-datalib';
import { AppObjectCore } from './AppObjectCore';
import { useCurrentArchive } from '../utility/globalState';
function Menu({ data }) {
const handleDelete = () => {
axios.post('archive/delete-folder', { folder: data.name });
};
return <>{data.name != 'default' && <DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem>}</>;
}
function ArchiveFolderAppObject({ data, commonProps }) {
const { name } = data;
const currentArchive = useCurrentArchive();
return (
<AppObjectCore
{...commonProps}
data={data}
title={name}
icon="img archive-folder"
isBold={name == currentArchive}
Menu={Menu}
/>
);
}
ArchiveFolderAppObject.extractKey = data => data.name;
ArchiveFolderAppObject.createMatcher = data => filter => filterName(filter, data.name);
export default ArchiveFolderAppObject;

View File

@@ -1,73 +0,0 @@
import React from 'react';
import _ from 'lodash';
import moment from 'moment';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import { useSetOpenedTabs } from '../utility/globalState';
import { AppObjectCore } from './AppObjectCore';
import { setSelectedTabFunc } from '../utility/common';
import styled from 'styled-components';
import { FontIcon } from '../icons';
import useTheme from '../theme/useTheme';
const InfoDiv = styled.div`
margin-left: 30px;
color: ${props => props.theme.left_font3};
`;
function Menu({ data }) {
const setOpenedTabs = useSetOpenedTabs();
const handleDelete = () => {
setOpenedTabs(tabs => tabs.filter(x => x.tabid != data.tabid));
};
const handleDeleteOlder = () => {
setOpenedTabs(tabs => tabs.filter(x => !x.closedTime || x.closedTime >= data.closedTime));
};
return (
<>
<DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem>
<DropDownMenuItem onClick={handleDeleteOlder}>Delete older</DropDownMenuItem>
</>
);
}
function ClosedTabAppObject({ data, commonProps }) {
const { tabid, props, selected, icon, title, closedTime, busy } = data;
const setOpenedTabs = useSetOpenedTabs();
const theme = useTheme();
const onClick = () => {
setOpenedTabs(files =>
setSelectedTabFunc(
files.map(x => ({
...x,
closedTime: x.tabid == tabid ? undefined : x.closedTime,
})),
tabid
)
);
};
return (
<AppObjectCore
{...commonProps}
data={data}
title={`${title} ${moment(closedTime).fromNow()}`}
icon={icon}
isBold={!!selected}
onClick={onClick}
isBusy={busy}
Menu={Menu}
>
{data.props && data.props.database && (
<InfoDiv theme={theme}>
<FontIcon icon="icon database" /> {data.props.database}
</InfoDiv>
)}
{data.contentPreview && <InfoDiv theme={theme}>{data.contentPreview}</InfoDiv>}
</AppObjectCore>
);
}
ClosedTabAppObject.extractKey = data => data.tabid;
export default ClosedTabAppObject;

View File

@@ -1,119 +0,0 @@
import _ from 'lodash';
import React from 'react';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import ConnectionModal from '../modals/ConnectionModal';
import axios from '../utility/axios';
import { filterName } from 'dbgate-datalib';
import ConfirmModal from '../modals/ConfirmModal';
import CreateDatabaseModal from '../modals/CreateDatabaseModal';
import { useCurrentDatabase, useOpenedConnections, useSetOpenedConnections } from '../utility/globalState';
import { AppObjectCore } from './AppObjectCore';
import useShowModal from '../modals/showModal';
import { useConfig } from '../utility/metadataLoaders';
import useExtensions from '../utility/useExtensions';
function Menu({ data }) {
const openedConnections = useOpenedConnections();
const setOpenedConnections = useSetOpenedConnections();
const showModal = useShowModal();
const config = useConfig();
const handleEdit = () => {
showModal(modalState => <ConnectionModal modalState={modalState} connection={data} />);
};
const handleDelete = () => {
showModal(modalState => (
<ConfirmModal
modalState={modalState}
message={`Really delete connection ${data.displayName || data.server}?`}
onConfirm={() => axios.post('connections/delete', data)}
/>
));
};
const handleCreateDatabase = () => {
showModal(modalState => <CreateDatabaseModal modalState={modalState} conid={data._id} />);
};
const handleRefresh = () => {
axios.post('server-connections/refresh', { conid: data._id });
};
const handleDisconnect = () => {
setOpenedConnections(list => list.filter(x => x != data._id));
};
const handleConnect = () => {
setOpenedConnections(list => _.uniq([...list, data._id]));
};
return (
<>
{config.runAsPortal == false && (
<>
<DropDownMenuItem onClick={handleEdit}>Edit</DropDownMenuItem>
<DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem>
</>
)}
{!openedConnections.includes(data._id) && <DropDownMenuItem onClick={handleConnect}>Connect</DropDownMenuItem>}
{openedConnections.includes(data._id) && data.status && (
<DropDownMenuItem onClick={handleRefresh}>Refresh</DropDownMenuItem>
)}
{openedConnections.includes(data._id) && (
<DropDownMenuItem onClick={handleDisconnect}>Disconnect</DropDownMenuItem>
)}
{openedConnections.includes(data._id) && (
<DropDownMenuItem onClick={handleCreateDatabase}>Create database</DropDownMenuItem>
)}
</>
);
}
function ConnectionAppObject({ data, commonProps }) {
const { _id, server, displayName, engine, status } = data;
const openedConnections = useOpenedConnections();
const setOpenedConnections = useSetOpenedConnections();
const currentDatabase = useCurrentDatabase();
const extensions = useExtensions();
const isBold = _.get(currentDatabase, 'connection._id') == _id;
const onClick = () => setOpenedConnections(c => _.uniq([...c, _id]));
let statusIcon = null;
let statusTitle = null;
let extInfo = null;
if (extensions.drivers.find(x => x.engine == engine)) {
const match = (engine || '').match(/^([^@]*)@/);
extInfo = match ? match[1] : engine;
} else {
extInfo = engine;
statusIcon = 'img warn';
statusTitle = `Engine driver ${engine} not found, review installed plugins and change engine in edit connection dialog`;
}
if (openedConnections.includes(_id)) {
if (!status) statusIcon = 'icon loading';
else if (status.name == 'pending') statusIcon = 'icon loading';
else if (status.name == 'ok') statusIcon = 'img ok';
else statusIcon = 'img error';
if (status && status.name == 'error') {
statusTitle = status.message;
}
}
return (
<AppObjectCore
{...commonProps}
title={displayName || server}
icon="img server"
data={data}
statusIcon={statusIcon}
statusTitle={statusTitle}
extInfo={extInfo}
isBold={isBold}
onClick={onClick}
Menu={Menu}
/>
);
}
ConnectionAppObject.extractKey = data => data._id;
ConnectionAppObject.createMatcher = ({ displayName, server }) => filter => filterName(filter, displayName, server);
export default ConnectionAppObject;

View File

@@ -1,90 +0,0 @@
import React from 'react';
import _ from 'lodash';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import ImportExportModal from '../modals/ImportExportModal';
import { getDefaultFileFormat } from '../utility/fileformats';
import { useCurrentDatabase } from '../utility/globalState';
import { AppObjectCore } from './AppObjectCore';
import useShowModal from '../modals/showModal';
import useExtensions from '../utility/useExtensions';
import useOpenNewTab from '../utility/useOpenNewTab';
function Menu({ data }) {
const { connection, name } = data;
const openNewTab = useOpenNewTab();
const extensions = useExtensions();
const showModal = useShowModal();
const tooltip = `${connection.displayName || connection.server}\n${name}`;
const handleNewQuery = () => {
openNewTab({
title: 'Query #',
icon: 'img sql-file',
tooltip,
tabComponent: 'QueryTab',
props: {
conid: connection._id,
database: name,
},
});
};
const handleImport = () => {
showModal(modalState => (
<ImportExportModal
modalState={modalState}
initialValues={{
sourceStorageType: getDefaultFileFormat(extensions).storageType,
targetStorageType: 'database',
targetConnectionId: connection._id,
targetDatabaseName: name,
}}
/>
));
};
const handleExport = () => {
showModal(modalState => (
<ImportExportModal
modalState={modalState}
initialValues={{
targetStorageType: getDefaultFileFormat(extensions).storageType,
sourceStorageType: 'database',
sourceConnectionId: connection._id,
sourceDatabaseName: name,
}}
/>
));
};
return (
<>
<DropDownMenuItem onClick={handleNewQuery}>New query</DropDownMenuItem>
<DropDownMenuItem onClick={handleImport}>Import</DropDownMenuItem>
<DropDownMenuItem onClick={handleExport}>Export</DropDownMenuItem>
</>
);
}
function DatabaseAppObject({ data, commonProps }) {
const { name, connection } = data;
const currentDatabase = useCurrentDatabase();
return (
<AppObjectCore
{...commonProps}
data={data}
title={name}
icon="img database"
isBold={
_.get(currentDatabase, 'connection._id') == _.get(connection, '_id') && _.get(currentDatabase, 'name') == name
}
Menu={Menu}
/>
);
}
DatabaseAppObject.extractKey = props => props.name;
export default DatabaseAppObject;

View File

@@ -1,325 +0,0 @@
import _ from 'lodash';
import React from 'react';
import { DropDownMenuDivider, DropDownMenuItem } from '../modals/DropDownMenu';
import { getConnectionInfo } from '../utility/metadataLoaders';
import fullDisplayName from '../utility/fullDisplayName';
import { filterName } from 'dbgate-datalib';
import ImportExportModal from '../modals/ImportExportModal';
import { useSetOpenedTabs } from '../utility/globalState';
import { AppObjectCore } from './AppObjectCore';
import useShowModal from '../modals/showModal';
import { findEngineDriver } from 'dbgate-tools';
import useExtensions from '../utility/useExtensions';
import useOpenNewTab from '../utility/useOpenNewTab';
import uuidv1 from 'uuid/v1';
import { AppObjectList } from './AppObjectList';
const icons = {
tables: 'img table',
views: 'img view',
procedures: 'img procedure',
functions: 'img function',
};
const menus = {
tables: [
{
label: 'Open data',
tab: 'TableDataTab',
forceNewTab: true,
},
{
label: 'Open form',
tab: 'TableDataTab',
forceNewTab: true,
initialData: {
grid: {
isFormView: true,
},
},
},
{
label: 'Open structure',
tab: 'TableStructureTab',
},
{
label: 'Query designer',
isQueryDesigner: true,
},
{
isDivider: true,
},
{
label: 'Export',
isExport: true,
},
{
label: 'Open in free table editor',
isOpenFreeTable: true,
},
{
label: 'Open active chart',
isActiveChart: true,
},
{
isDivider: true,
},
{
label: 'SQL: CREATE TABLE',
sqlTemplate: 'CREATE TABLE',
},
],
views: [
{
label: 'Open data',
tab: 'ViewDataTab',
forceNewTab: true,
},
{
label: 'Open structure',
tab: 'TableStructureTab',
},
{
label: 'Query designer',
isQueryDesigner: true,
},
{
isDivider: true,
},
{
label: 'Export',
isExport: true,
},
{
label: 'Open in free table editor',
isOpenFreeTable: true,
},
{
label: 'Open active chart',
isActiveChart: true,
},
{
isDivider: true,
},
{
label: 'SQL: CREATE VIEW',
sqlTemplate: 'CREATE OBJECT',
},
{
label: 'SQL: CREATE TABLE',
sqlTemplate: 'CREATE TABLE',
},
],
procedures: [
{
label: 'SQL: CREATE PROCEDURE',
sqlTemplate: 'CREATE OBJECT',
},
{
label: 'SQL: EXECUTE',
sqlTemplate: 'EXECUTE PROCEDURE',
},
],
functions: [
{
label: 'SQL: CREATE FUNCTION',
sqlTemplate: 'CREATE OBJECT',
},
],
};
const defaultTabs = {
tables: 'TableDataTab',
views: 'ViewDataTab',
};
export async function openDatabaseObjectDetail(
openNewTab,
tabComponent,
sqlTemplate,
{ schemaName, pureName, conid, database, objectTypeField },
forceNewTab,
initialData
) {
const connection = await getConnectionInfo({ conid });
const tooltip = `${connection.displayName || connection.server}\n${database}\n${fullDisplayName({
schemaName,
pureName,
})}`;
openNewTab(
{
title: sqlTemplate ? 'Query #' : pureName,
tooltip,
icon: sqlTemplate ? 'img sql-file' : icons[objectTypeField],
tabComponent: sqlTemplate ? 'QueryTab' : tabComponent,
props: {
schemaName,
pureName,
conid,
database,
objectTypeField,
initialArgs: sqlTemplate ? { sqlTemplate } : null,
},
},
initialData,
{ forceNewTab }
);
}
function Menu({ data }) {
const showModal = useShowModal();
const openNewTab = useOpenNewTab();
const extensions = useExtensions();
const getDriver = async () => {
const conn = await getConnectionInfo(data);
if (!conn) return;
const driver = findEngineDriver(conn, extensions);
return driver;
};
return (
<>
{menus[data.objectTypeField].map(menu =>
menu.isDivider ? (
<DropDownMenuDivider />
) : (
<DropDownMenuItem
key={menu.label}
onClick={async () => {
if (menu.isExport) {
showModal(modalState => (
<ImportExportModal
modalState={modalState}
initialValues={{
sourceStorageType: 'database',
sourceConnectionId: data.conid,
sourceDatabaseName: data.database,
sourceSchemaName: data.schemaName,
sourceList: [data.pureName],
}}
/>
));
} else if (menu.isOpenFreeTable) {
const coninfo = await getConnectionInfo(data);
openNewTab({
title: data.pureName,
icon: 'img free-table',
tabComponent: 'FreeTableTab',
props: {
initialArgs: {
functionName: 'tableReader',
props: {
connection: {
...coninfo,
database: data.database,
},
schemaName: data.schemaName,
pureName: data.pureName,
},
},
},
});
} else if (menu.isActiveChart) {
const driver = await getDriver();
const dmp = driver.createDumper();
dmp.put('^select * from %f', data);
openNewTab(
{
title: data.pureName,
icon: 'img chart',
tabComponent: 'ChartTab',
props: {
conid: data.conid,
database: data.database,
},
},
{
editor: {
config: { chartType: 'bar' },
sql: dmp.s,
},
}
);
} else if (menu.isQueryDesigner) {
openNewTab(
{
title: 'Query #',
icon: 'img query-design',
tabComponent: 'QueryDesignTab',
props: {
conid: data.conid,
database: data.database,
},
},
{
editor: {
tables: [
{
...data,
designerId: uuidv1(),
left: 50,
top: 50,
},
],
},
}
);
} else {
openDatabaseObjectDetail(
openNewTab,
menu.tab,
menu.sqlTemplate,
data,
menu.forceNewTab,
menu.initialData
);
}
}}
>
{menu.label}
</DropDownMenuItem>
)
)}
</>
);
}
function DatabaseObjectAppObject({ data, commonProps }) {
const { conid, database, pureName, schemaName, objectTypeField } = data;
const openNewTab = useOpenNewTab();
const onClick = ({ schemaName, pureName }) => {
openDatabaseObjectDetail(
openNewTab,
defaultTabs[objectTypeField],
defaultTabs[objectTypeField] ? null : 'CREATE OBJECT',
{
schemaName,
pureName,
conid,
database,
objectTypeField,
},
false
);
};
return (
<AppObjectCore
{...commonProps}
data={data}
title={schemaName ? `${schemaName}.${pureName}` : pureName}
icon={icons[objectTypeField]}
onClick={onClick}
Menu={Menu}
/>
);
}
DatabaseObjectAppObject.extractKey = ({ schemaName, pureName }) =>
schemaName ? `${schemaName}.${pureName}` : pureName;
DatabaseObjectAppObject.createMatcher = ({ pureName }) => filter => filterName(filter, pureName);
export default DatabaseObjectAppObject;

View File

@@ -1,104 +0,0 @@
import React from 'react';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import FavoriteModal from '../modals/FavoriteModal';
import useShowModal from '../modals/showModal';
import axios from '../utility/axios';
import { copyTextToClipboard } from '../utility/clipboard';
import getElectron from '../utility/getElectron';
import useOpenNewTab from '../utility/useOpenNewTab';
import { SavedFileAppObjectBase } from './SavedFileAppObject';
export function useOpenFavorite() {
const openNewTab = useOpenNewTab();
const openFavorite = React.useCallback(
async favorite => {
const { icon, tabComponent, title, props, tabdata } = favorite;
let tabdataNew = tabdata;
if (props.savedFile) {
const resp = await axios.post('files/load', {
folder: props.savedFolder,
file: props.savedFile,
format: props.savedFormat,
});
tabdataNew = {
...tabdata,
editor: resp.data,
};
}
openNewTab(
{
title,
icon: icon || 'img favorite',
props,
tabComponent,
},
tabdataNew
);
},
[openNewTab]
);
return openFavorite;
}
export function FavoriteFileAppObject({ data, commonProps }) {
const { icon, tabComponent, title, props, tabdata, urlPath } = data;
const openNewTab = useOpenNewTab();
const showModal = useShowModal();
const openFavorite = useOpenFavorite();
const electron = getElectron();
const editFavorite = () => {
showModal(modalState => <FavoriteModal modalState={modalState} editingData={data} />);
};
const editFavoriteJson = async () => {
const resp = await axios.post('files/load', {
folder: 'favorites',
file: data.file,
format: 'text',
});
openNewTab(
{
icon: 'icon favorite',
title,
tabComponent: 'FavoriteEditorTab',
props: {
savedFile: data.file,
savedFormat: 'text',
savedFolder: 'favorites',
},
},
{ editor: JSON.stringify(JSON.parse(resp.data), null, 2) }
);
};
const copyLink = () => {
copyTextToClipboard(`${document.location.origin}#favorite=${urlPath}`);
};
return (
<SavedFileAppObjectBase
data={data}
commonProps={commonProps}
format="json"
icon={icon || 'img favorite'}
title={title}
disableRename
onLoad={async data => {
openFavorite(data);
}}
menuExt={
<>
<DropDownMenuItem onClick={editFavorite}>Edit</DropDownMenuItem>
<DropDownMenuItem onClick={editFavoriteJson}>Edit JSON definition</DropDownMenuItem>
{!electron && urlPath && <DropDownMenuItem onClick={copyLink}>Copy link</DropDownMenuItem>}
</>
}
/>
);
}
FavoriteFileAppObject.extractKey = data => data.file;

View File

@@ -1,15 +0,0 @@
import _ from 'lodash';
import React from 'react';
import { filterName } from 'dbgate-datalib';
import { AppObjectCore } from './AppObjectCore';
function MacroAppObject({ data, commonProps }) {
const { name, type, title, group } = data;
return <AppObjectCore {...commonProps} data={data} title={title} icon={'img macro'} />;
}
MacroAppObject.extractKey = data => data.name;
MacroAppObject.createMatcher = ({ name, title }) => filter => filterName(filter, name, title);
export default MacroAppObject;

View File

@@ -1,314 +0,0 @@
import React from 'react';
import axios from '../utility/axios';
import _ from 'lodash';
import { DropDownMenuItem } from '../modals/DropDownMenu';
import { AppObjectCore } from './AppObjectCore';
import useNewQuery from '../query/useNewQuery';
import { useCurrentDatabase } from '../utility/globalState';
import ScriptWriter from '../impexp/ScriptWriter';
import { extractPackageName } from 'dbgate-tools';
import useShowModal from '../modals/showModal';
import InputTextModal from '../modals/InputTextModal';
import useHasPermission from '../utility/useHasPermission';
import useOpenNewTab from '../utility/useOpenNewTab';
import ConfirmModal from '../modals/ConfirmModal';
function Menu({ data, menuExt = null, title = undefined, disableRename = false }) {
const hasPermission = useHasPermission();
const showModal = useShowModal();
const handleDelete = () => {
showModal(modalState => (
<ConfirmModal
modalState={modalState}
message={`Really delete file ${title || data.file}?`}
onConfirm={() => {
axios.post('files/delete', data);
}}
/>
));
};
const handleRename = () => {
showModal(modalState => (
<InputTextModal
modalState={modalState}
value={data.file}
label="New file name"
header="Rename file"
onConfirm={newFile => {
axios.post('files/rename', { ...data, newFile });
}}
/>
));
};
return (
<>
{hasPermission(`files/${data.folder}/write`) && (
<DropDownMenuItem onClick={handleDelete}>Delete</DropDownMenuItem>
)}
{hasPermission(`files/${data.folder}/write`) && !disableRename && (
<DropDownMenuItem onClick={handleRename}>Rename</DropDownMenuItem>
)}
{menuExt}
</>
);
}
export function SavedFileAppObjectBase({
data,
commonProps,
format,
icon,
onLoad,
title = undefined,
menuExt = null,
disableRename = false,
}) {
const { file, folder } = data;
const onClick = async () => {
const resp = await axios.post('files/load', { folder, file, format });
onLoad(resp.data);
};
return (
<AppObjectCore
{...commonProps}
data={data}
title={title || file}
icon={icon}
onClick={onClick}
Menu={props => <Menu {...props} menuExt={menuExt} title={title} disableRename={disableRename} />}
/>
);
}
export function SavedSqlFileAppObject({ data, commonProps }) {
const { file, folder } = data;
const newQuery = useNewQuery();
const currentDatabase = useCurrentDatabase();
const openNewTab = useOpenNewTab();
const connection = _.get(currentDatabase, 'connection');
const database = _.get(currentDatabase, 'name');
const handleGenerateExecute = () => {
const script = new ScriptWriter();
const conn = {
..._.omit(connection, ['displayName', '_id']),
database,
};
script.put(`const sql = await dbgateApi.loadFile('${folder}/${file}');`);
script.put(`await dbgateApi.executeQuery({ sql, connection: ${JSON.stringify(conn)} });`);
// @ts-ignore
script.requirePackage(extractPackageName(conn.engine));
openNewTab(
{
title: 'Shell #',
icon: 'img shell',
tabComponent: 'ShellTab',
},
{ editor: script.getScript() }
);
};
return (
<SavedFileAppObjectBase
data={data}
commonProps={commonProps}
format="text"
icon="img sql-file"
menuExt={
connection && database ? (
<DropDownMenuItem onClick={handleGenerateExecute}>Generate shell execute</DropDownMenuItem>
) : null
}
onLoad={data => {
newQuery({
title: file,
initialData: data,
// @ts-ignore
savedFile: file,
savedFolder: 'sql',
savedFormat: 'text',
});
}}
/>
);
}
export function SavedShellFileAppObject({ data, commonProps }) {
const { file, folder } = data;
const openNewTab = useOpenNewTab();
return (
<SavedFileAppObjectBase
data={data}
commonProps={commonProps}
format="text"
icon="img shell"
onLoad={data => {
openNewTab(
{
title: file,
icon: 'img shell',
tabComponent: 'ShellTab',
props: {
savedFile: file,
savedFolder: 'shell',
savedFormat: 'text',
},
},
{ editor: data }
);
}}
/>
);
}
export function SavedChartFileAppObject({ data, commonProps }) {
const { file, folder } = data;
const openNewTab = useOpenNewTab();
const currentDatabase = useCurrentDatabase();
const connection = _.get(currentDatabase, 'connection') || {};
const database = _.get(currentDatabase, 'name');
const tooltip = `${connection.displayName || connection.server}\n${database}`;
return (
<SavedFileAppObjectBase
data={data}
commonProps={commonProps}
format="json"
icon="img chart"
onLoad={data => {
openNewTab(
{
title: file,
icon: 'img chart',
tooltip,
props: {
conid: connection._id,
database,
savedFile: file,
savedFolder: 'charts',
savedFormat: 'json',
},
tabComponent: 'ChartTab',
},
{ editor: data }
);
}}
/>
);
}
export function SavedQueryFileAppObject({ data, commonProps }) {
const { file, folder } = data;
const openNewTab = useOpenNewTab();
const currentDatabase = useCurrentDatabase();
const connection = _.get(currentDatabase, 'connection') || {};
const database = _.get(currentDatabase, 'name');
const tooltip = `${connection.displayName || connection.server}\n${database}`;
return (
<SavedFileAppObjectBase
data={data}
commonProps={commonProps}
format="json"
icon="img query-design"
onLoad={data => {
openNewTab(
{
title: file,
icon: 'img query-design',
tooltip,
props: {
conid: connection._id,
database,
savedFile: file,
savedFolder: 'query',
savedFormat: 'json',
},
tabComponent: 'QueryDesignTab',
},
{ editor: data }
);
}}
/>
);
}
export function SavedMarkdownFileAppObject({ data, commonProps }) {
const { file, folder } = data;
const openNewTab = useOpenNewTab();
const showPage = () => {
openNewTab({
title: file,
icon: 'img markdown',
tabComponent: 'MarkdownViewTab',
props: {
savedFile: file,
savedFolder: 'markdown',
savedFormat: 'text',
},
});
};
return (
<SavedFileAppObjectBase
data={data}
commonProps={commonProps}
format="text"
icon="img markdown"
onLoad={data => {
openNewTab(
{
title: file,
icon: 'img markdown',
tabComponent: 'MarkdownEditorTab',
props: {
savedFile: file,
savedFolder: 'markdown',
savedFormat: 'text',
},
},
{ editor: data }
);
}}
menuExt={<DropDownMenuItem onClick={showPage}>Show page</DropDownMenuItem>}
/>
);
}
export function SavedFileAppObject({ data, commonProps }) {
const { folder } = data;
const folderTypes = {
sql: SavedSqlFileAppObject,
shell: SavedShellFileAppObject,
charts: SavedChartFileAppObject,
markdown: SavedMarkdownFileAppObject,
query: SavedQueryFileAppObject,
};
const AppObject = folderTypes[folder];
if (AppObject) {
return <AppObject data={data} commonProps={commonProps} />;
}
return null;
}
[
SavedSqlFileAppObject,
SavedShellFileAppObject,
SavedChartFileAppObject,
SavedMarkdownFileAppObject,
SavedFileAppObject,
].forEach(fn => {
// @ts-ignore
fn.extractKey = data => data.file;
});

View File

@@ -1,36 +0,0 @@
import { findForeignKeyForColumn } from 'dbgate-tools';
import React from 'react';
import { getColumnIcon } from '../datagrid/ColumnLabel';
import { AppObjectCore } from './AppObjectCore';
import { AppObjectList } from './AppObjectList';
function ColumnAppObject({ data, commonProps }) {
const { columnName, dataType, foreignKey } = data;
let extInfo = dataType;
if (foreignKey) extInfo += ` -> ${foreignKey.refTableName}`;
return (
<AppObjectCore
{...commonProps}
data={data}
title={columnName}
extInfo={extInfo}
icon={getColumnIcon(data, true)}
disableHover
/>
);
}
ColumnAppObject.extractKey = ({ columnName }) => columnName;
export default function SubColumnParamList({ data }) {
const { columns } = data;
return (
<AppObjectList
list={(columns || []).map(col => ({
...col,
foreignKey: findForeignKeyForColumn(data, col),
}))}
AppObjectComponent={ColumnAppObject}
/>
);
}