From 51ba9d3b5a1d70c775ac1348dd01a1039fc081a3 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 28 Jan 2021 12:49:00 +0100 Subject: [PATCH] statusbar - show query execution duration --- packages/web/src/Screen.js | 5 +- packages/web/src/TabContent.js | 13 ++- packages/web/src/tabs/QueryTab.js | 21 ++++- packages/web/src/utility/useTimerLabel.js | 37 ++++++++ packages/web/src/widgets/StatusBar.js | 105 ++++++++++++---------- 5 files changed, 128 insertions(+), 53 deletions(-) create mode 100644 packages/web/src/utility/useTimerLabel.js 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 - - - )} + + )} + + ); }