diff --git a/packages/api/src/controllers/serverConnections.js b/packages/api/src/controllers/serverConnections.js
index aeaf1fdb0..b30f977bc 100644
--- a/packages/api/src/controllers/serverConnections.js
+++ b/packages/api/src/controllers/serverConnections.js
@@ -5,7 +5,7 @@ const _ = require('lodash');
module.exports = {
opened: [],
- closed: [],
+ closed: {},
handle_databases(conid, { databases }) {
const existing = this.opened.find((x) => x.conid == conid);
@@ -40,7 +40,7 @@ module.exports = {
disconnected: false,
};
this.opened.push(newOpened);
- this.closed = this.closed.filter((x) => x != conid);
+ delete this.closed[conid];
socket.emitChanged(`server-status-changed`);
// @ts-ignore
subprocess.on('message', ({ msgtype, ...message }) => {
@@ -49,21 +49,24 @@ module.exports = {
});
subprocess.on('exit', () => {
if (newOpened.disconnected) return;
- this.opened = this.opened.filter((x) => x.conid != conid);
- this.closed.push(conid);
- socket.emitChanged(`server-status-changed`);
+ this.close(conid, false);
});
subprocess.send({ msgtype: 'connect', ...connection });
return newOpened;
},
- close(conid) {
+ close(conid, kill = true) {
const existing = this.opened.find((x) => x.conid == conid);
if (existing) {
existing.disconnected = true;
- existing.subprocess.kill();
+ if (kill) existing.subprocess.kill();
+ const last = this.opened.find((x) => x.conid == conid);
this.opened = this.opened.filter((x) => x.conid != conid);
- this.closed.push(conid);
+ this.closed[conid] = {
+ ...(last && last.status),
+ name: 'error',
+ };
+ socket.emitChanged(`server-status-changed`);
}
},
@@ -76,15 +79,7 @@ module.exports = {
serverStatus_meta: 'get',
async serverStatus() {
return {
- ...this.closed.reduce(
- (res, conid) => ({
- ...res,
- [conid]: {
- name: 'error',
- },
- }),
- {}
- ),
+ ...this.closed,
..._.mapValues(_.keyBy(this.opened, 'conid'), 'status'),
};
},
diff --git a/packages/api/src/proc/serverConnectionProcess.js b/packages/api/src/proc/serverConnectionProcess.js
index 745875ac6..552ca422f 100644
--- a/packages/api/src/proc/serverConnectionProcess.js
+++ b/packages/api/src/proc/serverConnectionProcess.js
@@ -20,9 +20,12 @@ async function handleRefresh() {
lastDatabases = databasesString;
}
} catch (err) {
- setStatusName('error');
- console.error(err);
- process.exit(1);
+ setStatus({
+ name: 'error',
+ message: err.message,
+ });
+ // console.error(err);
+ setTimeout(() => process.exit(1), 1000);
}
}
@@ -49,9 +52,12 @@ async function handleConnect(connection) {
handleRefresh();
setInterval(handleRefresh, 30 * 1000);
} catch (err) {
- setStatusName('error');
- console.error(err);
- process.exit(1);
+ setStatus({
+ name: 'error',
+ message: err.message,
+ });
+ // console.error(err);
+ setTimeout(() => process.exit(1), 1000);
}
}
diff --git a/packages/web/src/appobj/AppObjectList.js b/packages/web/src/appobj/AppObjectList.js
index c36da4cbf..56689c9af 100644
--- a/packages/web/src/appobj/AppObjectList.js
+++ b/packages/web/src/appobj/AppObjectList.js
@@ -34,14 +34,30 @@ function AppObjectListItem({ makeAppObj, data, filter, appobj, onObjectClick, Su
const [isExpanded, setIsExpanded] = React.useState(false);
const [isHover, setIsHover] = React.useState(false);
+ React.useEffect(() => {
+ if (!appobj.isExpandable) {
+ // if (data._id == '6pOY2iFY8Gsq7mk6') console.log('COLLAPSE1');
+ setIsExpanded(false);
+ }
+ }, [appobj && appobj.isExpandable]);
+
// const { matcher } = appobj;
// if (matcher && !matcher(filter)) return null;
- if (onObjectClick) appobj.onClick = onObjectClick;
+
+ if (onObjectClick)
+ appobj = {
+ ...appobj,
+ onClick: onObjectClick,
+ };
if (SubItems) {
const oldClick = appobj.onClick;
- appobj.onClick = () => {
- if (oldClick) oldClick();
- setIsExpanded(!isExpanded);
+ appobj = {
+ ...appobj,
+ onClick: () => {
+ if (oldClick) oldClick();
+ // if (data._id == '6pOY2iFY8Gsq7mk6') console.log('COLLAPSE2');
+ setIsExpanded((v) => !v);
+ },
};
}
diff --git a/packages/web/src/appobj/AppObjects.js b/packages/web/src/appobj/AppObjects.js
index e52281c49..d074714f9 100644
--- a/packages/web/src/appobj/AppObjects.js
+++ b/packages/web/src/appobj/AppObjects.js
@@ -42,6 +42,7 @@ export function AppObjectCore({
component = 'div',
prefix = null,
statusIcon,
+ statusTitle,
...other
}) {
const appObjectParams = useAppObjectParams();
@@ -71,7 +72,7 @@ export function AppObjectCore({
{title}
{statusIcon && (
-
+
)}
diff --git a/packages/web/src/appobj/connectionAppObject.js b/packages/web/src/appobj/connectionAppObject.js
index f51b6b0de..d84fc9e1c 100644
--- a/packages/web/src/appobj/connectionAppObject.js
+++ b/packages/web/src/appobj/connectionAppObject.js
@@ -7,7 +7,7 @@ import ConnectionModal from '../modals/ConnectionModal';
import axios from '../utility/axios';
import { filterName } from '@dbgate/datalib';
-function Menu({ data, setOpenedConnections }) {
+function Menu({ data, setOpenedConnections, openedConnections }) {
const handleEdit = () => {
showModal((modalState) => );
};
@@ -24,8 +24,12 @@ function Menu({ data, setOpenedConnections }) {
<>
Edit
Delete
- Refresh
- Disconnect
+ {openedConnections.includes(data._id) && data.status && (
+ Refresh
+ )}
+ {openedConnections.includes(data._id) && (
+ Disconnect
+ )}
>
);
}
@@ -47,13 +51,16 @@ const connectionAppObject = (flags) => (
: null;
const onClick = () => setOpenedConnections((c) => [...c, _id]);
- // let isBusy = false;
let statusIcon = null;
+ let statusTitle = null;
if (openedConnections.includes(_id)) {
if (!status) statusIcon = 'fas fa-spinner fa-spin';
else if (status.name == 'pending') statusIcon = 'fas fa-spinner fa-spin';
else if (status.name == 'ok') statusIcon = 'fas fa-check-circle green';
else statusIcon = 'fas fa-times-circle red';
+ if (status && status.name == 'error') {
+ statusTitle = status.message;
+ }
}
return {
@@ -65,8 +72,8 @@ const connectionAppObject = (flags) => (
isBold,
isExpandable,
onClick,
- // isBusy,
statusIcon,
+ statusTitle,
};
};
diff --git a/packages/web/src/icons.js b/packages/web/src/icons.js
index 2748bd9f7..16de8be49 100644
--- a/packages/web/src/icons.js
+++ b/packages/web/src/icons.js
@@ -26,15 +26,12 @@ export function FontIcon({ icon, ...props }) {
let className = props.className || '';
- // if (_.startsWith(name, 'bs-')) className += ` glyphicon glyphicon-${name.substr(3)}`;
if (type == 'fas' || type == 'far') className += ` ${type} ${name} ${parts.join(' ')}`;
- if (_.includes(parts, 'spin')) className += ' fa-spin';
-
const style = { ...props.style };
const last = parts[parts.length - 1];
- if (last && last != 'spin') {
+ if (last && last != 'fa-spin') {
style['color'] = last;
}
diff --git a/packages/web/src/widgets/DatabaseWidget.js b/packages/web/src/widgets/DatabaseWidget.js
index 50c699804..acfbe76bc 100644
--- a/packages/web/src/widgets/DatabaseWidget.js
+++ b/packages/web/src/widgets/DatabaseWidget.js
@@ -4,11 +4,12 @@ import _ from 'lodash';
import { AppObjectList } from '../appobj/AppObjectList';
import connectionAppObject from '../appobj/connectionAppObject';
import databaseAppObject from '../appobj/databaseAppObject';
-import { useSetCurrentDatabase, useCurrentDatabase } from '../utility/globalState';
+import { useSetCurrentDatabase, useCurrentDatabase, useOpenedConnections } from '../utility/globalState';
import InlineButton from './InlineButton';
import databaseObjectAppObject from '../appobj/databaseObjectAppObject';
import { useSqlObjectList, useDatabaseList, useConnectionList, useServerStatus } from '../utility/metadataLoaders';
import { SearchBoxWrapper, InnerContainer, Input, MainContainer, OuterContainer, WidgetTitle } from './WidgetStyles';
+import axios from '../utility/axios';
function SubDatabaseList({ data }) {
const setDb = useSetCurrentDatabase();
@@ -32,8 +33,17 @@ function SubDatabaseList({ data }) {
function ConnectionList() {
const connections = useConnectionList();
const serverStatus = useServerStatus();
+ const openedConnections = useOpenedConnections();
const connectionsWithStatus =
- connections && serverStatus && connections.map((conn) => ({ ...conn, status: serverStatus[conn._id] }));
+ connections && serverStatus
+ ? connections.map((conn) => ({ ...conn, status: serverStatus[conn._id] }))
+ : connections;
+
+ const handleRefreshConnections = () => {
+ for (const conid of openedConnections) {
+ axios.post('server-connections/refresh', { conid });
+ }
+ };
const [filter, setFilter] = React.useState('');
return (
@@ -41,7 +51,7 @@ function ConnectionList() {
Connections
setFilter(e.target.value)} />
- Refresh
+ Refresh