query messages

This commit is contained in:
Jan Prochazka
2020-04-10 14:53:06 +02:00
parent aa2eae2696
commit 784c34c5c9
4 changed files with 106 additions and 27 deletions

View File

@@ -1,29 +1,95 @@
import React from 'react'; import React from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import moment from 'moment';
const MainContainer = styled.div`
flex:1
display:flex
overflow-y: scroll
`;
const StyledTable = styled.table` const StyledTable = styled.table`
flex: 1; flex: 1;
border-spacing: 0;
border-collapse: collapse;
`; `;
export default function MessagesView({ items }) { const StyledHeader = styled.th`
text-align: left;
border-bottom: 2px solid #ddd;
padding: 5px;
`;
const StyledCell = styled.td`
border-top: 1px solid #ddd;
padding: 5px;
`;
const StyledRow = styled.tr`
color: ${(props) =>
// @ts-ignore
props.severity == 'error' ? 'red' : 'black'};
${(props) =>
// @ts-ignore
props.line != null &&
`
&:hover {
background-color: #ccc;
}
`}
`;
function formatDuration(duration) {
if (duration == 0) return '0';
if (duration < 1000) {
return `${Math.round(duration)} ms`;
}
if (duration < 10000) {
return `${Math.round(duration / 100) / 10} s`;
}
return `${Math.round(duration / 1000)} s`;
}
export default function MessagesView({ items, onMessageClick }) {
const handleClick = (row) => {
if (onMessageClick) onMessageClick(row);
};
const mainDiv = React.useRef(null);
React.useEffect(() => {
const element = mainDiv.current;
if (element) {
element.scrollTop = element.scrollHeight;
}
}, [items]);
const time0 = items[0] && new Date(items[0].time).getTime();
return ( return (
<MainContainer ref={mainDiv}>
<StyledTable> <StyledTable>
<tr> <tr>
<th>Number</th> <StyledHeader>Number</StyledHeader>
<th>Message</th> <StyledHeader>Message</StyledHeader>
<th>Time</th> <StyledHeader>Time</StyledHeader>
<th>Procedure</th> <StyledHeader>Delta</StyledHeader>
<th>Line</th> <StyledHeader>Procedure</StyledHeader>
<StyledHeader>Line</StyledHeader>
</tr> </tr>
{items.map((row, index) => ( {items.map((row, index) => (
<tr key={index}> // @ts-ignore
<td>{index + 1}</td> <StyledRow key={index} severity={row.severity} line={row.line} onClick={() => handleClick(row)}>
<td>{row.message}</td> <StyledCell>{index + 1}</StyledCell>
<td>{row.time}</td> <StyledCell>{row.message}</StyledCell>
<td>{row.procedure}</td> <StyledCell>{moment(row.time).format('HH:mm:ss')}</StyledCell>
<td>{row.line}</td> <StyledCell>{formatDuration(new Date(row.time).getTime() - time0)}</StyledCell>
</tr> <StyledCell>{row.procedure}</StyledCell>
<StyledCell>{row.line}</StyledCell>
</StyledRow>
))} ))}
</StyledTable> </StyledTable>
</MainContainer>
); );
} }

View File

@@ -2,7 +2,7 @@ import React from 'react';
import MessagesView from './MessagesView'; import MessagesView from './MessagesView';
import useSocket from '../utility/SocketProvider'; import useSocket from '../utility/SocketProvider';
export default function SessionMessagesView({ sessionId }) { export default function SessionMessagesView({ sessionId, onMessageClick }) {
const [messages, setMessages] = React.useState([]); const [messages, setMessages] = React.useState([]);
const socket = useSocket(); const socket = useSocket();
@@ -17,5 +17,5 @@ export default function SessionMessagesView({ sessionId }) {
} }
}, [sessionId, socket]); }, [sessionId, socket]);
return <MessagesView items={messages} />; return <MessagesView items={messages} onMessageClick={onMessageClick} />;
} }

View File

@@ -29,27 +29,30 @@ export default function SqlEditor({
onChange = undefined, onChange = undefined,
tabVisible = false, tabVisible = false,
onKeyDown = undefined, onKeyDown = undefined,
editorRef = undefined,
}) { }) {
const [containerRef, { height, width }] = useDimensions(); const [containerRef, { height, width }] = useDimensions();
const editorRef = React.useRef(null); const ownEditorRef = React.useRef(null);
const currentEditorRef = editorRef || ownEditorRef;
React.useEffect(() => { React.useEffect(() => {
if (tabVisible && editorRef.current && editorRef.current.editor) editorRef.current.editor.focus(); if (tabVisible && currentEditorRef.current && currentEditorRef.current.editor) currentEditorRef.current.editor.focus();
}, [tabVisible]); }, [tabVisible]);
React.useEffect(() => { React.useEffect(() => {
if (onKeyDown && editorRef.current) { if (onKeyDown && currentEditorRef.current) {
editorRef.current.editor.keyBinding.addKeyboardHandler(onKeyDown); currentEditorRef.current.editor.keyBinding.addKeyboardHandler(onKeyDown);
} }
return () => { return () => {
editorRef.current.editor.keyBinding.removeKeyboardHandler(onKeyDown); currentEditorRef.current.editor.keyBinding.removeKeyboardHandler(onKeyDown);
}; };
}, [onKeyDown]); }, [onKeyDown]);
return ( return (
<Wrapper ref={containerRef}> <Wrapper ref={containerRef}>
<AceEditor <AceEditor
ref={editorRef} ref={currentEditorRef}
mode={engineToMode[engine] || 'sql'} mode={engineToMode[engine] || 'sql'}
theme="github" theme="github"
onChange={onChange} onChange={onChange}

View File

@@ -46,6 +46,8 @@ export default function QueryTab({ tabid, conid, database, tabVisible, toolbarPo
}; };
}, []); }, []);
const editorRef = React.useRef(null);
useUpdateDatabaseForTab(tabVisible, conid, database); useUpdateDatabaseForTab(tabVisible, conid, database);
const connection = useConnectionInfo(conid); const connection = useConnectionInfo(conid);
@@ -73,6 +75,13 @@ export default function QueryTab({ tabid, conid, database, tabVisible, toolbarPo
const handleKeyDown = (e) => {}; const handleKeyDown = (e) => {};
const handleMesageClick = (message) => {
// console.log('EDITOR', editorRef.current.editor);
if (editorRef.current && editorRef.current.editor) {
editorRef.current.editor.gotoLine(message.line);
}
};
return ( return (
<> <>
<VerticalSplitter> <VerticalSplitter>
@@ -82,10 +91,11 @@ export default function QueryTab({ tabid, conid, database, tabVisible, toolbarPo
tabVisible={tabVisible} tabVisible={tabVisible}
engine={connection && connection.engine} engine={connection && connection.engine}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
editorRef={editorRef}
/> />
<ResultTabs sessionId={sessionId}> <ResultTabs sessionId={sessionId}>
<TabPage label="Messages" key="messages"> <TabPage label="Messages" key="messages">
<SessionMessagesView sessionId={sessionId} /> <SessionMessagesView sessionId={sessionId} onMessageClick={handleMesageClick} />
</TabPage> </TabPage>
</ResultTabs> </ResultTabs>
</VerticalSplitter> </VerticalSplitter>