import "react-grid-layout/css/styles.css"; import "react-resizable/css/styles.css"; import "./DashboardDesigner.scss"; import { WidthProvider, Responsive } from "react-grid-layout"; import React, { createRef } from "react"; import { Button } from "primereact/button"; import _ from "lodash"; import { Ripple } from "primereact/ripple"; import { OverlayPanel } from "primereact/overlaypanel"; import { Dropdown } from "primereact/dropdown"; import { Dialog } from "primereact/dialog"; import NewWidget from "./NewWidget"; import { Calendar } from 'primereact/calendar'; import ColumnChartComponent from "../ChartsComponents/ColumnChartComponent"; import PieChartComponent from "../ChartsComponents/PieChartComponent"; import MixedChartComponent from "../ChartsComponents/MixedChartComponent"; import AreaChartComponent from "../ChartsComponents/AreaChartComponent"; import TimelineChartComponent from "../ChartsComponents/TimelineChartComponent"; import CandleChartComponent from "../ChartsComponents/CandleChartComponent"; import BarChartComponent from "../ChartsComponents/BarChartComponent"; import { WidgetComponent } from "../types/WidgetComponent"; import { Widget } from "../types/widget"; const ResponsiveReactGridLayout = WidthProvider(Responsive); class DashboardDesigner extends React.Component { moreButtonToggle; widgetButtonToggle; addWidgetButtonToggle; widgetComponents: WidgetComponent[] = [ { type: "Bar", component: BarChartComponent }, { type: "Column", component: ColumnChartComponent }, { type: "Pie", component: PieChartComponent }, { type: "Mixed", component: MixedChartComponent }, { type: "Timeline", component: TimelineChartComponent }, { type: "Candle", component: CandleChartComponent }, { type: "Area", component: AreaChartComponent }, ]; constructor(props: any) { super(props); this.moreButtonToggle = createRef(); this.widgetButtonToggle = createRef(); this.addWidgetButtonToggle = createRef(); var savedLayouts = this.getFromStorage("grid-layout"); var savedWidgets = this.getFromStorage("grid-widgets"); this.state = { layouts: savedLayouts || { lg: [] }, showMsg: false, dateFilter: null, displayDialog: false, dashboardTitle: "", widgets: savedWidgets || [], }; } static get layoutGridProps() { return { rowHeight: 50, className: "layout", cols: { lg: 12, md: 10, sm: 2, xs: 1, xxs: 1 }, // compactType: 'vertical', useCSSTransforms: true, }; } showMsg = false; onLayoutChange(layout: any, layouts) { this.saveToStorage("grid-layout", layouts); this.saveToStorage("grid-widgets", this.state.widgets); this.setState({ layouts }); } deletePanel = (i) => { let layout = this.state.layouts["lg"]; var itemIndex = layout.findIndex((d) => d.i === i); layout.splice(itemIndex, 1); this.setState({ layouts: { lg: [...layout] }, widgets: _.reject(this.state.widgets, { i: i }), }); this.SaveGrid(); }; addPanel = (newWidget: Widget) => { const widgetComponent = widgetComponents.find( (wc) => wc.type === newWidget.WidgetType ); const randomIndex = this.getRandomInt(100, 999); const newPanel = { i: "" + randomIndex, x: (this.state.widgets.length * 2) % 12, y: Infinity, w: 3, h: 5, minH: 5, minW: 3, }; this.state.widgets.push({ i: "" + randomIndex, title: newWidget.WidgetName, component: widgetComponent?.component, ...newWidget, }); this.setState({ layouts: { lg: this.state.layouts["lg"].concat(newPanel) }, widgets: this.state.widgets, }); }; SaveGrid() { this.saveToStorage("grid-layout", this.state.layouts); this.saveToStorage("grid-widgets", this.state.widgets); } hideDialog = () => {}; reset() { window.localStorage.clear(); window.location.reload(); } setToken() { const token = localStorage.getItem("token"); const newToken = prompt("Token: ", token || ""); if(newToken && newToken != '') localStorage.setItem("token", newToken || ""); } changeTitle(i) { let widget = this.state.widgets[i]; const newTitle = prompt("Title:"); widget.title = newTitle; this.setState(this.state.widgets); this.SaveGrid(); } selectedWidget; addComponent(componentType) { this.toggleDialog(); } onOkButton = (data: any) => { this.toggleDialog(); this.addPanel(data); }; onCancelButton = () => { this.toggleDialog(); }; saveToStorage = (key, value) => { this.setState({ showMsg: true, }); setTimeout(() => { this.setState({ showMsg: false }); }, 2000); window.localStorage.setItem(key, JSON.stringify(value)); }; getFromStorage = (key) => { const layout: any = window.localStorage.getItem(key); return JSON.parse(layout); }; FindWidget(el: any) { return this.state.widgets.find((d) => d.i === el.i); } toggleDialog() { this.setState({ displayDialog: !this.state.displayDialog }); } getRandomInt(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } renderNewWidgetDialog() { return ( ); } renderPageHeader() { return (

{this.state.dashboardTitle || "Dashboard"}

set token
reset
); } renderGridWidgetsPlaceholder() { return (
{[...Array(10)].map((e, i) => [...Array(DashboardDesigner.layoutGridProps.cols.lg)].map((e, i) => (
)) )}
); } renderLayoutGrid(layout: any) { return ( this.onLayoutChange(layout, layouts) } > {_.map(layout, (el) => this.renderWidgetComponent(el))} ); } renderWidgetComponent(el: any) { const widget = this.FindWidget(el); return (

{widget?.title || "not set"}

{React.createElement( this.widgetComponents.find((wc) => wc.type === widget.WidgetType) ?.component, { key: el.i, dateFilter: this.state.dateFilter, widget: widget } )}
); } render() { return ( <> {this.renderPageHeader()} this.setState({ dateFilter: e.value })} placeholder="filter by date..." >
{this.renderGridWidgetsPlaceholder()} {this.renderLayoutGrid(this.state.layouts["lg"])}
{this.renderNewWidgetDialog()} ); } } export default DashboardDesigner; const WidgetTypes = [ { Name: "Filter", Disabled: true }, { Name: "Chart", Disabled: false }, { Name: "Data Table", Disabled: true }, { Name: "Pivot Table", Disabled: true }, { Name: "KPI", Disabled: true }, { Name: "Gauge", Disabled: true }, ]; const widgetComponents = [ { type: "Bar", component: BarChartComponent }, { type: "Column", component: ColumnChartComponent }, { type: "Pie", component: PieChartComponent }, { type: "Mixed", component: MixedChartComponent }, { type: "Timeline", component: TimelineChartComponent }, { type: "Candle", component: CandleChartComponent }, { type: "Area", component: AreaChartComponent }, ];