mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-14 03:25:57 +08:00
feat: menu header is controlled from menuList rather than boolean for each menu (#3288)
* feat: create alerts method is added * feat: method is updated for onClick * chore: create alerts is udpated * chore: header menu list is updated * chore: headerMenuList is made optional * chore: default props is updated
This commit is contained in:
parent
900752b6e2
commit
3b22698e35
@ -53,9 +53,7 @@ function WidgetGraphComponent({
|
||||
setLayout,
|
||||
onDragSelect,
|
||||
onClickHandler,
|
||||
allowClone = true,
|
||||
allowDelete = true,
|
||||
allowEdit = true,
|
||||
headerMenuList,
|
||||
}: WidgetGraphComponentProps): JSX.Element {
|
||||
const [deleteModal, setDeleteModal] = useState(false);
|
||||
const [modal, setModal] = useState<boolean>(false);
|
||||
@ -281,9 +279,7 @@ function WidgetGraphComponent({
|
||||
onClone={onCloneHandler}
|
||||
queryResponse={queryResponse}
|
||||
errorMessage={errorMessage}
|
||||
allowClone={allowClone}
|
||||
allowDelete={allowDelete}
|
||||
allowEdit={allowEdit}
|
||||
headerMenuList={headerMenuList}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
@ -313,9 +309,6 @@ WidgetGraphComponent.defaultProps = {
|
||||
setLayout: undefined,
|
||||
onDragSelect: undefined,
|
||||
onClickHandler: undefined,
|
||||
allowDelete: true,
|
||||
allowClone: true,
|
||||
allowEdit: true,
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (
|
||||
|
@ -15,6 +15,7 @@ import { GlobalReducer } from 'types/reducer/globalTime';
|
||||
import { getSelectedDashboardVariable } from 'utils/dashboard/selectedDashboard';
|
||||
|
||||
import EmptyWidget from '../EmptyWidget';
|
||||
import { MenuItemKeys } from '../WidgetHeader/contants';
|
||||
import { GridCardGraphProps } from './types';
|
||||
import WidgetGraphComponent from './WidgetGraphComponent';
|
||||
|
||||
@ -26,9 +27,7 @@ function GridCardGraph({
|
||||
setLayout,
|
||||
onDragSelect,
|
||||
onClickHandler,
|
||||
allowDelete,
|
||||
allowClone,
|
||||
allowEdit,
|
||||
headerMenuList = [MenuItemKeys.View],
|
||||
isQueryEnabled,
|
||||
}: GridCardGraphProps): JSX.Element {
|
||||
const { isAddWidget } = useSelector<AppState, DashboardReducer>(
|
||||
@ -121,9 +120,7 @@ function GridCardGraph({
|
||||
yAxisUnit={yAxisUnit}
|
||||
layout={layout}
|
||||
setLayout={setLayout}
|
||||
allowClone={allowClone}
|
||||
allowDelete={allowDelete}
|
||||
allowEdit={allowEdit}
|
||||
headerMenuList={headerMenuList}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
@ -145,9 +142,7 @@ function GridCardGraph({
|
||||
yAxisUnit={yAxisUnit}
|
||||
layout={layout}
|
||||
setLayout={setLayout}
|
||||
allowClone={allowClone}
|
||||
allowDelete={allowDelete}
|
||||
allowEdit={allowEdit}
|
||||
headerMenuList={headerMenuList}
|
||||
onClickHandler={onClickHandler}
|
||||
/>
|
||||
) : (
|
||||
@ -170,9 +165,7 @@ function GridCardGraph({
|
||||
name={name}
|
||||
yAxisUnit={yAxisUnit}
|
||||
onDragSelect={onDragSelect}
|
||||
allowClone={allowClone}
|
||||
allowDelete={allowDelete}
|
||||
allowEdit={allowEdit}
|
||||
headerMenuList={headerMenuList}
|
||||
onClickHandler={onClickHandler}
|
||||
/>
|
||||
)}
|
||||
@ -185,10 +178,8 @@ function GridCardGraph({
|
||||
GridCardGraph.defaultProps = {
|
||||
onDragSelect: undefined,
|
||||
onClickHandler: undefined,
|
||||
allowDelete: true,
|
||||
allowClone: true,
|
||||
allowEdit: true,
|
||||
isQueryEnabled: true,
|
||||
headerMenuList: [MenuItemKeys.View],
|
||||
};
|
||||
|
||||
export default memo(GridCardGraph);
|
||||
|
@ -10,6 +10,7 @@ import { Widgets } from 'types/api/dashboard/getAll';
|
||||
import { MetricRangePayloadProps } from 'types/api/metrics/getQueryRange';
|
||||
|
||||
import { LayoutProps } from '..';
|
||||
import { MenuItemKeys } from '../WidgetHeader/contants';
|
||||
import { LegendEntryProps } from './FullView/types';
|
||||
|
||||
export interface GraphVisibilityLegendEntryProps {
|
||||
@ -38,25 +39,19 @@ export interface WidgetGraphComponentProps extends DispatchProps {
|
||||
setLayout?: Dispatch<SetStateAction<LayoutProps[]>>;
|
||||
onDragSelect?: (start: number, end: number) => void;
|
||||
onClickHandler?: GraphOnClickHandler;
|
||||
allowDelete?: boolean;
|
||||
allowClone?: boolean;
|
||||
allowEdit?: boolean;
|
||||
headerMenuList: MenuItemKeys[];
|
||||
}
|
||||
|
||||
export interface GridCardGraphProps {
|
||||
widget: Widgets;
|
||||
name: string;
|
||||
yAxisUnit: string | undefined;
|
||||
// eslint-disable-next-line react/require-default-props
|
||||
layout?: Layout[];
|
||||
// eslint-disable-next-line react/require-default-props
|
||||
setLayout?: Dispatch<SetStateAction<LayoutProps[]>>;
|
||||
onDragSelect?: (start: number, end: number) => void;
|
||||
onClickHandler?: GraphOnClickHandler;
|
||||
allowDelete?: boolean;
|
||||
allowClone?: boolean;
|
||||
allowEdit?: boolean;
|
||||
isQueryEnabled?: boolean;
|
||||
headerMenuList?: WidgetGraphComponentProps['headerMenuList'];
|
||||
isQueryEnabled: boolean;
|
||||
}
|
||||
|
||||
export interface GetGraphVisibilityStateOnLegendClickProps {
|
||||
|
@ -3,6 +3,7 @@ export enum MenuItemKeys {
|
||||
Edit = 'edit',
|
||||
Delete = 'delete',
|
||||
Clone = 'clone',
|
||||
CreateAlerts = 'createAlerts',
|
||||
}
|
||||
|
||||
export const MENUITEM_KEYS_VS_LABELS = {
|
||||
@ -10,4 +11,5 @@ export const MENUITEM_KEYS_VS_LABELS = {
|
||||
[MenuItemKeys.Edit]: 'Edit',
|
||||
[MenuItemKeys.Delete]: 'Delete',
|
||||
[MenuItemKeys.Clone]: 'Clone',
|
||||
[MenuItemKeys.CreateAlerts]: 'Create Alerts',
|
||||
};
|
||||
|
@ -7,9 +7,9 @@ import {
|
||||
FullscreenOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import { Dropdown, MenuProps, Tooltip, Typography } from 'antd';
|
||||
import { MenuItemType } from 'antd/es/menu/hooks/useItems';
|
||||
import Spinner from 'components/Spinner';
|
||||
import { queryParamNamesMap } from 'constants/queryBuilderQueryNames';
|
||||
import ROUTES from 'constants/routes';
|
||||
import useComponentPermission from 'hooks/useComponentPermission';
|
||||
import history from 'lib/history';
|
||||
import { useCallback, useMemo, useState } from 'react';
|
||||
@ -33,7 +33,7 @@ import {
|
||||
HeaderContainer,
|
||||
HeaderContentContainer,
|
||||
} from './styles';
|
||||
import { KeyMethodMappingProps, MenuItem, TWidgetOptions } from './types';
|
||||
import { MenuItem } from './types';
|
||||
import { generateMenuList, isTWidgetOptions } from './utils';
|
||||
|
||||
interface IWidgetHeaderProps {
|
||||
@ -47,10 +47,9 @@ interface IWidgetHeaderProps {
|
||||
SuccessResponse<MetricRangePayloadProps> | ErrorResponse
|
||||
>;
|
||||
errorMessage: string | undefined;
|
||||
allowDelete?: boolean;
|
||||
allowClone?: boolean;
|
||||
allowEdit?: boolean;
|
||||
headerMenuList?: MenuItemKeys[];
|
||||
}
|
||||
|
||||
function WidgetHeader({
|
||||
title,
|
||||
widget,
|
||||
@ -60,9 +59,7 @@ function WidgetHeader({
|
||||
parentHover,
|
||||
queryResponse,
|
||||
errorMessage,
|
||||
allowClone = true,
|
||||
allowDelete = true,
|
||||
allowEdit = true,
|
||||
headerMenuList,
|
||||
}: IWidgetHeaderProps): JSX.Element {
|
||||
const [localHover, setLocalHover] = useState(false);
|
||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
||||
@ -78,32 +75,30 @@ function WidgetHeader({
|
||||
);
|
||||
}, [widget.id, widget.panelTypes, widget.query]);
|
||||
|
||||
const keyMethodMapping: KeyMethodMappingProps<TWidgetOptions> = useMemo(
|
||||
const onCreateAlertsHandler = useCallback(() => {
|
||||
history.push(
|
||||
`${ROUTES.ALERTS_NEW}?${
|
||||
queryParamNamesMap.compositeQuery
|
||||
}=${encodeURIComponent(JSON.stringify(widget.query))}`,
|
||||
);
|
||||
}, [widget]);
|
||||
|
||||
const keyMethodMapping = useMemo(
|
||||
() => ({
|
||||
view: {
|
||||
key: MenuItemKeys.View,
|
||||
method: onView,
|
||||
},
|
||||
edit: {
|
||||
key: MenuItemKeys.Edit,
|
||||
method: onEditHandler,
|
||||
},
|
||||
delete: {
|
||||
key: MenuItemKeys.Delete,
|
||||
method: onDelete,
|
||||
},
|
||||
clone: {
|
||||
key: MenuItemKeys.Clone,
|
||||
method: onClone,
|
||||
},
|
||||
[MenuItemKeys.View]: onView,
|
||||
[MenuItemKeys.Edit]: onEditHandler,
|
||||
[MenuItemKeys.Delete]: onDelete,
|
||||
[MenuItemKeys.Clone]: onClone,
|
||||
[MenuItemKeys.CreateAlerts]: onCreateAlertsHandler,
|
||||
}),
|
||||
[onDelete, onEditHandler, onView, onClone],
|
||||
[onDelete, onEditHandler, onView, onClone, onCreateAlertsHandler],
|
||||
);
|
||||
|
||||
const onMenuItemSelectHandler: MenuProps['onClick'] = useCallback(
|
||||
({ key }: { key: string }): void => {
|
||||
if (isTWidgetOptions(key)) {
|
||||
const functionToCall = keyMethodMapping[key]?.method;
|
||||
const functionToCall = keyMethodMapping[key];
|
||||
|
||||
if (functionToCall) {
|
||||
functionToCall();
|
||||
setIsOpen(false);
|
||||
@ -125,46 +120,43 @@ function WidgetHeader({
|
||||
key: MenuItemKeys.View,
|
||||
icon: <FullscreenOutlined />,
|
||||
label: MENUITEM_KEYS_VS_LABELS[MenuItemKeys.View],
|
||||
isVisible: true,
|
||||
isVisible: headerMenuList?.includes(MenuItemKeys.View) || false,
|
||||
disabled: queryResponse.isLoading,
|
||||
},
|
||||
{
|
||||
key: MenuItemKeys.Edit,
|
||||
icon: <EditFilled />,
|
||||
label: MENUITEM_KEYS_VS_LABELS[MenuItemKeys.Edit],
|
||||
isVisible: allowEdit,
|
||||
isVisible: headerMenuList?.includes(MenuItemKeys.Edit) || false,
|
||||
disabled: !editWidget,
|
||||
},
|
||||
{
|
||||
key: MenuItemKeys.Clone,
|
||||
icon: <CopyOutlined />,
|
||||
label: MENUITEM_KEYS_VS_LABELS[MenuItemKeys.Clone],
|
||||
isVisible: allowClone,
|
||||
isVisible: headerMenuList?.includes(MenuItemKeys.Clone) || false,
|
||||
disabled: !editWidget,
|
||||
},
|
||||
{
|
||||
key: MenuItemKeys.Delete,
|
||||
icon: <DeleteOutlined />,
|
||||
label: MENUITEM_KEYS_VS_LABELS[MenuItemKeys.Delete],
|
||||
isVisible: allowDelete,
|
||||
isVisible: headerMenuList?.includes(MenuItemKeys.Delete) || false,
|
||||
disabled: !deleteWidget,
|
||||
danger: true,
|
||||
},
|
||||
{
|
||||
key: MenuItemKeys.CreateAlerts,
|
||||
icon: <DeleteOutlined />,
|
||||
label: MENUITEM_KEYS_VS_LABELS[MenuItemKeys.CreateAlerts],
|
||||
isVisible: headerMenuList?.includes(MenuItemKeys.CreateAlerts) || false,
|
||||
disabled: false,
|
||||
},
|
||||
],
|
||||
[
|
||||
allowEdit,
|
||||
allowClone,
|
||||
allowDelete,
|
||||
queryResponse.isLoading,
|
||||
deleteWidget,
|
||||
editWidget,
|
||||
],
|
||||
[queryResponse.isLoading, headerMenuList, editWidget, deleteWidget],
|
||||
);
|
||||
|
||||
const menuList: MenuItemType[] = useMemo(
|
||||
(): MenuItemType[] => generateMenuList(actions, keyMethodMapping),
|
||||
[actions, keyMethodMapping],
|
||||
);
|
||||
const updatedMenuList = useMemo(() => generateMenuList(actions), [actions]);
|
||||
|
||||
const onClickHandler = useCallback(() => {
|
||||
setIsOpen((open) => !open);
|
||||
@ -172,10 +164,10 @@ function WidgetHeader({
|
||||
|
||||
const menu = useMemo(
|
||||
() => ({
|
||||
items: menuList,
|
||||
items: updatedMenuList,
|
||||
onClick: onMenuItemSelectHandler,
|
||||
}),
|
||||
[menuList, onMenuItemSelectHandler],
|
||||
[updatedMenuList, onMenuItemSelectHandler],
|
||||
);
|
||||
|
||||
return (
|
||||
@ -219,9 +211,7 @@ function WidgetHeader({
|
||||
WidgetHeader.defaultProps = {
|
||||
onDelete: undefined,
|
||||
onClone: undefined,
|
||||
allowDelete: true,
|
||||
allowClone: true,
|
||||
allowEdit: true,
|
||||
headerMenuList: [MenuItemKeys.View],
|
||||
};
|
||||
|
||||
export default WidgetHeader;
|
||||
|
@ -3,23 +3,10 @@ import { ReactNode } from 'react';
|
||||
import { MenuItemKeys } from './contants';
|
||||
|
||||
export interface MenuItem {
|
||||
key: TWidgetOptions;
|
||||
key: MenuItemKeys;
|
||||
icon: ReactNode;
|
||||
label: string;
|
||||
isVisible: boolean;
|
||||
disabled: boolean;
|
||||
danger?: boolean;
|
||||
}
|
||||
|
||||
export type TWidgetOptions =
|
||||
| MenuItemKeys.View
|
||||
| MenuItemKeys.Edit
|
||||
| MenuItemKeys.Delete
|
||||
| MenuItemKeys.Clone;
|
||||
|
||||
export type KeyMethodMappingProps<T extends TWidgetOptions> = {
|
||||
[K in T]: {
|
||||
key: TWidgetOptions;
|
||||
method?: VoidFunction;
|
||||
};
|
||||
};
|
||||
|
@ -1,24 +1,22 @@
|
||||
import { MenuItemType } from 'antd/es/menu/hooks/useItems';
|
||||
|
||||
import { MenuItemKeys } from './contants';
|
||||
import { KeyMethodMappingProps, MenuItem, TWidgetOptions } from './types';
|
||||
import { MenuItem } from './types';
|
||||
|
||||
export const generateMenuList = (
|
||||
actions: MenuItem[],
|
||||
keyMethodMapping: KeyMethodMappingProps<TWidgetOptions>,
|
||||
): MenuItemType[] =>
|
||||
export const generateMenuList = (actions: MenuItem[]): MenuItemType[] =>
|
||||
actions
|
||||
.filter((action: MenuItem) => action.isVisible)
|
||||
.map(({ key, icon: Icon, label, disabled, ...rest }) => ({
|
||||
key: keyMethodMapping[key].key,
|
||||
key,
|
||||
icon: Icon,
|
||||
label,
|
||||
disabled,
|
||||
...rest,
|
||||
}));
|
||||
|
||||
export const isTWidgetOptions = (value: string): value is TWidgetOptions =>
|
||||
export const isTWidgetOptions = (value: string): value is MenuItemKeys =>
|
||||
value === MenuItemKeys.View ||
|
||||
value === MenuItemKeys.Edit ||
|
||||
value === MenuItemKeys.Delete ||
|
||||
value === MenuItemKeys.Clone;
|
||||
value === MenuItemKeys.Clone ||
|
||||
value === MenuItemKeys.CreateAlerts;
|
||||
|
8
frontend/src/container/GridGraphLayout/config.ts
Normal file
8
frontend/src/container/GridGraphLayout/config.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { MenuItemKeys } from 'container/GridGraphLayout/WidgetHeader/contants';
|
||||
|
||||
export const headerMenuList = [
|
||||
MenuItemKeys.View,
|
||||
MenuItemKeys.Clone,
|
||||
MenuItemKeys.Delete,
|
||||
MenuItemKeys.Edit,
|
||||
];
|
@ -29,6 +29,7 @@ import { Dashboard, Widgets } from 'types/api/dashboard/getAll';
|
||||
import AppReducer from 'types/reducer/app';
|
||||
import DashboardReducer from 'types/reducer/dashboards';
|
||||
|
||||
import { headerMenuList } from './config';
|
||||
import Graph from './Graph';
|
||||
import GraphLayoutContainer from './GraphLayout';
|
||||
import { UpdateDashboard } from './utils';
|
||||
@ -49,6 +50,7 @@ export const getPreLayouts = (
|
||||
yAxisUnit={widget?.yAxisUnit}
|
||||
layout={layout}
|
||||
setLayout={setLayout}
|
||||
headerMenuList={headerMenuList}
|
||||
/>
|
||||
);
|
||||
},
|
||||
@ -233,6 +235,7 @@ function GridGraph(props: Props): JSX.Element {
|
||||
layout={layout}
|
||||
setLayout={setLayout}
|
||||
onDragSelect={onDragSelect}
|
||||
headerMenuList={headerMenuList}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
@ -117,9 +117,6 @@ function DBCall(): JSX.Element {
|
||||
'database_call_rps',
|
||||
);
|
||||
}}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
/>
|
||||
</GraphContainer>
|
||||
</Card>
|
||||
@ -153,9 +150,6 @@ function DBCall(): JSX.Element {
|
||||
'database_call_avg_duration',
|
||||
);
|
||||
}}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
/>
|
||||
</GraphContainer>
|
||||
</Card>
|
||||
|
@ -156,9 +156,6 @@ function External(): JSX.Element {
|
||||
'external_call_error_percentage',
|
||||
);
|
||||
}}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
/>
|
||||
</GraphContainer>
|
||||
</Card>
|
||||
@ -194,9 +191,6 @@ function External(): JSX.Element {
|
||||
'external_call_duration',
|
||||
);
|
||||
}}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
/>
|
||||
</GraphContainer>
|
||||
</Card>
|
||||
@ -233,9 +227,6 @@ function External(): JSX.Element {
|
||||
'external_call_rps_by_address',
|
||||
);
|
||||
}}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
/>
|
||||
</GraphContainer>
|
||||
</Card>
|
||||
@ -271,9 +262,6 @@ function External(): JSX.Element {
|
||||
'external_call_duration_by_address',
|
||||
);
|
||||
}}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
/>
|
||||
</GraphContainer>
|
||||
</Card>
|
||||
|
@ -75,9 +75,6 @@ function ServiceOverview({
|
||||
widget={latencyWidget}
|
||||
yAxisUnit="ns"
|
||||
onClickHandler={handleGraphClick('Service')}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
isQueryEnabled={isQueryEnabled}
|
||||
/>
|
||||
</GraphContainer>
|
||||
|
@ -39,9 +39,6 @@ function TopLevelOperation({
|
||||
onClickHandler={handleGraphClick(opName)}
|
||||
yAxisUnit={yAxisUnit}
|
||||
onDragSelect={onDragSelect}
|
||||
allowClone={false}
|
||||
allowDelete={false}
|
||||
allowEdit={false}
|
||||
/>
|
||||
)}
|
||||
</GraphContainer>
|
||||
|
Loading…
x
Reference in New Issue
Block a user