This is an automated email from the ASF dual-hosted git repository.
bbovenzi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new cf8ca16ead Make datasets list/graph width adjustable (#37425)
cf8ca16ead is described below
commit cf8ca16ead1802fbdc919ab6816a1c4b2274496e
Author: Brent Bovenzi <[email protected]>
AuthorDate: Wed Feb 14 13:30:55 2024 -0500
Make datasets list/graph width adjustable (#37425)
---
airflow/www/static/js/datasets/List.tsx | 2 +-
.../www/static/js/datasets/{index.tsx => Main.tsx} | 97 ++++++++++++++--------
airflow/www/static/js/datasets/index.tsx | 52 +-----------
3 files changed, 67 insertions(+), 84 deletions(-)
diff --git a/airflow/www/static/js/datasets/List.tsx
b/airflow/www/static/js/datasets/List.tsx
index 6bbfd26497..a327936883 100644
--- a/airflow/www/static/js/datasets/List.tsx
+++ b/airflow/www/static/js/datasets/List.tsx
@@ -158,7 +158,7 @@ const DatasetsList = ({ onSelect }: Props) => {
to learn how to create a dataset.
</Text>
)}
- <Flex>
+ <Flex wrap="wrap">
<Text mr={2}>Filter datasets with updates in the past:</Text>
<ButtonGroup size="sm" isAttached variant="outline">
<Button
diff --git a/airflow/www/static/js/datasets/index.tsx
b/airflow/www/static/js/datasets/Main.tsx
similarity index 57%
copy from airflow/www/static/js/datasets/index.tsx
copy to airflow/www/static/js/datasets/Main.tsx
index 166b3f26ec..70f7629804 100644
--- a/airflow/www/static/js/datasets/index.tsx
+++ b/airflow/www/static/js/datasets/Main.tsx
@@ -17,40 +17,29 @@
* under the License.
*/
-/* global document */
-
-import React, { useRef } from "react";
-import { createRoot } from "react-dom/client";
-import createCache from "@emotion/cache";
+import React, { useCallback, useEffect, useRef } from "react";
import { useSearchParams } from "react-router-dom";
import { Flex, Box } from "@chakra-ui/react";
-import reactFlowStyle from "reactflow/dist/style.css";
-
-import App from "src/App";
import { useOffsetTop } from "src/utils";
import DatasetsList from "./List";
import DatasetDetails from "./Details";
import Graph from "./Graph";
-// create shadowRoot
-const root = document.querySelector("#root");
-const shadowRoot = root?.attachShadow({ mode: "open" });
-const cache = createCache({
- container: shadowRoot,
- key: "c",
-});
-const mainElement = document.getElementById("react-container");
-
const DATASET_URI = "uri";
+const minPanelWidth = 300;
const Datasets = () => {
const [searchParams, setSearchParams] = useSearchParams();
const contentRef = useRef<HTMLDivElement>(null);
const offsetTop = useOffsetTop(contentRef);
+ const listRef = useRef<HTMLDivElement>(null);
+ const graphRef = useRef<HTMLDivElement>(null);
// 60px for footer height
const height = `calc(100vh - ${offsetTop + 60}px)`;
+ const resizeRef = useRef<HTMLDivElement>(null);
+
const onBack = () => {
searchParams.delete(DATASET_URI);
setSearchParams(searchParams);
@@ -61,6 +50,41 @@ const Datasets = () => {
setSearchParams(searchParams);
};
+ const resize = useCallback(
+ (e: MouseEvent) => {
+ const listEl = listRef.current;
+ if (
+ listEl &&
+ e.x > minPanelWidth &&
+ e.x < window.innerWidth - minPanelWidth
+ ) {
+ const width = `${e.x}px`;
+ listEl.style.width = width;
+ }
+ },
+ [listRef]
+ );
+
+ useEffect(() => {
+ const resizeEl = resizeRef.current;
+ if (resizeEl) {
+ resizeEl.addEventListener("mousedown", (e) => {
+ e.preventDefault();
+ document.addEventListener("mousemove", resize);
+ });
+
+ document.addEventListener("mouseup", () => {
+ document.removeEventListener("mousemove", resize);
+ });
+
+ return () => {
+ resizeEl?.removeEventListener("mousedown", resize);
+ document.removeEventListener("mouseup", resize);
+ };
+ }
+ return () => {};
+ }, [resize]);
+
const datasetUri = decodeURIComponent(searchParams.get(DATASET_URI) || "");
return (
@@ -69,31 +93,38 @@ const Datasets = () => {
justifyContent="space-between"
ref={contentRef}
>
- <Box minWidth="450px" height={height} overflowY="auto">
+ <Box
+ minWidth={minPanelWidth}
+ height={height}
+ overflowY="auto"
+ ref={listRef}
+ mr={3}
+ >
{datasetUri ? (
<DatasetDetails uri={datasetUri} onBack={onBack} />
) : (
<DatasetsList onSelect={onSelect} />
)}
</Box>
- <Box flex={1} height={height} borderColor="gray.200" borderWidth={1}>
+ <Box
+ width={2}
+ cursor="ew-resize"
+ bg="gray.200"
+ ref={resizeRef}
+ zIndex={1}
+ height={height}
+ />
+ <Box
+ ref={graphRef}
+ flex={1}
+ height={height}
+ borderColor="gray.200"
+ borderWidth={1}
+ >
<Graph selectedUri={datasetUri} onSelect={onSelect} />
</Box>
</Flex>
);
};
-if (mainElement) {
- shadowRoot?.appendChild(mainElement);
- const styleTag = document.createElement("style");
- const style = reactFlowStyle.toString();
- styleTag.innerHTML = style;
- shadowRoot?.appendChild(styleTag);
-
- const reactRoot = createRoot(mainElement);
- reactRoot.render(
- <App cache={cache}>
- <Datasets />
- </App>
- );
-}
+export default Datasets;
diff --git a/airflow/www/static/js/datasets/index.tsx
b/airflow/www/static/js/datasets/index.tsx
index 166b3f26ec..63f33d9178 100644
--- a/airflow/www/static/js/datasets/index.tsx
+++ b/airflow/www/static/js/datasets/index.tsx
@@ -19,19 +19,13 @@
/* global document */
-import React, { useRef } from "react";
+import React from "react";
import { createRoot } from "react-dom/client";
import createCache from "@emotion/cache";
-import { useSearchParams } from "react-router-dom";
-import { Flex, Box } from "@chakra-ui/react";
import reactFlowStyle from "reactflow/dist/style.css";
import App from "src/App";
-import { useOffsetTop } from "src/utils";
-
-import DatasetsList from "./List";
-import DatasetDetails from "./Details";
-import Graph from "./Graph";
+import Datasets from "./Main";
// create shadowRoot
const root = document.querySelector("#root");
@@ -41,48 +35,6 @@ const cache = createCache({
key: "c",
});
const mainElement = document.getElementById("react-container");
-
-const DATASET_URI = "uri";
-
-const Datasets = () => {
- const [searchParams, setSearchParams] = useSearchParams();
- const contentRef = useRef<HTMLDivElement>(null);
- const offsetTop = useOffsetTop(contentRef);
- // 60px for footer height
- const height = `calc(100vh - ${offsetTop + 60}px)`;
-
- const onBack = () => {
- searchParams.delete(DATASET_URI);
- setSearchParams(searchParams);
- };
-
- const onSelect = (datasetUri: string) => {
- searchParams.set(DATASET_URI, encodeURIComponent(datasetUri));
- setSearchParams(searchParams);
- };
-
- const datasetUri = decodeURIComponent(searchParams.get(DATASET_URI) || "");
-
- return (
- <Flex
- alignItems="flex-start"
- justifyContent="space-between"
- ref={contentRef}
- >
- <Box minWidth="450px" height={height} overflowY="auto">
- {datasetUri ? (
- <DatasetDetails uri={datasetUri} onBack={onBack} />
- ) : (
- <DatasetsList onSelect={onSelect} />
- )}
- </Box>
- <Box flex={1} height={height} borderColor="gray.200" borderWidth={1}>
- <Graph selectedUri={datasetUri} onSelect={onSelect} />
- </Box>
- </Flex>
- );
-};
-
if (mainElement) {
shadowRoot?.appendChild(mainElement);
const styleTag = document.createElement("style");