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}