diff --git a/packages/web/src/Screen.js b/packages/web/src/Screen.js index 7b574e3c2..22894e366 100644 --- a/packages/web/src/Screen.js +++ b/packages/web/src/Screen.js @@ -9,6 +9,7 @@ import WidgetIconPanel from './widgets/WidgetIconPanel'; import { useCurrentWidget } from './utility/globalState'; import WidgetContainer from './widgets/WidgetContainer'; import ToolBar from './widgets/Toolbar'; +import StatusBar from './widgets/StatusBar'; const BodyDiv = styled.div` position: fixed; @@ -57,7 +58,7 @@ const TabsPanelContainer = styled.div` background-color: ${theme.tabsPanel.background}; `; -const StausBar = styled.div` +const StausBarContainer = styled.div` position: fixed; height: ${theme.statusBar.height}px; left: 0; @@ -89,7 +90,9 @@ export default function Screen() { - + + + ); } diff --git a/packages/web/src/appobj/connectionAppObject.js b/packages/web/src/appobj/connectionAppObject.js index e7b1255c6..82a4f89b6 100644 --- a/packages/web/src/appobj/connectionAppObject.js +++ b/packages/web/src/appobj/connectionAppObject.js @@ -1,25 +1,11 @@ import React from 'react'; -import { MicrosoftIcon, SqliteIcon, PostgreSqlIcon, MySqlIcon, ServerIcon } from '../icons'; +import { getEngineIcon } from '../icons'; import { DropDownMenuItem } from '../modals/DropDownMenu'; import showModal from '../modals/showModal'; import ConnectionModal from '../modals/ConnectionModal'; import axios from '../utility/axios'; import { filterName } from '@dbgate/datalib'; -function getIcon(engine) { - switch (engine) { - case 'mssql': - return MicrosoftIcon; - case 'sqlite': - return SqliteIcon; - case 'postgres': - return PostgreSqlIcon; - case 'mysql': - return MySqlIcon; - } - return ServerIcon; -} - function Menu({ data, makeAppObj }) { const handleEdit = () => { showModal(modalState => ); @@ -38,7 +24,7 @@ function Menu({ data, makeAppObj }) { export default function connectionAppObject({ _id, server, displayName, engine }) { const title = displayName || server; const key = _id; - const Icon = getIcon(engine); + const Icon = getEngineIcon(engine); const matcher = filter => filterName(filter, displayName, server); return { title, key, Icon, Menu, matcher }; diff --git a/packages/web/src/datagrid/DataGridContextMenu.js b/packages/web/src/datagrid/DataGridContextMenu.js index 9fca5b523..9939e2761 100644 --- a/packages/web/src/datagrid/DataGridContextMenu.js +++ b/packages/web/src/datagrid/DataGridContextMenu.js @@ -1,5 +1,5 @@ import React from 'react'; -import { DropDownMenuItem } from '../modals/DropDownMenu'; +import { DropDownMenuItem, DropDownMenuDivider } from '../modals/DropDownMenu'; export default function DataGridContextMenu({ copy, revertRowChanges, deleteSelectedRows, insertNewRow, reload }) { return ( @@ -7,6 +7,7 @@ export default function DataGridContextMenu({ copy, revertRowChanges, deleteSele Reload + Copy diff --git a/packages/web/src/icons.js b/packages/web/src/icons.js index 06e828f14..6f089aac0 100644 --- a/packages/web/src/icons.js +++ b/packages/web/src/icons.js @@ -102,3 +102,17 @@ export const HourGlassIcon = props => ; export const SpinnerIcon = props => ; + +export function getEngineIcon(engine) { + switch (engine) { + case 'mssql': + return MicrosoftIcon; + case 'sqlite': + return SqliteIcon; + case 'postgres': + return PostgreSqlIcon; + case 'mysql': + return MySqlIcon; + } + return ServerIcon; +} diff --git a/packages/web/src/modals/ConfirmSqlModal.js b/packages/web/src/modals/ConfirmSqlModal.js index 7f9dfe1a1..195ca01c6 100644 --- a/packages/web/src/modals/ConfirmSqlModal.js +++ b/packages/web/src/modals/ConfirmSqlModal.js @@ -19,7 +19,7 @@ export default function ConfirmSqlModal({ modalState, sql, engine, onConfirm })

Save changes

- + diff --git a/packages/web/src/query/useNewQuery.js b/packages/web/src/query/useNewQuery.js new file mode 100644 index 000000000..f75840465 --- /dev/null +++ b/packages/web/src/query/useNewQuery.js @@ -0,0 +1,19 @@ +import { useSetOpenedTabs } from '../utility/globalState'; +import { openNewTab } from '../utility/common'; + +export default function useNewQuery() { + const setOpenedTabs = useSetOpenedTabs(); + + return () => + openNewTab(setOpenedTabs, { + title: 'Query', + icon: 'sql.svg', + tabComponent: 'QueryTab', + // props: { + // schemaName, + // pureName, + // conid, + // database, + // }, + }); +} diff --git a/packages/web/src/sqleditor/SqlEditor.js b/packages/web/src/sqleditor/SqlEditor.js index 24a62abcf..9585caa23 100644 --- a/packages/web/src/sqleditor/SqlEditor.js +++ b/packages/web/src/sqleditor/SqlEditor.js @@ -22,19 +22,31 @@ const engineToMode = { postgre: 'pgsql', }; -export default function SqlEditor({ value, engine }) { +export default function SqlEditor({ + value = undefined, + engine = undefined, + readOnly = false, + onChange = undefined, + tabVisible = false, +}) { const [containerRef, { height, width }] = useDimensions(); + const editorRef = React.useRef(null); + React.useEffect(() => { + console.log('editorRef.current', editorRef.current); + if (tabVisible) editorRef.current.editor.focus(); + }, [tabVisible]); return ( { + setQueryText(text); + }; + + return ; +} diff --git a/packages/web/src/tabs/TableCreateScriptTab.js b/packages/web/src/tabs/TableCreateScriptTab.js index 8a6b173fc..1935a18a5 100644 --- a/packages/web/src/tabs/TableCreateScriptTab.js +++ b/packages/web/src/tabs/TableCreateScriptTab.js @@ -14,5 +14,5 @@ export default function TableCreateScriptTab({ conid, database, schemaName, pure const dmp = driver.createDumper(); if (tableInfo) dmp.createTable(tableInfo); - return ; + return ; } diff --git a/packages/web/src/tabs/TableDataTab.js b/packages/web/src/tabs/TableDataTab.js index b10b2164d..859211ec7 100644 --- a/packages/web/src/tabs/TableDataTab.js +++ b/packages/web/src/tabs/TableDataTab.js @@ -10,6 +10,7 @@ import engines from '@dbgate/engines'; import getTableInfo from '../utility/getTableInfo'; import useUndoReducer from '../utility/useUndoReducer'; import usePropsCompare from '../utility/usePropsCompare'; +import { useUpdateDatabaseForTab } from '../utility/globalState'; export default function TableDataTab({ conid, database, schemaName, pureName, tabVisible, toolbarPortalRef }) { const tableInfo = useTableInfo({ conid, database, schemaName, pureName }); @@ -17,8 +18,7 @@ export default function TableDataTab({ conid, database, schemaName, pureName, ta const [cache, setCache] = React.useState(createGridCache()); const [changeSetState, dispatchChangeSet] = useUndoReducer(createChangeSet()); - // console.log('changeSet', changeSet); - + useUpdateDatabaseForTab(tabVisible, conid, database); const connection = useConnectionInfo(conid); // usePropsCompare({ tableInfo, connection, config, cache }); diff --git a/packages/web/src/tabs/index.js b/packages/web/src/tabs/index.js index cf00bd3cb..a7a2f88dd 100644 --- a/packages/web/src/tabs/index.js +++ b/packages/web/src/tabs/index.js @@ -1,9 +1,11 @@ import TableDataTab from './TableDataTab'; import TableStructureTab from './TableStructureTab'; -import TableCreateScriptTab from './TableCreateScriptTab' +import TableCreateScriptTab from './TableCreateScriptTab'; +import QueryTab from './QueryTab'; export default { TableDataTab, TableStructureTab, TableCreateScriptTab, + QueryTab, }; diff --git a/packages/web/src/utility/globalState.js b/packages/web/src/utility/globalState.js index f93752f02..df843e386 100644 --- a/packages/web/src/utility/globalState.js +++ b/packages/web/src/utility/globalState.js @@ -1,5 +1,7 @@ +import _ from 'lodash'; import React from 'react'; import useStorage from './useStorage'; +import useConnectionInfo from './useConnectionInfo'; function createGlobalState(defaultValue) { const Context = React.createContext(null); @@ -42,8 +44,30 @@ function createStorageState(storageKey, defaultValue) { const [CurrentWidgetProvider, useCurrentWidget, useSetCurrentWidget] = createGlobalState('database'); export { CurrentWidgetProvider, useCurrentWidget, useSetCurrentWidget }; -const [CurrentDatabaseProvider, useCurrentDatabase, useSetCurrentDatabase] = createGlobalState(null); +const [CurrentDatabaseProvider, useCurrentDatabase, useSetCurrentDatabaseCore] = createGlobalState(null); + +function useSetCurrentDatabase() { + const setDb = useSetCurrentDatabaseCore(); + const db = useCurrentDatabase(); + return value => { + if (_.get(db, 'name') !== _.get(value, 'name') || _.get(db, 'connection._id') != _.get(value, 'connection._id')) { + setDb(value); + } + }; +} + export { CurrentDatabaseProvider, useCurrentDatabase, useSetCurrentDatabase }; const [OpenedTabsProvider, useOpenedTabs, useSetOpenedTabs] = createStorageState('openedTabs', []); export { OpenedTabsProvider, useOpenedTabs, useSetOpenedTabs }; + +export function useUpdateDatabaseForTab(tabVisible, conid, database) { + const connection = useConnectionInfo(conid); + const setDb = useSetCurrentDatabase(); + if (tabVisible && connection) { + setDb({ + name: database, + connection, + }); + } +} diff --git a/packages/web/src/widgets/StatusBar.js b/packages/web/src/widgets/StatusBar.js new file mode 100644 index 000000000..87f2cb9ef --- /dev/null +++ b/packages/web/src/widgets/StatusBar.js @@ -0,0 +1,43 @@ +import React from 'react'; +import styled from 'styled-components'; + +import { getEngineIcon } from '../icons'; +import { useCurrentDatabase } from '../utility/globalState'; + +const Container = styled.div` + display: flex; + color: white; + align-items: stretch; +`; + +const Item = styled.div` + padding: 2px 10px; + // margin: auto; + // flex-grow: 0; +`; + +export default function StatusBar() { + const { name, connection } = useCurrentDatabase() || {}; + const { displayName, server, user, engine } = connection || {}; + const EngineIcon = getEngineIcon(engine); + return ( + + {name && ( + + {name} + + )} + {(displayName || server) && ( + + {displayName || server} + + )} + + {user && ( + + {user} + + )} + + ); +} diff --git a/packages/web/src/widgets/Toolbar.js b/packages/web/src/widgets/Toolbar.js index d2633f5d7..db4f13f78 100644 --- a/packages/web/src/widgets/Toolbar.js +++ b/packages/web/src/widgets/Toolbar.js @@ -3,6 +3,7 @@ import useModalState from '../modals/useModalState'; import ConnectionModal from '../modals/ConnectionModal'; import styled from 'styled-components'; import ToolbarButton from './ToolbarButton'; +import useNewQuery from '../query/useNewQuery'; const ToolbarContainer = styled.div` display: flex; @@ -11,11 +12,13 @@ const ToolbarContainer = styled.div` export default function ToolBar({ toolbarPortalRef }) { const modalState = useModalState(); + const newQuery = useNewQuery(); return ( Add connection + Query );