import Icon, { SyncOutlined } from "@ant-design/icons"; import { gql, useMutation, useQuery } from "@apollo/client"; import { Button, Dropdown, Menu, notification, PageHeader, Space } from "antd"; import i18next from "i18next"; import _ from "lodash"; import moment from "moment"; import React, { useState } from "react"; import { Responsive, WidthProvider } from "react-grid-layout"; import { useTranslation } from "react-i18next"; import { MdClose } from "react-icons/md"; import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { logImEXEvent } from "../../firebase/firebase.utils"; import { UPDATE_DASHBOARD_LAYOUT } from "../../graphql/user.queries"; import { selectBodyshop, selectCurrentUser, } from "../../redux/user/user.selectors"; import AlertComponent from "../alert/alert.component"; import DashboardMonthlyEmployeeEfficiency, { DashboardMonthlyEmployeeEfficiencyGql, } from "../dashboard-components/monthly-employee-efficiency/monthly-employee-efficiency.component"; import DashboardMonthlyJobCosting from "../dashboard-components/monthly-job-costing/monthly-job-costing.component"; import DashboardMonthlyLaborSales from "../dashboard-components/monthly-labor-sales/monthly-labor-sales.component"; import DashboardMonthlyPartsSales from "../dashboard-components/monthly-parts-sales/monthly-parts-sales.component"; import DashboardMonthlyRevenueGraph, { DashboardMonthlyRevenueGraphGql, } from "../dashboard-components/monthly-revenue-graph/monthly-revenue-graph.component"; import DashboardProjectedMonthlySales, { DashboardProjectedMonthlySalesGql, } from "../dashboard-components/pojected-monthly-sales/projected-monthly-sales.component"; import DashboardTotalProductionDollars from "../dashboard-components/total-production-dollars/total-production-dollars.component"; import DashboardTotalProductionHours, { DashboardTotalProductionHoursGql, } from "../dashboard-components/total-production-hours/total-production-hours.component"; import LoadingSkeleton from "../loading-skeleton/loading-skeleton.component"; //Combination of the following: // /node_modules/react-grid-layout/css/styles.css // /node_modules/react-resizable/css/styles.css import "./dashboard-grid.styles.scss"; import { GenerateDashboardData } from "./dashboard-grid.utils"; const ResponsiveReactGridLayout = WidthProvider(Responsive); const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, bodyshop: selectBodyshop, }); const mapDispatchToProps = (dispatch) => ({ //setUserLanguage: language => dispatch(setUserLanguage(language)) }); export function DashboardGridComponent({ currentUser, bodyshop }) { const { t } = useTranslation(); const [state, setState] = useState({ ...(bodyshop.associations[0].user.dashboardlayout ? bodyshop.associations[0].user.dashboardlayout : { items: [], layout: {}, layouts: [] }), }); const { loading, error, data, refetch } = useQuery( createDashboardQuery(state), { fetchPolicy: "network-only", nextFetchPolicy: "network-only" } ); const [updateLayout] = useMutation(UPDATE_DASHBOARD_LAYOUT); const handleLayoutChange = async (layout, layouts) => { logImEXEvent("dashboard_change_layout"); setState({ ...state, layout, layouts }); const result = await updateLayout({ variables: { email: currentUser.email, layout: { ...state, layout, layouts }, }, }); if (!!result.errors) { notification["error"]({ message: t("dashboard.errors.updatinglayout", { message: JSON.stringify(result.errors), }), }); } }; const handleRemoveComponent = (key) => { logImEXEvent("dashboard_remove_component", { name: key }); const idxToRemove = state.items.findIndex((i) => i.i === key); const items = _.cloneDeep(state.items); items.splice(idxToRemove, 1); setState({ ...state, items }); }; const handleAddComponent = (e) => { logImEXEvent("dashboard_add_component", { name: e }); setState({ ...state, items: [ ...state.items, { i: e.key, x: (state.items.length * 2) % (state.cols || 12), y: 99, // puts it at the bottom w: componentList[e.key].w || 2, h: componentList[e.key].h || 2, }, ], }); }; const dashboarddata = React.useMemo( () => GenerateDashboardData(data), [data] ); const existingLayoutKeys = state.items.map((i) => i.i); const addComponentOverlay = (
); if (error) return