diff --git a/packages/web/src/widgets/ArchiveWidget.js b/packages/web/src/widgets/ArchiveWidget.js index 5c647cb15..c628a37a7 100644 --- a/packages/web/src/widgets/ArchiveWidget.js +++ b/packages/web/src/widgets/ArchiveWidget.js @@ -12,6 +12,7 @@ import { WidgetsOuterContainer, WidgetTitle, } from './WidgetStyles'; +import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar'; import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject'; import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders'; import archiveFolderAppObject from '../appobj/archiveFolderAppObject'; @@ -22,7 +23,6 @@ import axios from '../utility/axios'; function ArchiveFolderList() { const folders = useArchiveFolders(); - const inputRef = React.useRef(null); const [filter, setFilter] = React.useState(''); const setArchive = useSetCurrentArchive(); @@ -33,9 +33,8 @@ function ArchiveFolderList() { return ( <> - Archive folder - + Refresh @@ -53,7 +52,6 @@ function ArchiveFolderList() { function ArchiveFilesList() { const folder = useCurrentArchive(); const files = useArchiveFiles({ folder }); - const inputRef = React.useRef(null); const [filter, setFilter] = React.useState(''); const handleRefreshFiles = () => { axios.post('archive/refresh-files', { folder }); @@ -61,9 +59,8 @@ function ArchiveFilesList() { return ( <> - Archive files - + Refresh @@ -82,13 +79,13 @@ function ArchiveFilesList() { export default function ArchiveWidget() { return ( - - + + - - + + - - + + ); } diff --git a/packages/web/src/widgets/DatabaseWidget.js b/packages/web/src/widgets/DatabaseWidget.js index 1919acba8..cebef0811 100644 --- a/packages/web/src/widgets/DatabaseWidget.js +++ b/packages/web/src/widgets/DatabaseWidget.js @@ -26,6 +26,7 @@ import axios from '../utility/axios'; import LoadingInfo from './LoadingInfo'; import SearchInput from './SearchInput'; import ErrorInfo from './ErrorInfo'; +import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar'; function SubDatabaseList({ data }) { const setDb = useSetCurrentDatabase(); @@ -60,14 +61,12 @@ function ConnectionList() { axios.post('server-connections/refresh', { conid }); } }; - const inputRef = React.useRef(null); const [filter, setFilter] = React.useState(''); return ( <> - Connections - + Refresh @@ -103,7 +102,6 @@ function SqlObjectList({ conid, database }) { const inputRef = React.useRef(null); return ( <> - Tables, views, functions Refresh @@ -128,12 +126,7 @@ function SqlObjectListWrapper() { const db = useCurrentDatabase(); if (!db) { - return ( - <> - Tables, views, functions - - - ); + return ; } const { name, connection } = db; @@ -144,13 +137,13 @@ function SqlObjectListWrapper() { export default function DatabaseWidget() { return ( - - + + - - + + - - + + ); } diff --git a/packages/web/src/widgets/FilesWidget.js b/packages/web/src/widgets/FilesWidget.js index 05d4fcddf..84277755c 100644 --- a/packages/web/src/widgets/FilesWidget.js +++ b/packages/web/src/widgets/FilesWidget.js @@ -13,13 +13,13 @@ import { WidgetTitle, } from './WidgetStyles'; import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject'; +import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar'; function ClosedTabsList() { const tabs = useOpenedTabs(); return ( <> - Recently closed tabs - Saved SQL files @@ -48,13 +47,13 @@ function SavedSqlFilesList() { export default function FilesWidget() { return ( - - + + - - + + - - + + ); } diff --git a/packages/web/src/widgets/Splitter.js b/packages/web/src/widgets/Splitter.js index cbcf5ef9b..81102979e 100644 --- a/packages/web/src/widgets/Splitter.js +++ b/packages/web/src/widgets/Splitter.js @@ -14,6 +14,7 @@ const SplitterMainBase = styled.div` bottom: 0; `; +// @ts-ignore const VerticalMainContainer = styled(SplitterMainBase)` flex: 1; display: flex; diff --git a/packages/web/src/widgets/WidgetColumnBar.js b/packages/web/src/widgets/WidgetColumnBar.js new file mode 100644 index 000000000..9d570ba4f --- /dev/null +++ b/packages/web/src/widgets/WidgetColumnBar.js @@ -0,0 +1,72 @@ +import React from 'react'; +import _ from 'lodash'; +import { + SearchBoxWrapper, + WidgetsInnerContainer, + WidgetsMainContainer, + WidgetsOuterContainer, + WidgetTitle, +} from './WidgetStyles'; +import { VerticalSplitHandle, useSplitterDrag } from './Splitter'; +import useDimensions from '../utility/useDimensions'; + +export function WidgetColumnBarItem({ title, children, name, height = undefined }) { + return <>; +} + +function WidgetContainer({ widget, visible, splitterVisible, parentHeight, initialSize = undefined }) { + const [size, setSize] = React.useState(null); + + const handleResizeDown = useSplitterDrag('clientY', (diff) => setSize((v) => v + diff)); + + React.useEffect(() => { + if (_.isString(initialSize) && initialSize.endsWith('px')) setSize(parseInt(initialSize.slice(0, -2))); + else if (_.isString(initialSize) && initialSize.endsWith('%')) + setSize((parentHeight * parseFloat(initialSize.slice(0, -1))) / 100); + else setSize(parentHeight / 3); + }, [parentHeight]); + + if (!visible) return null; + + return ( + <> + + {widget.props.children} + + {splitterVisible && } + + ); +} + +export default function WidgetColumnBar({ children }) { + const childArray = _.isArray(children) ? children : [children]; + const [refNode, dimensions] = useDimensions(); + const [collapsedWidgets, setCollapsedWidgets] = React.useState(() => + childArray.filter((x) => x.props.collapsed).map((x) => x.props.key) + ); + const toggleCollapsed = (name) => { + if (collapsedWidgets.includes(name)) setCollapsedWidgets(collapsedWidgets.filter((x) => x != name)); + else setCollapsedWidgets([...collapsedWidgets, name]); + }; + + return ( + + {childArray.map((widget, index) => { + if (!widget) return null; + return ( + <> + toggleCollapsed(widget.props.name)}>{widget.props.title} + !collapsedWidgets.includes(x.props.name))} + /> + + ); + })} + + ); +} diff --git a/packages/web/src/widgets/WidgetStyles.js b/packages/web/src/widgets/WidgetStyles.js index bcd33989d..77c4c9607 100644 --- a/packages/web/src/widgets/WidgetStyles.js +++ b/packages/web/src/widgets/WidgetStyles.js @@ -19,7 +19,6 @@ export const WidgetsMainContainer = styled.div` `; const StyledWidgetsOuterContainer = styled.div` - flex: 1 1 0; overflow: hidden; width: ${(props) => props.leftPanelWidth}px; position: relative; @@ -27,9 +26,20 @@ const StyledWidgetsOuterContainer = styled.div` display: flex; `; -export function WidgetsOuterContainer({ children }) { +export function WidgetsOuterContainer({ children, style = undefined, refNode = undefined }) { const leftPanelWidth = useLeftPanelWidth(); - return {children}; + return ( + + {children} + + ); } export const StyledWidgetsInnerContainer = styled.div` @@ -53,14 +63,16 @@ const StyledWidgetTitle = styled.div` font-weight: bold; text-transform: uppercase; background-color: gray; + border: 1px solid #aaa; // background-color: #CEC; `; -export function WidgetTitle({ children, inputRef = undefined }) { +export function WidgetTitle({ children, inputRef = undefined, onClick = undefined }) { return ( { if (inputRef && inputRef.current) inputRef.current.focus(); + if (onClick) onClick(); }} > {children}