mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-03 01:23:57 +00:00
install/uninstall plugin
This commit is contained in:
@@ -2,12 +2,32 @@ const fs = require('fs-extra');
|
|||||||
const fetch = require('node-fetch');
|
const fetch = require('node-fetch');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const pacote = require('pacote');
|
const pacote = require('pacote');
|
||||||
const { pluginstmpdir } = require('../utility/directories');
|
const { pluginstmpdir, pluginsdir } = require('../utility/directories');
|
||||||
|
const socket = require('../utility/socket');
|
||||||
|
|
||||||
|
async function loadPackageInfo(dir) {
|
||||||
|
const readmeFile = path.join(dir, 'README.md');
|
||||||
|
const packageFile = path.join(dir, 'package.json');
|
||||||
|
|
||||||
|
if (!(await fs.exists(packageFile))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
let readme = null;
|
||||||
|
let manifest = null;
|
||||||
|
if (await fs.exists(readmeFile)) readme = await fs.readFile(readmeFile, { encoding: 'utf-8' });
|
||||||
|
if (await fs.exists(packageFile)) manifest = JSON.parse(await fs.readFile(packageFile, { encoding: 'utf-8' }));
|
||||||
|
return {
|
||||||
|
readme,
|
||||||
|
manifest,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
script_meta: 'get',
|
script_meta: 'get',
|
||||||
async script({ packageName }) {
|
async script({ packageName }) {
|
||||||
const data = await fs.readFile('/home/jena/jenasoft/dbgate-plugin-csv/lib/frontend.js', {
|
const file = path.join(pluginsdir(), packageName, 'lib', 'frontend.js');
|
||||||
|
const data = await fs.readFile(file, {
|
||||||
encoding: 'utf-8',
|
encoding: 'utf-8',
|
||||||
});
|
});
|
||||||
return data;
|
return data;
|
||||||
@@ -15,21 +35,54 @@ module.exports = {
|
|||||||
|
|
||||||
search_meta: 'get',
|
search_meta: 'get',
|
||||||
async search({ filter }) {
|
async search({ filter }) {
|
||||||
const response = await fetch(`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();
|
||||||
|
// const { results } = json || {};
|
||||||
|
// return (results || []).map((x) => x.package);
|
||||||
|
|
||||||
|
const response = await fetch(
|
||||||
|
`https://www.npmjs.com/search/suggestions?q=dbgate-plugin ${encodeURIComponent(filter)}`
|
||||||
|
);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
console.log(json);
|
return json || [];
|
||||||
const { results } = json || {};
|
|
||||||
return results || [];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
readme_meta: 'get',
|
info_meta: 'get',
|
||||||
async readme({ packageName }) {
|
async info({ packageName }) {
|
||||||
const dir = path.join(pluginstmpdir(), packageName);
|
const dir = path.join(pluginstmpdir(), packageName);
|
||||||
if (!(await fs.exists(dir))) {
|
if (!(await fs.exists(dir))) {
|
||||||
await pacote.extract(packageName, dir);
|
await pacote.extract(packageName, dir);
|
||||||
}
|
}
|
||||||
const file = path.join(dir, 'README.md');
|
return await loadPackageInfo(dir);
|
||||||
if (await fs.exists(file)) return await fs.readFile(file, { encoding: 'utf-8' });
|
// return await {
|
||||||
return '';
|
// ...loadPackageInfo(dir),
|
||||||
|
// installed: loadPackageInfo(path.join(pluginsdir(), packageName)),
|
||||||
|
// };
|
||||||
|
},
|
||||||
|
|
||||||
|
installed_meta: 'get',
|
||||||
|
async installed() {
|
||||||
|
const files = await fs.readdir(pluginsdir());
|
||||||
|
return await Promise.all(
|
||||||
|
files.map((packageName) =>
|
||||||
|
fs.readFile(path.join(pluginsdir(), packageName, 'package.json')).then((x) => JSON.parse(x))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
install_meta: 'post',
|
||||||
|
async install({ packageName }) {
|
||||||
|
const dir = path.join(pluginsdir(), packageName);
|
||||||
|
if (!(await fs.exists(dir))) {
|
||||||
|
await pacote.extract(packageName, dir);
|
||||||
|
}
|
||||||
|
socket.emitChanged(`installed-plugins-changed`);
|
||||||
|
},
|
||||||
|
|
||||||
|
uninstall_meta: 'post',
|
||||||
|
async uninstall({ packageName }) {
|
||||||
|
const dir = path.join(pluginsdir(), packageName);
|
||||||
|
await fs.rmdir(dir, { recursive: true });
|
||||||
|
socket.emitChanged(`installed-plugins-changed`);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
15
packages/web/public/unknown.svg
Normal file
15
packages/web/public/unknown.svg
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" version="1.1" width="116" height="116" id="svg2">
|
||||||
|
<defs id="defs4"/>
|
||||||
|
<metadata id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||||
|
<dc:title/>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<text x="10.710938" y="111.5" id="text2996" xml:space="preserve" style="font-size:144px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans"><tspan x="10.710938" y="111.5" id="tspan2998" style="font-size:150px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:Arial;-inkscape-font-specification:Arial Bold">?</tspan></text>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -1,7 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
|
|
||||||
export default function PluginIcon({ plugin, className = undefined }) {
|
|
||||||
return (
|
|
||||||
<img src="https://raw.githubusercontent.com/dbshell/dbgate-plugin-csv/master/icon.svg" className={className} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,7 @@ import styled from 'styled-components';
|
|||||||
import useTheme from '../theme/useTheme';
|
import useTheme from '../theme/useTheme';
|
||||||
import { openNewTab } from '../utility/common';
|
import { openNewTab } from '../utility/common';
|
||||||
import { useSetOpenedTabs } from '../utility/globalState';
|
import { useSetOpenedTabs } from '../utility/globalState';
|
||||||
import PluginIcon from './PluginIcon';
|
import { extractPluginIcon, extractPluginAuthor } from '../plugins/manifestExtractors';
|
||||||
|
|
||||||
const Wrapper = styled.div`
|
const Wrapper = styled.div`
|
||||||
margin: 1px 3px 10px 5px;
|
margin: 1px 3px 10px 5px;
|
||||||
@@ -26,7 +26,7 @@ const Line = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Icon = styled(PluginIcon)`
|
const Icon = styled.img`
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
`;
|
`;
|
||||||
@@ -43,33 +43,33 @@ const Version = styled.div`
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
function openPlugin(setOpenedTabs, plugin) {
|
function openPlugin(setOpenedTabs, packageManifest) {
|
||||||
openNewTab(setOpenedTabs, {
|
openNewTab(setOpenedTabs, {
|
||||||
title: plugin.package.name,
|
title: packageManifest.name,
|
||||||
icon: 'icon plugin',
|
icon: 'icon plugin',
|
||||||
tabComponent: 'PluginTab',
|
tabComponent: 'PluginTab',
|
||||||
props: {
|
props: {
|
||||||
plugin,
|
packageName: packageManifest.name,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function PluginsListItem({ plugin }) {
|
function PluginsListItem({ packageManifest }) {
|
||||||
const setOpenedTabs = useSetOpenedTabs();
|
const setOpenedTabs = useSetOpenedTabs();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
return (
|
return (
|
||||||
<Wrapper onClick={() => openPlugin(setOpenedTabs, plugin)} theme={theme}>
|
<Wrapper onClick={() => openPlugin(setOpenedTabs, packageManifest)} theme={theme}>
|
||||||
<Icon plugin={plugin} />
|
<Icon src={extractPluginIcon(packageManifest)} />
|
||||||
<Texts>
|
<Texts>
|
||||||
<Line>
|
<Line>
|
||||||
<Name>{plugin.package.name}</Name>
|
<Name>{packageManifest.name}</Name>
|
||||||
<Version>{plugin.package.version}</Version>
|
<Version>{packageManifest.version}</Version>
|
||||||
</Line>
|
</Line>
|
||||||
<Line>
|
<Line>
|
||||||
<Description>{plugin.package.description}</Description>
|
<Description>{packageManifest.description}</Description>
|
||||||
</Line>
|
</Line>
|
||||||
<Line>
|
<Line>
|
||||||
<Author>{plugin.package.author && plugin.package.author.name}</Author>
|
<Author>{extractPluginAuthor(packageManifest)}</Author>
|
||||||
</Line>
|
</Line>
|
||||||
</Texts>
|
</Texts>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
@@ -79,8 +79,8 @@ function PluginsListItem({ plugin }) {
|
|||||||
export default function PluginsList({ plugins }) {
|
export default function PluginsList({ plugins }) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{plugins.map((plugin) => (
|
{plugins.map((packageManifest) => (
|
||||||
<PluginsListItem plugin={plugin} key={plugin.package.name} />
|
<PluginsListItem packageManifest={packageManifest} key={packageManifest.name} />
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,23 +1,40 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import _ from 'lodash';
|
||||||
import axios from '../utility/axios';
|
import axios from '../utility/axios';
|
||||||
|
import { useInstalledPlugins } from '../utility/metadataLoaders';
|
||||||
|
|
||||||
const PluginsContext = React.createContext(null);
|
const PluginsContext = React.createContext(null);
|
||||||
|
|
||||||
export default function PluginsProvider({ children }) {
|
export default function PluginsProvider({ children }) {
|
||||||
const [plugins, setPlugins] = React.useState(null);
|
const installedPlugins = useInstalledPlugins();
|
||||||
const handleLoadPlugin = async () => {
|
const [plugins, setPlugins] = React.useState({});
|
||||||
const resp = await axios.request({
|
const handleLoadPlugins = async () => {
|
||||||
method: 'get',
|
setPlugins((x) =>
|
||||||
url: 'plugins/script',
|
_.pick(
|
||||||
params: {
|
x,
|
||||||
plugin: 'csv',
|
installedPlugins.map((y) => y.name)
|
||||||
},
|
)
|
||||||
});
|
);
|
||||||
const module = eval(resp.data);
|
for (const installed of installedPlugins) {
|
||||||
console.log('MODULE', module);
|
if (!_.keys(plugins).includes(installed.name)) {
|
||||||
|
console.log('Loading module', installed.name);
|
||||||
|
const resp = await axios.request({
|
||||||
|
method: 'get',
|
||||||
|
url: 'plugins/script',
|
||||||
|
params: {
|
||||||
|
packageName: installed.name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const module = eval(resp.data);
|
||||||
|
setPlugins((v) => ({
|
||||||
|
...v,
|
||||||
|
[installed.name]: module,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
handleLoadPlugin();
|
handleLoadPlugins();
|
||||||
}, []);
|
}, [installedPlugins]);
|
||||||
return <PluginsContext.Provider value={{ plugins, setPlugins }}>{children}</PluginsContext.Provider>;
|
return <PluginsContext.Provider value={plugins}>{children}</PluginsContext.Provider>;
|
||||||
}
|
}
|
||||||
|
|||||||
20
packages/web/src/plugins/manifestExtractors.js
Normal file
20
packages/web/src/plugins/manifestExtractors.js
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export function extractPluginIcon(packageManifest) {
|
||||||
|
const { links } = packageManifest || {};
|
||||||
|
const { repository, homepage } = links || {};
|
||||||
|
const tested = repository || homepage || packageManifest.homepage;
|
||||||
|
|
||||||
|
if (tested) {
|
||||||
|
const match = tested.match(/https:\/\/github.com\/([^/]*)\/([^/]*)/);
|
||||||
|
if (match) {
|
||||||
|
return `https://raw.githubusercontent.com/${match[1]}/${match[2]}/master/icon.svg`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
return `${process.env.PUBLIC_URL}/unknown.svg`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractPluginAuthor(packageManifest) {
|
||||||
|
return _.isPlainObject(packageManifest.author) ? packageManifest.author.name : packageManifest.author;
|
||||||
|
}
|
||||||
@@ -2,14 +2,13 @@ import React from 'react';
|
|||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
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';
|
import useTheme from '../theme/useTheme';
|
||||||
import useFetch from '../utility/useFetch';
|
import useFetch from '../utility/useFetch';
|
||||||
import LoadingInfo from '../widgets/LoadingInfo';
|
import LoadingInfo from '../widgets/LoadingInfo';
|
||||||
|
import { extractPluginIcon, extractPluginAuthor } from '../plugins/manifestExtractors';
|
||||||
|
import FormStyledButton from '../widgets/FormStyledButton';
|
||||||
|
import axios from '../utility/axios';
|
||||||
|
import { useInstalledPlugins } from '../utility/metadataLoaders';
|
||||||
|
|
||||||
const WhitePage = styled.div`
|
const WhitePage = styled.div`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -22,23 +21,84 @@ const WhitePage = styled.div`
|
|||||||
padding: 10px;
|
padding: 10px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Title = styled.div`
|
const Icon = styled.img`
|
||||||
font-size: 20pt;
|
width: 80px;
|
||||||
border-bottom: 1px solid ${(props) => props.theme.border};
|
height: 80px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function PluginTab({ plugin }) {
|
const Header = styled.div`
|
||||||
|
display: flex;
|
||||||
|
border-bottom: 1px solid ${(props) => props.theme.border};
|
||||||
|
margin-bottom: 20px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const HeaderBody = styled.div`
|
||||||
|
margin-left: 10px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Title = styled.div`
|
||||||
|
font-size: 20pt;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const HeaderLine = styled.div`
|
||||||
|
margin-top: 5px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Author = styled.span`
|
||||||
|
font-weight: bold;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Version = styled.span``;
|
||||||
|
|
||||||
|
function Delimiter() {
|
||||||
|
return <span> | </span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function PluginTab({ packageName }) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const packageName = plugin.package.name;
|
const installed = useInstalledPlugins();
|
||||||
const readme = useFetch({
|
const info = useFetch({
|
||||||
params: { packageName },
|
params: { packageName },
|
||||||
url: 'plugins/readme',
|
url: 'plugins/info',
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
});
|
});
|
||||||
|
const { readme, manifest } = info || {};
|
||||||
|
const handleInstall = async () => {
|
||||||
|
axios.post('plugins/install', { packageName });
|
||||||
|
};
|
||||||
|
const handleUninstall = async () => {
|
||||||
|
axios.post('plugins/uninstall', { packageName });
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WhitePage theme={theme}>
|
<WhitePage theme={theme}>
|
||||||
<Title theme={theme}>{packageName}</Title>
|
{info == null || manifest == null ? (
|
||||||
{readme == null ? <LoadingInfo message="Loading extension detail" /> : <ReactMarkdown>{readme}</ReactMarkdown>}
|
<LoadingInfo message="Loading extension detail" />
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Header theme={theme}>
|
||||||
|
<Icon src={extractPluginIcon(manifest)} />
|
||||||
|
<HeaderBody>
|
||||||
|
<Title theme={theme}>{packageName}</Title>
|
||||||
|
<HeaderLine>
|
||||||
|
<Author>{extractPluginAuthor(manifest)}</Author>
|
||||||
|
<Delimiter />
|
||||||
|
<Version>{manifest.version && manifest.version}</Version>
|
||||||
|
</HeaderLine>
|
||||||
|
<HeaderLine>
|
||||||
|
{!installed.find((x) => x.name == packageName) && (
|
||||||
|
<FormStyledButton type="button" value="Install" onClick={handleInstall} />
|
||||||
|
)}
|
||||||
|
{!!installed.find((x) => x.name == packageName) && (
|
||||||
|
<FormStyledButton type="button" value="Uninstall" onClick={handleUninstall} />
|
||||||
|
)}
|
||||||
|
</HeaderLine>
|
||||||
|
</HeaderBody>
|
||||||
|
</Header>
|
||||||
|
<ReactMarkdown>{readme}</ReactMarkdown>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</WhitePage>
|
</WhitePage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,6 +88,12 @@ const connectionListLoader = () => ({
|
|||||||
reloadTrigger: `connection-list-changed`,
|
reloadTrigger: `connection-list-changed`,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const insttalledPluginsLoader = () => ({
|
||||||
|
url: 'plugins/installed',
|
||||||
|
params: {},
|
||||||
|
reloadTrigger: `installed-plugins-changed`,
|
||||||
|
});
|
||||||
|
|
||||||
async function getCore(loader, args) {
|
async function getCore(loader, args) {
|
||||||
const { url, params, reloadTrigger, transform } = loader(args);
|
const { url, params, reloadTrigger, transform } = loader(args);
|
||||||
const key = stableStringify({ url, ...params });
|
const key = stableStringify({ url, ...params });
|
||||||
@@ -243,3 +249,10 @@ export function getArchiveFolders(args) {
|
|||||||
export function useArchiveFolders(args) {
|
export function useArchiveFolders(args) {
|
||||||
return useCore(archiveFoldersLoader, args);
|
return useCore(archiveFoldersLoader, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getInstalledPlugins(args) {
|
||||||
|
return getCore(insttalledPluginsLoader, args) || [];
|
||||||
|
}
|
||||||
|
export function useInstalledPlugins(args) {
|
||||||
|
return useCore(insttalledPluginsLoader, args) || [];
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,37 +1,17 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
import { AppObjectList } from '../appobj/AppObjectList';
|
|
||||||
import { useCurrentArchive, useSetCurrentArchive } from '../utility/globalState';
|
|
||||||
import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles';
|
import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles';
|
||||||
import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar';
|
import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar';
|
||||||
import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders';
|
import { useInstalledPlugins } from '../utility/metadataLoaders';
|
||||||
import archiveFolderAppObject from '../appobj/archiveFolderAppObject';
|
|
||||||
import archiveFileAppObject from '../appobj/archiveFileAppObject';
|
|
||||||
import SearchInput from './SearchInput';
|
import SearchInput from './SearchInput';
|
||||||
import InlineButton from './InlineButton';
|
|
||||||
import axios from '../utility/axios';
|
|
||||||
import useFetch from '../utility/useFetch';
|
import useFetch from '../utility/useFetch';
|
||||||
import PluginsList from '../plugins/PluginsList';
|
import PluginsList from '../plugins/PluginsList';
|
||||||
|
|
||||||
function InstalledPluginsList() {
|
function InstalledPluginsList() {
|
||||||
// const folders = useArchiveFolders();
|
const plugins = useInstalledPlugins();
|
||||||
// const [filter, setFilter] = React.useState('');
|
|
||||||
|
|
||||||
// const setArchive = useSetCurrentArchive();
|
|
||||||
|
|
||||||
// const handleRefreshFolders = () => {
|
|
||||||
// axios.post('archive/refresh-folders', {});
|
|
||||||
// };
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WidgetsInnerContainer>
|
<WidgetsInnerContainer>
|
||||||
{/* <AppObjectList
|
<PluginsList plugins={plugins} />
|
||||||
list={_.sortBy(folders, 'name')}
|
|
||||||
makeAppObj={archiveFolderAppObject()}
|
|
||||||
onObjectClick={(archive) => setArchive(archive.name)}
|
|
||||||
filter={filter}
|
|
||||||
/> */}
|
|
||||||
</WidgetsInnerContainer>
|
</WidgetsInnerContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user