- {/* eslint-disable-next-line css-modules/no-undef-class */}
diff --git a/airbyte-webapp/src/views/Connection/CatalogTree/StreamHeader.tsx b/airbyte-webapp/src/views/Connection/CatalogTree/StreamHeader.tsx
index 4b68734658e0..01606ac001db 100644
--- a/airbyte-webapp/src/views/Connection/CatalogTree/StreamHeader.tsx
+++ b/airbyte-webapp/src/views/Connection/CatalogTree/StreamHeader.tsx
@@ -94,8 +94,6 @@ export const StreamHeader: React.FC
= ({
[styles.purpleBackground]: isSelected,
[styles.redBorder]: hasError,
});
- // FIXME: find out why checkboxCell warns as unused
- // eslint-disable-next-line css-modules/no-undef-class
const checkboxCellCustomStyle = classnames(styles.checkboxCell, { [styles.streamRowCheckboxCell]: true });
return (
diff --git a/airbyte-webapp/src/views/layout/SideBar/SideBar.module.scss b/airbyte-webapp/src/views/layout/SideBar/SideBar.module.scss
index 4321f1f01f01..2bcbe139f03f 100644
--- a/airbyte-webapp/src/views/layout/SideBar/SideBar.module.scss
+++ b/airbyte-webapp/src/views/layout/SideBar/SideBar.module.scss
@@ -1,5 +1,40 @@
@use "../../../scss/colors";
@use "../../../scss/variables";
+@use "../../../scss/z-indices";
+
+.nav {
+ z-index: z-indices.$sidebar;
+ display: flex;
+ position: relative;
+ flex-direction: column;
+ justify-content: space-between;
+ height: 100%;
+ width: 100px;
+ min-width: 65px;
+ background-color: colors.$dark-blue;
+ padding: 23px 4px 15px;
+ text-align: center;
+}
+
+.text {
+ margin-top: 7px;
+ color: colors.$white;
+}
+
+.helpIcon {
+ font-size: 21px;
+ line-height: 21px;
+}
+
+.menu {
+ width: 100%;
+ padding: 0;
+ margin: variables.$spacing-xl 0 0;
+
+ li {
+ margin-top: 7px;
+ }
+}
.menuItem {
background-color: transparent;
@@ -17,7 +52,6 @@
font-weight: normal;
font-size: 12px;
line-height: 15px;
- margin-top: 7px;
text-decoration: none;
position: relative;
@@ -50,9 +84,4 @@
background: colors.$dark-blue-400;
}
}
-
- &.popoutOpen {
- background: colors.$dark-blue-600;
- transition: variables.$transition-out;
- }
}
diff --git a/airbyte-webapp/src/views/layout/SideBar/SideBar.tsx b/airbyte-webapp/src/views/layout/SideBar/SideBar.tsx
index b9e5dce9a963..2c9dbc430c91 100644
--- a/airbyte-webapp/src/views/layout/SideBar/SideBar.tsx
+++ b/airbyte-webapp/src/views/layout/SideBar/SideBar.tsx
@@ -1,12 +1,13 @@
+import { faSlack } from "@fortawesome/free-brands-svg-icons";
import { faRocket } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import classnames from "classnames";
import React from "react";
import { FormattedMessage } from "react-intl";
import { NavLink, useLocation } from "react-router-dom";
-import styled from "styled-components";
import { Link } from "components";
+import { Text } from "components/base/Text";
import Version from "components/Version";
import { useConfig } from "config";
@@ -17,41 +18,13 @@ import ConnectionsIcon from "./components/ConnectionsIcon";
import DestinationIcon from "./components/DestinationIcon";
import DocsIcon from "./components/DocsIcon";
import OnboardingIcon from "./components/OnboardingIcon";
+import RecipesIcon from "./components/RecipesIcon";
import SettingsIcon from "./components/SettingsIcon";
-import SidebarPopout from "./components/SidebarPopout";
+import { SidebarDropdownMenu, SidebarDropdownMenuItemType } from "./components/SidebarDropdownMenu";
import SourceIcon from "./components/SourceIcon";
import { NotificationIndicator } from "./NotificationIndicator";
import styles from "./SideBar.module.scss";
-const Bar = styled.nav`
- width: 100px;
- min-width: 65px;
- height: 100%;
- background: ${({ theme }) => theme.darkPrimaryColor};
- padding: 23px 3px 15px 4px;
- text-align: center;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
- position: relative;
- z-index: 9999;
-`;
-
-const Menu = styled.ul`
- padding: 0;
- margin: 20px 0 0;
- width: 100%;
-`;
-
-const Text = styled.div`
- margin-top: 7px;
-`;
-
-const HelpIcon = styled(FontAwesomeIcon)`
- font-size: 21px;
- line-height: 21px;
-`;
-
export const useCalculateSidebarStyles = () => {
const location = useLocation();
@@ -63,28 +36,23 @@ export const useCalculateSidebarStyles = () => {
return ({ isActive }: { isActive: boolean }) => menuItemStyle(isActive);
};
-export const getPopoutStyles = (isOpen?: boolean) => {
- return classnames(styles.menuItem, { [styles.popoutOpen]: isOpen });
-};
-
const SideBar: React.FC = () => {
const config = useConfig();
const workspace = useCurrentWorkspace();
-
const navLinkClassName = useCalculateSidebarStyles();
return (
-
+
+
+
);
};
diff --git a/airbyte-webapp/src/views/layout/SideBar/components/SidebarDropdownMenu.module.scss b/airbyte-webapp/src/views/layout/SideBar/components/SidebarDropdownMenu.module.scss
new file mode 100644
index 000000000000..82b425ddf821
--- /dev/null
+++ b/airbyte-webapp/src/views/layout/SideBar/components/SidebarDropdownMenu.module.scss
@@ -0,0 +1,77 @@
+@use "../../../../scss/colors";
+@use "../../../../scss/variables";
+
+.sidebarMenu {
+ position: relative;
+}
+
+.button {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ height: 70px;
+ width: 100%;
+ background: transparent;
+ border: 0;
+ outline: none;
+ cursor: pointer;
+ border-radius: variables.$border-radius-md;
+ color: colors.$grey-30;
+ text-decoration: none;
+ transition: variables.$transition-out;
+
+ .text {
+ margin-top: 7px;
+ color: colors.$grey-30;
+ }
+
+ &.open {
+ background-color: colors.$dark-blue-600;
+ }
+
+ &:hover:not(.open) {
+ background-color: colors.$dark-blue-800;
+ }
+}
+
+.items {
+ position: absolute;
+ left: 100%;
+ bottom: 0;
+ min-width: 260px;
+ margin: 0 0 14px 12px;
+ padding: variables.$spacing-sm 0;
+ outline: none;
+ border-radius: variables.$border-radius-xs;
+ background-color: colors.$white;
+ box-shadow: 0 8px 10px 0 rgb(11 10 26 / 4%), 0 3px 14px 0 rgb(11 10 26 / 8%), 0 5px 5px 0 rgb(11 10 26 / 12%);
+
+ &:focus-within {
+ outline: none;
+ }
+
+ .item {
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ height: 42px;
+ width: 100%;
+ padding: 0 variables.$spacing-lg;
+ border: 0;
+ background-color: transparent;
+ text-decoration: none;
+
+ .icon {
+ display: flex;
+ align-items: center;
+ width: 34px;
+ font-size: 22px;
+ color: colors.$dark-blue;
+ }
+
+ &.active {
+ background-color: colors.$grey-50;
+ }
+ }
+}
diff --git a/airbyte-webapp/src/views/layout/SideBar/components/SidebarDropdownMenu.tsx b/airbyte-webapp/src/views/layout/SideBar/components/SidebarDropdownMenu.tsx
new file mode 100644
index 000000000000..6ce486eb741b
--- /dev/null
+++ b/airbyte-webapp/src/views/layout/SideBar/components/SidebarDropdownMenu.tsx
@@ -0,0 +1,80 @@
+import { Menu } from "@headlessui/react";
+import classNames from "classnames";
+import React from "react";
+
+import { Text } from "components/base/Text";
+
+import styles from "./SidebarDropdownMenu.module.scss";
+
+export enum SidebarDropdownMenuItemType {
+ LINK = "link",
+ BUTTON = "button",
+}
+
+interface MenuItemLink {
+ type: SidebarDropdownMenuItemType.LINK;
+ href: string;
+ icon: React.ReactNode;
+ displayName: React.ReactNode;
+}
+
+interface MenuItemButton {
+ type: SidebarDropdownMenuItemType.BUTTON;
+ icon: React.ReactNode;
+ displayName: React.ReactNode;
+ onClick: () => void;
+}
+
+interface Label {
+ icon: React.ReactNode;
+ displayName: React.ReactNode;
+}
+
+export const SidebarDropdownMenu: React.FC<{
+ label: Label;
+ options?: Array;
+}> = ({ label, options }) => {
+ function menuItem(active: boolean, item: MenuItemLink | MenuItemButton): React.ReactNode {
+ switch (item.type) {
+ case SidebarDropdownMenuItemType.LINK:
+ return (
+
+ {item.icon}
+ {item.displayName}
+
+ );
+ case SidebarDropdownMenuItemType.BUTTON:
+ return (
+
+ );
+ }
+ }
+
+ return (
+
+ );
+};
diff --git a/airbyte-webapp/src/views/layout/SideBar/components/SidebarPopout.tsx b/airbyte-webapp/src/views/layout/SideBar/components/SidebarPopout.tsx
deleted file mode 100644
index 842732987692..000000000000
--- a/airbyte-webapp/src/views/layout/SideBar/components/SidebarPopout.tsx
+++ /dev/null
@@ -1,132 +0,0 @@
-import { faSlack } from "@fortawesome/free-brands-svg-icons";
-import { faEnvelope } from "@fortawesome/free-regular-svg-icons";
-import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import React, { useMemo } from "react";
-import { FormattedMessage } from "react-intl";
-import styled from "styled-components";
-
-import { Popout } from "components";
-
-import { useConfig } from "config";
-
-import DocsIcon from "./DocsIcon";
-import RecipesIcon from "./RecipesIcon";
-import StatusIcon from "./StatusIcon";
-
-export const Item = styled.a`
- display: flex;
- flex-direction: row;
- align-items: center;
- text-decoration: none;
- color: ${({ theme }) => theme.textColor};
- font-size: 14px;
- font-weight: 500;
-`;
-
-export const Icon = styled.div`
- width: 34px;
- font-size: 22px;
-`;
-
-const SidebarPopout: React.FC<{
- children: (props: { onOpen: () => void; isOpen?: boolean }) => React.ReactNode;
- options: Array<{ value: string; label?: React.ReactNode }>;
-}> = ({ children, options }) => {
- const config = useConfig();
-
- const listData = useMemo(
- () =>
- options.map((item) => {
- switch (item.value) {
- case "docs":
- return {
- value: "docs",
- label: (
- -
-
-
-
-
-
- ),
- };
- case "slack":
- return {
- value: "slack",
- label: (
- -
-
-
-
-
-
- ),
- };
- case "status":
- return {
- value: "status",
- label: (
- -
-
-
-
-
-
- ),
- };
- case "recipes":
- return {
- value: "recipes",
- label: (
- -
-
-
-
-
-
- ),
- };
- case "ticket":
- return {
- value: "ticket",
- label: (
- -
-
-
-
-
-
- ),
- };
- default:
- return {
- value: item.value,
- label: item.label ?? item.value,
- };
- }
- }),
- [options, config]
- );
-
- return (
-
- children({
- onOpen: targetProps.onOpen,
- isOpen: targetProps.isOpen,
- })
- }
- styles={{
- menuPortal: (base) => ({
- ...base,
- // TODO: temporary dirty hack
- transform: "translate3D(100px, -100px, 0px)",
- }),
- }}
- isSearchable={false}
- options={listData}
- />
- );
-};
-
-export default SidebarPopout;