diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/AdminButton.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/AdminButton.tsx index ddc01d9db28ee..427d994c55aa7 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/AdminButton.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/AdminButton.tsx @@ -79,7 +79,7 @@ export const AdminButton = ({ return ( - } title={translate("nav.admin")} /> + {menuItems} diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/BrowseButton.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/BrowseButton.tsx index 170f89a94f5fb..986fa973bbc19 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/BrowseButton.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/BrowseButton.tsx @@ -70,7 +70,7 @@ export const BrowseButton = ({ return ( - } title={translate("nav.browse")} /> + {menuItems} diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/DocsButton.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/DocsButton.tsx index d73b323b3e122..3af4e7f93a636 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/DocsButton.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/DocsButton.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { Link } from "@chakra-ui/react"; +import { Box, Icon, Link } from "@chakra-ui/react"; import { useTranslation } from "react-i18next"; import { FiBookOpen, FiExternalLink } from "react-icons/fi"; @@ -61,7 +61,7 @@ export const DocsButton = ({ return ( - } title={translate("nav.docs")} /> + {links @@ -73,17 +73,18 @@ export const DocsButton = ({ href={link.href} rel="noopener noreferrer" target="_blank" + textDecoration="none" > - {translate(`docs.${link.key}`)} - + {translate(`docs.${link.key}`)} + ))} {version === undefined ? undefined : ( - {version} - + {version} + )} diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/Nav.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/Nav.tsx index 39a1afccf4df6..878f8d42a1d7e 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/Nav.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/Nav.tsx @@ -19,7 +19,7 @@ import { Box, Flex, VStack } from "@chakra-ui/react"; import { useTranslation } from "react-i18next"; import { FiDatabase, FiHome } from "react-icons/fi"; -import { NavLink } from "react-router-dom"; +import { Link } from "react-router-dom"; import { useAuthLinksServiceGetAuthMenus, @@ -140,14 +140,14 @@ export const Nav = () => { height="100%" justifyContent="space-between" position="fixed" - py={3} + py={1} top={0} - width={20} + width={16} zIndex={2} > - - - + + + { transition: "transform 0.8s ease-in-out", }, }} - height="35px" - width="35px" + boxSize={8} /> - + - } title={translate("nav.home")} to="/" /> + } + icon={DagIcon} title={translate("nav.dags")} to="dags" /> } + icon={FiDatabase} title={translate("nav.assets")} to="assets" /> @@ -184,7 +183,7 @@ export const Nav = () => { - + >; readonly isExternal?: boolean; - readonly title?: string; + readonly title: string; readonly to?: string; } & ButtonProps; -export const NavButton = ({ icon, isExternal = false, title, to, ...rest }: NavButtonProps) => - to === undefined ? ( - - ) : isExternal ? ( - - - - ) : ( - - {({ isActive }: { readonly isActive: boolean }) => ( - - )} - + + ); + } + + return ( + ); +}; diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/PluginMenus.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/PluginMenus.tsx index 2dfbf58ac3d4e..c872780489097 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/PluginMenus.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/PluginMenus.tsx @@ -53,7 +53,7 @@ export const PluginMenus = ({ navItems }: { readonly navItems: Array= 2 ? ( - } title={translate("nav.plugins")} /> + {buttons.map((navItem) => ( diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/SecurityButton.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/SecurityButton.tsx index 6d9fdca68f0e2..2955abce5ee30 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/SecurityButton.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/SecurityButton.tsx @@ -36,7 +36,7 @@ export const SecurityButton = () => { return ( - } title={translate("nav.security")} /> + {authLinks.extra_menu_items.map(({ text }) => { diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneMenuItem.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneMenuItem.tsx index 596cf79bb1ba1..cb13b3c976301 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneMenuItem.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/TimezoneMenuItem.tsx @@ -16,6 +16,7 @@ * specific language governing permissions and limitations * under the License. */ +import { Box, Icon } from "@chakra-ui/react"; import dayjs from "dayjs"; import timezone from "dayjs/plugin/timezone"; import utc from "dayjs/plugin/utc"; @@ -48,8 +49,8 @@ export const TimezoneMenuItem = ({ onOpen }: { readonly onOpen: () => void }) => return ( - - {translate("timezone")}: {dayjs(time).tz(selectedTimezone).format("HH:mm z (Z)")} + + {translate("timezone")}: {dayjs(time).tz(selectedTimezone).format("HH:mm z (Z)")} ); }; diff --git a/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx b/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx index 31e2dd0078a60..15ee91b04228c 100644 --- a/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx +++ b/airflow-core/src/airflow/ui/src/layouts/Nav/UserSettingsButton.tsx @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { useDisclosure } from "@chakra-ui/react"; +import { Box, Icon, useDisclosure } from "@chakra-ui/react"; import { useTranslation } from "react-i18next"; import { FiGrid, @@ -55,9 +55,29 @@ type ColorMode = (typeof COLOR_MODES)[keyof typeof COLOR_MODES]; export const UserSettingsButton = ({ externalViews }: { readonly externalViews: Array }) => { const { i18n, t: translate } = useTranslation(); const { selectedTheme, setColorMode } = useColorMode(); + + const colorModeOptions = [ + { + icon: FiSun, + label: translate("appearance.lightMode"), + value: COLOR_MODES.LIGHT, + }, + { + icon: FiMoon, + label: translate("appearance.darkMode"), + value: COLOR_MODES.DARK, + }, + { + icon: FiMonitor, + label: translate("appearance.systemMode"), + value: COLOR_MODES.SYSTEM, + }, + ]; + const { onClose: onCloseTimezone, onOpen: onOpenTimezone, open: isOpenTimezone } = useDisclosure(); const { onClose: onCloseLogout, onOpen: onOpenLogout, open: isOpenLogout } = useDisclosure(); const { onClose: onCloseLanguage, onOpen: onOpenLanguage, open: isOpenLanguage } = useDisclosure(); + const [dagView, setDagView] = useLocalStorage<"graph" | "grid">("default_dag_view", "grid"); const theme = selectedTheme ?? COLOR_MODES.SYSTEM; @@ -65,79 +85,58 @@ export const UserSettingsButton = ({ externalViews }: { readonly externalViews: const isRTL = i18n.dir() === "rtl"; return ( - - - } title={translate("user")} /> - - - - - {translate("selectLanguage")} - - - - - {translate("appearance.appearance")} - {isRTL ? ( - - ) : ( - - )} - - - setColorMode(element.value as ColorMode)} - value={theme} - > - - - {translate("appearance.lightMode")} - - - - - {translate("appearance.darkMode")} - - - - - {translate("appearance.systemMode")} - - - - - - (dagView === "grid" ? setDagView("graph") : setDagView("grid"))} - value={dagView} - > - {dagView === "grid" ? ( - <> - - {translate("defaultToGraphView")} - - ) : ( - <> - - {translate("defaultToGridView")} - - )} - - - {externalViews.map((view) => ( - - ))} - - - {translate("logout")} - - + <> + + + + + + + + {translate("selectLanguage")} + + + + + {translate("appearance.appearance")} + + + + setColorMode(element.value as ColorMode)} + value={theme} + > + {colorModeOptions.map(({ icon, label, value }) => ( + + + {label} + + + ))} + + + + (dagView === "grid" ? setDagView("graph") : setDagView("grid"))} + value={dagView} + > + + {dagView === "grid" ? translate("defaultToGraphView") : translate("defaultToGridView")} + + + {externalViews.map((view) => ( + + ))} + + + + {translate("logout")} + + + - + ); };