Palash Gupta f2f89eb38b
feat: uplot graph is added and some re-rendering is reduced (#3771)
* feat: uplot graph is added and some re-rendering is reduced

* chore: uplot is updated

* feat: changes for the graph is updated

* refactor: added y-axis unit in uplot graph (#3818)

* refactor: added y-axis unit in uplot graph

* refactor: removed the ticks stroke from both access

* feat: create tooltip plugin for uplot charts (#3823)

* feat: create tooltip plugin for uplot charts

* feat: show labels in legends section

---------

Co-authored-by: Yunus M <myounis.ar@live.com>

* feat: uplot points is handled  (#3817)

* chore: resize is updated

* chore: uplot chart dark mode is updated

* chore: widget is updated

* chore: options is updated

* chore: value panel is updated

* feat: uplot chart is updated

* feat: onDrag is updated

* feat: data for graph is updated

* feat: alert section is fixed

* feat: not found is updated

* feat: fix dashboard title section and other uplot parity issues (#3839)

* feat: fix dashboard title section and other uplot parity issues

* feat: update scrollbar style for legend container

* chore: initial width is updated

* feat: onlcick is updated

* feat: widget full view fixes (#3847)

Co-authored-by: Palash Gupta <palashgdev@gmail.com>

* feat: show labels in tooltip overlay (#3867)

* chore: memo is added

* feat: toggle is updated

* fix: Tooltip values is now fixed (#3894)

* chore: tooltip is updated

* chore: avoided the compute based on show

* chore: tooltip data is updated

* feat: resize graph based on the y axis max label length (#3895)

* chore: build is in progress to fix

* [Feat]: Full View  (#3896)

* fix: initial setup for full view done

* refactor: done with the graph manager logic

* refactor: done with the toggle issue in full view

* refactor: done with toggle of data

* refactor: done with legend to table mapping

* refactor: ts error

* chore: utils is updated

* refactor: updated types

* fix: option type fix

---------

Co-authored-by: Palash Gupta <palashgdev@gmail.com>

* feat: use spline renderer to plot curved line graphs, full view impor… (#3919)

* feat: use spline renderer to plot curved line graphs, full view imporvements

* feat: increase min height for panel

* chore: move code to utils and plugins in uplot folder

* chore: update tooltip styles

* fix: add panel issue in dashboard (#3920)

* fix: update on click plugin opts import path

* feat: replace time series graph in logs explorer and trace explorer with uplot (#3925)

* feat: alert threshold is added (#3931)

* feat: uplot styles are fixed (#3941)

* Fix/app dex aligment (#3944)

* feat: uplot styles are fixed

* fix: app dex aligment

* fix: full view after saving is fixed

* feat: css is updated (#3948)

* feat: on click handler position - factor in the padding on top and left

* fix: timestamp for start and end is updated for view trace (#3966)

* fix: timestamp for start and end is updated for view trace

* chore: timestamp is added

* fix: loading over flow is fixed (#3969)

---------

Co-authored-by: Rajat Dabade <rajat@signoz.io>
Co-authored-by: Yunus M <myounis.ar@live.com>
2023-11-15 15:33:45 +05:30

173 lines
4.6 KiB
TypeScript

import { PlusOutlined, SaveFilled } from '@ant-design/icons';
import { SOMETHING_WENT_WRONG } from 'constants/api';
import { PANEL_TYPES } from 'constants/queryBuilder';
import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
import useComponentPermission from 'hooks/useComponentPermission';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useNotifications } from 'hooks/useNotifications';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { useTranslation } from 'react-i18next';
import { useSelector } from 'react-redux';
import { AppState } from 'store/reducers';
import { Dashboard, Widgets } from 'types/api/dashboard/getAll';
import AppReducer from 'types/reducer/app';
import { ROLES, USER_ROLES } from 'types/roles';
import { ComponentTypes } from 'utils/permission';
import { EditMenuAction, ViewMenuAction } from './config';
import GridCard from './GridCard';
import {
Button,
ButtonContainer,
Card,
CardContainer,
ReactGridLayout,
} from './styles';
import { GraphLayoutProps } from './types';
function GraphLayout({ onAddPanelHandler }: GraphLayoutProps): JSX.Element {
const {
selectedDashboard,
layouts,
setLayouts,
setSelectedDashboard,
isDashboardLocked,
} = useDashboard();
const { data } = selectedDashboard || {};
const { widgets, variables } = data || {};
const { t } = useTranslation(['dashboard']);
const { featureResponse, role, user } = useSelector<AppState, AppReducer>(
(state) => state.app,
);
const isDarkMode = useIsDarkMode();
const updateDashboardMutation = useUpdateDashboard();
const { notifications } = useNotifications();
let permissions: ComponentTypes[] = ['save_layout', 'add_panel'];
if (isDashboardLocked) {
permissions = ['edit_locked_dashboard', 'add_panel_locked_dashboard'];
}
const userRole: ROLES | null =
selectedDashboard?.created_by === user?.email
? (USER_ROLES.AUTHOR as ROLES)
: role;
const [saveLayoutPermission, addPanelPermission] = useComponentPermission(
permissions,
userRole,
);
const onSaveHandler = (): void => {
if (!selectedDashboard) return;
const updatedDashboard: Dashboard = {
...selectedDashboard,
data: {
...selectedDashboard.data,
layout: layouts.filter((e) => e.i !== PANEL_TYPES.EMPTY_WIDGET),
},
uuid: selectedDashboard.uuid,
};
updateDashboardMutation.mutate(updatedDashboard, {
onSuccess: (updatedDashboard) => {
if (updatedDashboard.payload) {
if (updatedDashboard.payload.data.layout)
setLayouts(updatedDashboard.payload.data.layout);
setSelectedDashboard(updatedDashboard.payload);
}
notifications.success({
message: t('dashboard:layout_saved_successfully'),
});
featureResponse.refetch();
},
onError: () => {
notifications.error({
message: SOMETHING_WENT_WRONG,
});
},
});
};
const widgetActions = !isDashboardLocked
? [...ViewMenuAction, ...EditMenuAction]
: [...ViewMenuAction];
return (
<>
{!isDashboardLocked && (
<ButtonContainer>
{saveLayoutPermission && (
<Button
loading={updateDashboardMutation.isLoading}
onClick={onSaveHandler}
icon={<SaveFilled />}
disabled={updateDashboardMutation.isLoading}
>
{t('dashboard:save_layout')}
</Button>
)}
{addPanelPermission && (
<Button onClick={onAddPanelHandler} icon={<PlusOutlined />}>
{t('dashboard:add_panel')}
</Button>
)}
</ButtonContainer>
)}
<ReactGridLayout
cols={12}
rowHeight={100}
autoSize
width={100}
useCSSTransforms
isDraggable={!isDashboardLocked && addPanelPermission}
isDroppable={!isDashboardLocked && addPanelPermission}
isResizable={!isDashboardLocked && addPanelPermission}
allowOverlap={false}
onLayoutChange={setLayouts}
draggableHandle=".drag-handle"
layout={layouts}
>
{layouts.map((layout) => {
const { i: id } = layout;
const currentWidget = (widgets || [])?.find((e) => e.id === id);
return (
<CardContainer
className={isDashboardLocked ? '' : 'enable-resize'}
isDarkMode={isDarkMode}
key={id}
data-grid={layout}
>
<Card
className="grid-item"
$panelType={currentWidget?.panelTypes || PANEL_TYPES.TIME_SERIES}
>
<GridCard
widget={currentWidget || ({ id, query: {} } as Widgets)}
name={currentWidget?.id || ''}
headerMenuList={widgetActions}
variables={variables}
/>
</Card>
</CardContainer>
);
})}
</ReactGridLayout>
</>
);
}
export default GraphLayout;