diff --git a/packages/web/src/Screen.js b/packages/web/src/Screen.js
index db7ebae6e..8299dce9f 100644
--- a/packages/web/src/Screen.js
+++ b/packages/web/src/Screen.js
@@ -100,6 +100,7 @@ export default function Screen() {
? dimensions.widgetMenu.iconSize + leftPanelWidth + dimensions.splitter.thickness
: dimensions.widgetMenu.iconSize;
const toolbarPortalRef = React.useRef();
+ const statusbarPortalRef = React.useRef();
const onSplitDown = useSplitterDrag('clientX', diff => setLeftPanelWidth(v => v + diff));
const { getRootProps, getInputProps, isDragActive } = useUploadsZone();
@@ -131,10 +132,10 @@ export default function Screen() {
-
+
-
+
diff --git a/packages/web/src/TabContent.js b/packages/web/src/TabContent.js
index f4733d669..f90da055f 100644
--- a/packages/web/src/TabContent.js
+++ b/packages/web/src/TabContent.js
@@ -18,12 +18,18 @@ const TabContainerStyled = styled.div`
`;
function TabContainer({ TabComponent, ...props }) {
- const { tabVisible, tabid, toolbarPortalRef } = props;
+ const { tabVisible, tabid, toolbarPortalRef, statusbarPortalRef } = props;
return (
// @ts-ignore
-
+
);
@@ -42,7 +48,7 @@ function createTabComponent(selectedTab) {
return null;
}
-export default function TabContent({ toolbarPortalRef }) {
+export default function TabContent({ toolbarPortalRef, statusbarPortalRef }) {
const files = useOpenedTabs();
const [mountedTabs, setMountedTabs] = React.useState({});
@@ -84,6 +90,7 @@ export default function TabContent({ toolbarPortalRef }) {
tabid={tabid}
tabVisible={tabVisible}
toolbarPortalRef={toolbarPortalRef}
+ statusbarPortalRef={statusbarPortalRef}
TabComponent={TabComponent}
/>
);
diff --git a/packages/web/src/tabs/QueryTab.js b/packages/web/src/tabs/QueryTab.js
index a945fc861..bc50240b7 100644
--- a/packages/web/src/tabs/QueryTab.js
+++ b/packages/web/src/tabs/QueryTab.js
@@ -21,8 +21,19 @@ import useEditorData from '../utility/useEditorData';
import applySqlTemplate from '../utility/applySqlTemplate';
import LoadingInfo from '../widgets/LoadingInfo';
import useExtensions from '../utility/useExtensions';
+import useTimerLabel from '../utility/useTimerLabel';
+import { StatusBarItem } from '../widgets/StatusBar';
-export default function QueryTab({ tabid, conid, database, initialArgs, tabVisible, toolbarPortalRef, ...other }) {
+export default function QueryTab({
+ tabid,
+ conid,
+ database,
+ initialArgs,
+ tabVisible,
+ toolbarPortalRef,
+ statusbarPortalRef,
+ ...other
+}) {
const [sessionId, setSessionId] = React.useState(null);
const [visibleResultTabs, setVisibleResultTabs] = React.useState(false);
const [executeNumber, setExecuteNumber] = React.useState(0);
@@ -31,6 +42,7 @@ export default function QueryTab({ tabid, conid, database, initialArgs, tabVisib
const [busy, setBusy] = React.useState(false);
const saveFileModalState = useModalState();
const extensions = useExtensions();
+ const timerLabel = useTimerLabel();
const { editorData, setEditorData, isLoading } = useEditorData({
tabid,
loadFromArgs:
@@ -43,6 +55,7 @@ export default function QueryTab({ tabid, conid, database, initialArgs, tabVisib
const handleSessionDone = React.useCallback(() => {
setBusy(false);
+ timerLabel.stop();
}, []);
React.useEffect(() => {
@@ -77,6 +90,7 @@ export default function QueryTab({ tabid, conid, database, initialArgs, tabVisib
setSessionId(sesid);
}
setBusy(true);
+ timerLabel.start();
await axios.post('sessions/execute-query', {
sesid,
sql: selectedText || editorData,
@@ -95,6 +109,7 @@ export default function QueryTab({ tabid, conid, database, initialArgs, tabVisib
});
setSessionId(null);
setBusy(false);
+ timerLabel.stop();
};
const handleKeyDown = (data, hash, keyString, keyCode, event) => {
@@ -167,6 +182,10 @@ export default function QueryTab({ tabid, conid, database, initialArgs, tabVisib
/>,
toolbarPortalRef.current
)}
+ {statusbarPortalRef &&
+ statusbarPortalRef.current &&
+ tabVisible &&
+ ReactDOM.createPortal({timerLabel.text}, statusbarPortalRef.current)}
{
+ if (busy) {
+ setDuration(0);
+ const handle = setInterval(() => setDuration(x => x + 1), 1000);
+ return () => window.clearInterval(handle);
+ }
+ }, [busy]);
+
+ const start = React.useCallback(() => {
+ setBusy(true);
+ }, []);
+
+ const stop = React.useCallback(() => {
+ setBusy(false);
+ }, []);
+
+ return {
+ start,
+ stop,
+ text: formatSeconds(duration),
+ duration,
+ };
+}
diff --git a/packages/web/src/widgets/StatusBar.js b/packages/web/src/widgets/StatusBar.js
index 097b4c135..7d4849b69 100644
--- a/packages/web/src/widgets/StatusBar.js
+++ b/packages/web/src/widgets/StatusBar.js
@@ -10,9 +10,10 @@ const Container = styled.div`
display: flex;
color: ${props => props.theme.statusbar_font1};
align-items: stretch;
+ justify-content: space-between;
`;
-const Item = styled.div`
+export const StatusBarItem = styled.div`
padding: 2px 10px;
// margin: auto;
// flex-grow: 0;
@@ -30,62 +31,72 @@ const InfoWrapper = styled.span`
props.theme.statusbar_font_green[5]};
`;
-export default function StatusBar() {
+const StatusbarContainer = styled.div`
+ display: flex;
+ // align-items: flex-end;
+ // display: flex;
+ // user-select: none;
+`;
+
+export default function StatusBar({ statusbarPortalRef }) {
const { name, connection } = useCurrentDatabase() || {};
const status = useDatabaseStatus(connection ? { conid: connection._id, database: name } : {});
const { displayName, server, user, engine } = connection || {};
const theme = useTheme();
return (
- {name && (
- -
- {name}
-
- )}
- {(displayName || server) && (
- -
- {displayName || server}
-
- )}
+
+ {name && (
+
+ {name}
+
+ )}
+ {(displayName || server) && (
+
+ {displayName || server}
+
+ )}
- {user && (
- -
- {user}
-
- )}
+ {user && (
+
+ {user}
+
+ )}
- {connection && status && (
- -
- {status.name == 'pending' && (
+ {connection && status && (
+
+ {status.name == 'pending' && (
+ <>
+ Loading
+ >
+ )}
+ {status.name == 'ok' && (
+ <>
+
+
+ {' '}
+ Connected
+ >
+ )}
+ {status.name == 'error' && (
+ <>
+
+
+ {' '}
+ Error
+ >
+ )}
+
+ )}
+ {!connection && (
+
<>
- Loading
+ Not connected
>
- )}
- {status.name == 'ok' && (
- <>
-
-
- {' '}
- Connected
- >
- )}
- {status.name == 'error' && (
- <>
-
-
- {' '}
- Error
- >
- )}
-
- )}
- {!connection && (
- -
- <>
- Not connected
- >
-
- )}
+
+ )}
+
+
);
}