openreplay/frontend/app/components/ui/ItemMenu/ItemMenu.tsx
Delirium d604f9920b
feat ui: dashboards redesign (#2230)
* feat ui: dashboards redesign start

* more cards

* fix ui: more different cards...

* feat ui: finish cards, all trigger, all icons

* change(ui): added missin const

* feature(ui): new dashboard modal

* feature(ui): new dashboard modal

* change(ui): new cards

* change(ui): dashboard redesign

* change(ui): dashboard redesign

* change(ui): dashboard redesign

* change(ui): modal context and alert form

* change(ui): table card show more with modal

* change(ui): examples

* change(ui): example categorize and other improvements

* change(ui): example categorize and other improvements

* change(ui): performance cards

* change(ui): insights card

* Various style updates in dashboards and other pages. (#2308)

* Various minor style updates

* Various style improvements

* Update ExampleCards.tsx

* change(ui): fixed an issue with card create

* change(ui): fixed an issue with card create

* change(ui): default filters and events order

* change(ui): random data

* Dashboards redesign - improvments (#2313)

* Various minor style updates

* Various style improvements

* Update ExampleCards.tsx

* various minor improvements in dashbaords.

* revised dashboard widget header

* change(ui): sessions by user

* change(ui): funnel example

* change(ui): modal height and scroll

* change(ui): example cards with data

* change(ui): example cards with data

* change(ui): funnel bar text color

* change(ui): example cards overlay click

* change(ui): path analysis filter card

---------

Co-authored-by: Shekar Siri <sshekarsiri@gmail.com>
Co-authored-by: Sudheer Salavadi <connect.uxmaster@gmail.com>
2024-06-27 19:47:34 +02:00

124 lines
No EOL
3.5 KiB
TypeScript

import React from "react";
import { Icon, Popover, Tooltip } from "UI";
import { Dropdown, Menu, Button } from "antd";
import { MoreOutlined } from "@ant-design/icons";
import styles from "./itemMenu.module.css";
import cn from "classnames";
interface Item {
icon?: string;
text: string;
onClick: (args: any) => void;
hidden?: boolean;
disabled?: boolean;
tooltipTitle?: string;
}
interface Props {
bold?: boolean;
flat?: boolean;
items: Item[];
label?: React.ReactNode;
sm?: boolean;
onToggle?: (args: any) => void;
}
export default class ItemMenu extends React.PureComponent<Props> {
menuBtnRef: HTMLDivElement = null;
state = {
displayed: false,
};
handleEsc = (e: KeyboardEvent) => e.key === "Escape" && this.closeMenu();
componentDidMount() {
document.addEventListener("keydown", this.handleEsc, false);
}
componentWillUnmount() {
document.removeEventListener("keydown", this.handleEsc, false);
}
onClick = (callback: Function) => (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();
callback(e);
};
toggleMenu = () => {
const shouldDisplay = !this.state.displayed;
this.setState({ displayed: shouldDisplay });
this.props.onToggle?.(shouldDisplay);
};
closeMenu = () => {
this.setState({ displayed: false });
this.props.onToggle?.(false);
};
render() {
const { items, label, bold, sm } = this.props;
const { displayed } = this.state;
const parentStyles = label ? "hover:bg-gray-light" : "";
return (
<Popover
placement="bottom-end" // Set the placement to bottom-end for right alignment
render={() => (
<div className={cn(styles.menu, 'rounded-lg', { [styles.menuDim]: !bold })}>
{items
.filter(({ hidden }) => !hidden)
.map(
({
onClick,
text,
icon,
disabled = false,
tooltipTitle = "",
}) => (
<Tooltip key={text} disabled={!disabled} title={tooltipTitle} delay={0}>
<div
onClick={!disabled ? this.onClick(onClick) : () => {}}
className={`${disabled ? "cursor-not-allowed" : ""}`}
role="menuitem"
>
<div className={cn(styles.menuItem, { disabled: disabled })}>
{icon && (
<div className={styles.iconWrapper}>
<Icon name={icon} size="13" color="gray-dark" />
</div>
)}
<div>{text}</div>
</div>
</div>
</Tooltip>
)
)}
</div>
)}
>
<Button
className={cn("select-none", !this.props.flat ? parentStyles : "", {
"": !this.props.flat && displayed && label,
})}
>
{label && (
<span className={cn("font-medium")}>
{label}
</span>
)}
{!this.props.flat && (
<div
ref={(ref) => {
this.menuBtnRef = ref;
}}
className={cn("rounded-full flex items-center justify-center")}
role="button"
>
<MoreOutlined />
</div>
)}
</Button>
</Popover>
);
}
}