/* eslint-disable react/display-name */ import { SaveFilled } from '@ant-design/icons'; import { notification } from 'antd'; import updateDashboardApi from 'api/dashboard/update'; import Spinner from 'components/Spinner'; import { GRAPH_TYPES } from 'container/NewDashboard/ComponentsSlider'; import React, { memo, useCallback, useEffect, useRef, useState } from 'react'; import { Layout } from 'react-grid-layout'; import { useSelector } from 'react-redux'; import { AppState } from 'store/reducers'; import DashboardReducer from 'types/reducer/dashboards'; import { v4 } from 'uuid'; import AddWidget from './AddWidget'; import Graph from './Graph'; import { Button, ButtonContainer, Card, CardContainer, ReactGridLayout, } from './styles'; import { updateDashboard } from './utils'; const GridGraph = (): JSX.Element => { const { dashboards, loading } = useSelector( (state) => state.dashboards, ); const [saveLayoutState, setSaveLayoutState] = useState({ loading: false, error: false, errorMessage: '', payload: [], }); const [selectedDashboard] = dashboards; const { data } = selectedDashboard; const { widgets } = data; const [layouts, setLayout] = useState([]); const AddWidgetWrapper = useCallback(() => , []); const isMounted = useRef(true); const isDeleted = useRef(false); const getPreLayouts: () => LayoutProps[] = useCallback(() => { if (widgets === undefined) { return []; } // when the layout is not present if (data.layout === undefined) { return widgets.map((e, index) => { return { h: 2, w: 6, y: Infinity, i: (index + 1).toString(), x: (index % 2) * 6, Component: (): JSX.Element => ( ), }; }); } else { return data.layout .filter((_, index) => widgets[index]) .map((e, index) => ({ ...e, Component: (): JSX.Element => { if (widgets[index]) { return ( ); } return <>; }, })); } }, [widgets, data.layout]); useEffect(() => { if ( loading === false && (isMounted.current === true || isDeleted.current === true) ) { const preLayouts = getPreLayouts(); setLayout(() => { const getX = (): number => { if (preLayouts && preLayouts?.length > 0) { const last = preLayouts[preLayouts?.length - 1]; return (last.w + last.x) % 12; } return 0; }; console.log({ x: getX() }); return [ ...preLayouts, { i: (preLayouts.length + 1).toString(), x: getX(), y: Infinity, w: 6, h: 2, Component: AddWidgetWrapper, maxW: 6, isDraggable: false, isResizable: false, isBounded: true, }, ]; }); } return (): void => { isMounted.current = false; }; }, [widgets, layouts.length, AddWidgetWrapper, loading, getPreLayouts]); const onDropHandler = useCallback( async (allLayouts: Layout[], currentLayout: Layout, event: DragEvent) => { event.preventDefault(); if (event.dataTransfer) { try { const graphType = event.dataTransfer.getData('text') as GRAPH_TYPES; const generateWidgetId = v4(); await updateDashboard({ data, generateWidgetId, graphType, selectedDashboard: selectedDashboard, layout: allLayouts .map((e, index) => ({ ...e, i: index.toString(), // when a new element drops w: e.i === '__dropping-elem__' ? 6 : e.w, h: e.i === '__dropping-elem__' ? 2 : e.h, })) .filter((e) => e.maxW === undefined), }); } catch (error) { notification.error({ message: error.toString() || 'Something went wrong', }); } } }, [data, selectedDashboard], ); const onLayoutSaveHandler = async (): Promise => { setSaveLayoutState((state) => ({ ...state, error: false, errorMessage: '', loading: true, })); const response = await updateDashboardApi({ title: data.title, uuid: selectedDashboard.uuid, description: data.description, name: data.name, tags: data.tags, widgets: data.widgets, layout: saveLayoutState.payload.filter((e) => e.maxW === undefined), }); if (response.statusCode === 200) { setSaveLayoutState((state) => ({ ...state, error: false, errorMessage: '', loading: false, })); } else { setSaveLayoutState((state) => ({ ...state, error: true, errorMessage: response.error || 'Something went wrong', loading: false, })); } }; const onLayoutChangeHandler = (layout: Layout[]): void => { setSaveLayoutState({ loading: false, error: false, errorMessage: '', payload: layout, }); }; if (layouts.length === 0) { return ; } return ( <> {layouts.map(({ Component, ...rest }, index) => { const widget = (widgets || [])[index] || {}; const type = widget?.panelTypes || 'TIME_SERIES'; const isQueryType = type === 'VALUE'; return ( ); })} ); }; interface LayoutProps extends Layout { Component: () => JSX.Element; } interface State { loading: boolean; error: boolean; payload: Layout[]; errorMessage: string; } export default memo(GridGraph);