search plugins, plugin tab

This commit is contained in:
Jan Prochazka 2020-11-21 10:01:19 +01:00
parent e2ee1f7561
commit 3771134b1c
15 changed files with 260 additions and 12 deletions

View File

@ -46,6 +46,7 @@
"mssql": "^6.0.1",
"mysql": "^2.17.1",
"nedb-promises": "^4.0.1",
"node-fetch": "^2.6.1",
"pg": "^7.17.0",
"pg-query-stream": "^3.1.1",
"xlsx": "^0.16.8"

View File

@ -0,0 +1,22 @@
const fs = require('fs-extra');
const fetch = require('node-fetch');
module.exports = {
script_meta: 'get',
async script({ plugin }) {
const data = await fs.readFile('/home/jena/jenasoft/dbgate-plugin-csv/lib/frontend.js', {
encoding: 'utf-8',
});
return data;
},
search_meta: 'get',
async search({ filter }) {
console.log(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`);
const response = await fetch(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`);
const json = await response.json();
console.log(json);
const { results } = json || {};
return results || [];
},
};

View File

@ -23,6 +23,7 @@ const config = require('./controllers/config');
const files = require('./controllers/files');
const archive = require('./controllers/archive');
const uploads = require('./controllers/uploads');
const plugins = require('./controllers/plugins');
const { rundir } = require('./utility/directories');
@ -67,6 +68,7 @@ function start(argument = null) {
useController(app, '/files', files);
useController(app, '/archive', archive);
useController(app, '/uploads', uploads);
useController(app, '/plugins', plugins);
if (process.env.PAGES_DIRECTORY) {
app.use('/pages', express.static(process.env.PAGES_DIRECTORY));

View File

@ -35,6 +35,8 @@ const dirFunc = (dirname, clean = false) => () => {
const jsldir = dirFunc('jsl', true);
const rundir = dirFunc('run', true);
const uploadsdir = dirFunc('uploads', true);
const pluginstmpdir = dirFunc('plugins-tmp', true);
const pluginsdir = dirFunc('plugins');
const archivedir = dirFunc('archive');
module.exports = {
@ -44,4 +46,6 @@ module.exports = {
uploadsdir,
archivedir,
ensureDirectory,
pluginstmpdir,
pluginsdir,
};

View File

@ -16,6 +16,7 @@ import ConnectionsPinger from './utility/ConnectionsPinger';
import { ModalLayerProvider } from './modals/showModal';
import UploadsProvider from './utility/UploadsProvider';
import ThemeHelmet from './themes/ThemeHelmet';
import PluginsProvider from './plugins/PluginsProvider';
function App() {
return (
@ -31,7 +32,9 @@ function App() {
<CurrentArchiveProvider>
<CurrentThemeProvider>
<UploadsProvider>
<PluginsProvider>
<ThemeHelmet />
</PluginsProvider>
<Screen />
</UploadsProvider>
</CurrentThemeProvider>

View File

@ -42,6 +42,7 @@ const iconNames = {
'icon run': 'mdi mdi-play',
'icon chevron-down': 'mdi mdi-chevron-down',
'icon plugin': 'mdi mdi-toy-brick',
'img green-ok': 'mdi mdi-check-circle color-green-8',
'img alert': 'mdi mdi-alert-circle color-blue-6',

View File

@ -0,0 +1,86 @@
import React from 'react';
import styled from 'styled-components';
import useTheme from '../theme/useTheme';
import { openNewTab } from '../utility/common';
import { useSetOpenedTabs } from '../utility/globalState';
const Wrapper = styled.div`
margin: 1px 3px 10px 5px;
display: flex;
align-items: center;
&:hover {
background-color: ${(props) => props.theme.left_background_blue[1]};
}
`;
const Texts = styled.div`
margin-left: 10px;
`;
const Name = styled.div`
font-weight: bold;
`;
const Line = styled.div`
display: flex;
`;
const Icon = styled.img`
width: 50px;
height: 50px;
`;
const Description = styled.div`
font-style: italic;
`;
const Author = styled.div`
font-weight: bold;
`;
const Version = styled.div`
margin-left: 5px;
`;
function openPlugin(setOpenedTabs, plugin) {
openNewTab(setOpenedTabs, {
title: plugin.package.name,
icon: 'icon plugin',
tabComponent: 'PluginTab',
props: {
plugin,
},
});
}
function PluginsListItem({ plugin }) {
const setOpenedTabs = useSetOpenedTabs();
const theme = useTheme();
return (
<Wrapper onClick={() => openPlugin(setOpenedTabs, plugin)} theme={theme}>
<Icon src="https://raw.githubusercontent.com/dbshell/dbgate-plugin-csv/master/icon.svg" />
<Texts>
<Line>
<Name>{plugin.package.name}</Name>
<Version>{plugin.package.version}</Version>
</Line>
<Line>
<Description>{plugin.package.description}</Description>
</Line>
<Line>
<Author>{plugin.package.author && plugin.package.author.name}</Author>
</Line>
</Texts>
</Wrapper>
);
}
export default function PluginsList({ plugins }) {
return (
<>
{plugins.map((plugin) => (
<PluginsListItem plugin={plugin} key={plugin.package.name} />
))}
</>
);
}

View File

@ -0,0 +1,23 @@
import React from 'react';
import axios from '../utility/axios';
const PluginsContext = React.createContext(null);
export default function PluginsProvider({ children }) {
const [plugins, setPlugins] = React.useState(null);
const handleLoadPlugin = async () => {
const resp = await axios.request({
method: 'get',
url: 'plugins/script',
params: {
plugin: 'csv',
},
});
const module = eval(resp.data);
console.log('MODULE', module);
};
React.useEffect(() => {
handleLoadPlugin();
}, []);
return <PluginsContext.Provider value={{ plugins, setPlugins }}>{children}</PluginsContext.Provider>;
}

View File

@ -0,0 +1,28 @@
import React from 'react';
import styled from 'styled-components';
import _ from 'lodash';
import ObjectListControl from '../utility/ObjectListControl';
import { TableColumn } from '../utility/TableControl';
import columnAppObject from '../appobj/columnAppObject';
import constraintAppObject from '../appobj/constraintAppObject';
import { useTableInfo, useDbCore } from '../utility/metadataLoaders';
import useTheme from '../theme/useTheme';
const WhitePage = styled.div`
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
background-color: ${(props) => props.theme.main_background};
overflow: auto;
`;
export default function PluginTab({ plugin }) {
const theme = useTheme();
return (
<WhitePage theme={theme}>
<div>{plugin.package.name}</div>
</WhitePage>
);
}

View File

@ -6,6 +6,7 @@ import ShellTab from './ShellTab';
import InfoPageTab from './InfoPageTab';
import ArchiveFileTab from './ArchiveFileTab';
import FreeTableTab from './FreeTableTab';
import PluginTab from './PluginTab';
export default {
TableDataTab,
@ -16,4 +17,5 @@ export default {
ShellTab,
ArchiveFileTab,
FreeTableTab,
PluginTab,
};

View File

@ -1,19 +1,10 @@
import React from 'react';
import styled from 'styled-components';
import _ from 'lodash';
import { AppObjectList } from '../appobj/AppObjectList';
import { useCurrentArchive, useOpenedTabs, useSavedSqlFiles, useSetCurrentArchive } from '../utility/globalState';
import closedTabAppObject from '../appobj/closedTabAppObject';
import {
SearchBoxWrapper,
WidgetsInnerContainer,
WidgetsMainContainer,
WidgetsOuterContainer,
WidgetTitle,
} from './WidgetStyles';
import { useCurrentArchive, useSetCurrentArchive } from '../utility/globalState';
import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles';
import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar';
import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject';
import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders';
import archiveFolderAppObject from '../appobj/archiveFolderAppObject';
import archiveFileAppObject from '../appobj/archiveFileAppObject';

View File

@ -0,0 +1,73 @@
import React from 'react';
import _ from 'lodash';
import { AppObjectList } from '../appobj/AppObjectList';
import { useCurrentArchive, useSetCurrentArchive } from '../utility/globalState';
import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles';
import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar';
import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders';
import archiveFolderAppObject from '../appobj/archiveFolderAppObject';
import archiveFileAppObject from '../appobj/archiveFileAppObject';
import SearchInput from './SearchInput';
import InlineButton from './InlineButton';
import axios from '../utility/axios';
import useFetch from '../utility/useFetch';
import PluginsList from '../plugins/PluginsList';
function InstalledPluginsList() {
// const folders = useArchiveFolders();
// const [filter, setFilter] = React.useState('');
// const setArchive = useSetCurrentArchive();
// const handleRefreshFolders = () => {
// axios.post('archive/refresh-folders', {});
// };
return (
<WidgetsInnerContainer>
{/* <AppObjectList
list={_.sortBy(folders, 'name')}
makeAppObj={archiveFolderAppObject()}
onObjectClick={(archive) => setArchive(archive.name)}
filter={filter}
/> */}
</WidgetsInnerContainer>
);
}
function AvailablePluginsList() {
const [filter, setFilter] = React.useState('');
const plugins = useFetch({
url: 'plugins/search',
params: {
filter,
},
defaultValue: [],
});
return (
<>
<SearchBoxWrapper>
<SearchInput placeholder="Search extensions on web" filter={filter} setFilter={setFilter} />
</SearchBoxWrapper>
<WidgetsInnerContainer>
<PluginsList plugins={plugins} />
</WidgetsInnerContainer>
</>
);
}
export default function PluginsWidget() {
return (
<WidgetColumnBar>
<WidgetColumnBarItem title="Installed extensions" name="installed" height="50%">
<InstalledPluginsList />
</WidgetColumnBarItem>
<WidgetColumnBarItem title="Available extensions" name="all">
<AvailablePluginsList />
</WidgetColumnBarItem>
</WidgetColumnBar>
);
}

View File

@ -3,11 +3,13 @@ import { useCurrentWidget } from '../utility/globalState';
import ArchiveWidget from './ArchiveWidget';
import DatabaseWidget from './DatabaseWidget';
import FilesWidget from './FilesWidget';
import PluginsWidget from './PluginsWidget';
export default function WidgetContainer() {
const currentWidget = useCurrentWidget();
if (currentWidget === 'database') return <DatabaseWidget />;
if (currentWidget === 'file') return <FilesWidget />;
if (currentWidget === 'archive') return <ArchiveWidget />;
if (currentWidget === 'plugins') return <PluginsWidget />;
return null;
}

View File

@ -51,6 +51,11 @@ export default function WidgetIconPanel() {
name: 'archive',
title: 'Archive (saved tabular data)',
},
{
icon: 'icon plugin',
name: 'plugins',
title: 'Extensions & Plugins',
},
// {
// icon: 'fa-cog',
// name: 'settings',

View File

@ -7960,6 +7960,11 @@ node-fetch@^1.0.1:
encoding "^0.1.11"
is-stream "^1.0.1"
node-fetch@^2.6.1:
version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-forge@0.9.0:
version "0.9.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"