mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-23 01:06:01 +00:00
query - basic print workflow - messages on client
This commit is contained in:
24
packages/web/src/query/MessagesView.js
Normal file
24
packages/web/src/query/MessagesView.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function MessagesView({ items }) {
|
||||
return (
|
||||
<table>
|
||||
<tr>
|
||||
<th>Number</th>
|
||||
<th>Message</th>
|
||||
<th>Time</th>
|
||||
<th>Procedure</th>
|
||||
<th>Line</th>
|
||||
</tr>
|
||||
{items.map((row, index) => (
|
||||
<tr key={index}>
|
||||
<td>{index + 1}</td>
|
||||
<td>{row.message}</td>
|
||||
<td>{row.time}</td>
|
||||
<td>{row.procedure}</td>
|
||||
<td>{row.line}</td>
|
||||
</tr>
|
||||
))}
|
||||
</table>
|
||||
);
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
import React from 'react'
|
||||
import ToolbarButton from '../widgets/ToolbarButton'
|
||||
import React from 'react';
|
||||
import ToolbarButton from '../widgets/ToolbarButton';
|
||||
|
||||
export default function QueryToolbar() {
|
||||
return <>
|
||||
<ToolbarButton onClick={()=>{}}>Execute</ToolbarButton>
|
||||
export default function QueryToolbar({ execute,isDatabaseDefined }) {
|
||||
return (
|
||||
<>
|
||||
<ToolbarButton disabled={!isDatabaseDefined} onClick={execute}>Execute</ToolbarButton>
|
||||
</>
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
21
packages/web/src/query/SessionMessagesView.js
Normal file
21
packages/web/src/query/SessionMessagesView.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
import MessagesView from './MessagesView';
|
||||
import useSocket from '../utility/SocketProvider';
|
||||
|
||||
export default function SessionMessagesView({ sessionId }) {
|
||||
const [messages, setMessages] = React.useState([]);
|
||||
const socket = useSocket();
|
||||
|
||||
const handleInfo = React.useCallback((info) => setMessages((items) => [...items, info]), []);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (sessionId && socket) {
|
||||
socket.on(`session-info-${sessionId}`, handleInfo);
|
||||
return () => {
|
||||
socket.off(`session-info-${sessionId}`, handleInfo);
|
||||
};
|
||||
}
|
||||
}, [sessionId, socket]);
|
||||
|
||||
return <MessagesView items={messages} />;
|
||||
}
|
||||
@@ -1,17 +1,30 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import _ from 'lodash';
|
||||
import axios from '../utility/axios';
|
||||
import engines from '@dbgate/engines';
|
||||
import useTableInfo from '../utility/useTableInfo';
|
||||
import useConnectionInfo from '../utility/useConnectionInfo';
|
||||
import SqlEditor from '../sqleditor/SqlEditor';
|
||||
import { useUpdateDatabaseForTab } from '../utility/globalState';
|
||||
import QueryToolbar from '../query/QueryToolbar';
|
||||
import styled from 'styled-components';
|
||||
import SessionMessagesView from '../query/SessionMessagesView';
|
||||
|
||||
const MainContainer = styled.div``;
|
||||
|
||||
const EditorContainer = styled.div`
|
||||
height: 600px;
|
||||
position: relative;
|
||||
`;
|
||||
|
||||
const MessagesContainer = styled.div``;
|
||||
|
||||
export default function QueryTab({ tabid, conid, database, tabVisible, toolbarPortalRef }) {
|
||||
const localStorageKey = `sql_${tabid}`;
|
||||
const [queryText, setQueryText] = React.useState(() => localStorage.getItem(localStorageKey) || '');
|
||||
const queryTextRef = React.useRef(queryText);
|
||||
const [sessionId, setSessionId] = React.useState(null);
|
||||
|
||||
const saveToStorage = React.useCallback(() => localStorage.setItem(localStorageKey, queryTextRef.current), [
|
||||
localStorageKey,
|
||||
@@ -22,26 +35,57 @@ export default function QueryTab({ tabid, conid, database, tabVisible, toolbarPo
|
||||
React.useEffect(() => {
|
||||
window.addEventListener('beforeunload', saveToStorage);
|
||||
return () => {
|
||||
saveToStorage();
|
||||
window.removeEventListener('beforeunload', saveToStorage);
|
||||
};
|
||||
}, []);
|
||||
|
||||
useUpdateDatabaseForTab(tabVisible, conid, database);
|
||||
const connection = useConnectionInfo(conid);
|
||||
|
||||
const handleChange = text => {
|
||||
const handleChange = (text) => {
|
||||
if (text != null) queryTextRef.current = text;
|
||||
setQueryText(text);
|
||||
saveToStorageDebounced();
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<SqlEditor value={queryText} onChange={handleChange} tabVisible={tabVisible} />
|
||||
const handleExecute = async () => {
|
||||
let sesid = sessionId;
|
||||
if (!sesid) {
|
||||
const resp = await axios.post('sessions/create', {
|
||||
conid,
|
||||
database,
|
||||
});
|
||||
sesid = resp.data.sesid;
|
||||
setSessionId(sesid);
|
||||
}
|
||||
const resp2 = await axios.post('sessions/execute-query', {
|
||||
sesid,
|
||||
sql: queryText,
|
||||
});
|
||||
};
|
||||
|
||||
{toolbarPortalRef &&
|
||||
toolbarPortalRef.current &&
|
||||
tabVisible &&
|
||||
ReactDOM.createPortal(<QueryToolbar />, toolbarPortalRef.current)}
|
||||
</>
|
||||
return (
|
||||
<MainContainer>
|
||||
<EditorContainer>
|
||||
<SqlEditor
|
||||
value={queryText}
|
||||
onChange={handleChange}
|
||||
tabVisible={tabVisible}
|
||||
engine={connection && connection.engine}
|
||||
/>
|
||||
|
||||
{toolbarPortalRef &&
|
||||
toolbarPortalRef.current &&
|
||||
tabVisible &&
|
||||
ReactDOM.createPortal(
|
||||
<QueryToolbar isDatabaseDefined={conid && database} execute={handleExecute} />,
|
||||
toolbarPortalRef.current
|
||||
)}
|
||||
</EditorContainer>
|
||||
<MessagesContainer>
|
||||
<SessionMessagesView sessionId={sessionId} />
|
||||
</MessagesContainer>
|
||||
</MainContainer>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ export default function useFetch({
|
||||
const [loadCounter, setLoadCounter] = React.useState(0);
|
||||
const socket = useSocket();
|
||||
|
||||
const handleReload = () => {
|
||||
setLoadCounter(loadCounter + 1);
|
||||
};
|
||||
const handleReload = React.useCallback(() => {
|
||||
setLoadCounter((counter) => counter + 1);
|
||||
}, []);
|
||||
|
||||
const indicators = [url, stableStringify(data), stableStringify(params), loadCounter];
|
||||
|
||||
@@ -32,15 +32,29 @@ export default function useFetch({
|
||||
});
|
||||
setValue([resp.data, loadedIndicators]);
|
||||
}
|
||||
|
||||
// React.useEffect(() => {
|
||||
// loadValue(indicators);
|
||||
// if (reloadTrigger && socket) {
|
||||
// socket.on(reloadTrigger, handleReload);
|
||||
// return () => {
|
||||
// socket.off(reloadTrigger, handleReload);
|
||||
// };
|
||||
// }
|
||||
// }, [...indicators, socket]);
|
||||
|
||||
React.useEffect(() => {
|
||||
loadValue(indicators);
|
||||
}, [...indicators]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (reloadTrigger && socket) {
|
||||
socket.on(reloadTrigger, handleReload);
|
||||
return () => {
|
||||
socket.off(reloadTrigger, handleReload);
|
||||
};
|
||||
}
|
||||
}, [...indicators, socket]);
|
||||
}, [socket, reloadTrigger]);
|
||||
|
||||
const [returnValue, loadedIndicators] = value;
|
||||
if (_.isEqual(indicators, loadedIndicators)) return returnValue;
|
||||
|
||||
Reference in New Issue
Block a user