Added dashboard framework. Components are not yet created nor is the query finalized. BOD-79

Missed in previous commit. BOD-79
This commit is contained in:
Patrick Fic
2020-07-14 15:21:38 -07:00
parent e91751e20c
commit 2eb8360f5d
28 changed files with 753 additions and 85 deletions

View File

@@ -1,64 +1,176 @@
import { Card } from "antd";
import Icon from "@ant-design/icons";
import { Button, Dropdown, Menu, notification } from "antd";
import React, { useState } from "react";
import { useMutation, useQuery } from "react-apollo";
import { Responsive, WidthProvider } from "react-grid-layout";
import styled from "styled-components";
import { useTranslation } from "react-i18next";
import { MdClose } from "react-icons/md";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import { UPDATE_DASHBOARD_LAYOUT } from "../../graphql/user.queries";
import { QUERY_DASHBOARD_DETAILS } from "../../graphql/bodyshop.queries";
import {
selectBodyshop,
selectCurrentUser,
} from "../../redux/user/user.selectors";
import DashboardMonthlyRevenueGraph from "../dashboard-components/monthly-revenue-graph/monthly-revenue-graph.component";
import DashboardProjectedMonthlySales from "../dashboard-components/pojected-monthly-sales/projected-monthly-sales.component";
import DashboardTotalProductionDollars from "../dashboard-components/total-production-dollars/total-production-dollars.component";
import DashboardTotalProductionHours 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.css";
const Sdiv = styled.div`
position: absolute;
height: 80%;
width: 80%;
top: 10%;
left: 10%;
// background-color: #ffcc00;
`;
import "./dashboard-grid.styles.scss";
const ResponsiveReactGridLayout = WidthProvider(Responsive);
export default function DashboardGridComponent() {
const mapStateToProps = createStructuredSelector({
currentUser: selectCurrentUser,
bodyshop: selectBodyshop,
});
const mapDispatchToProps = (dispatch) => ({
//setUserLanguage: language => dispatch(setUserLanguage(language))
});
export function DashboardGridComponent({ currentUser, bodyshop }) {
const { loading, error, data } = useQuery(QUERY_DASHBOARD_DETAILS);
const { t } = useTranslation();
const [state, setState] = useState({
layout: [
{ i: "1", x: 0, y: 0, w: 2, h: 2 },
{ i: "2", x: 2, y: 0, w: 2, h: 2 },
{ i: "3", x: 4, y: 0, w: 2, h: 2 }
]
layout: bodyshop.associations[0].user.dashboardlayout || [
{ i: "ProductionDollars", x: 0, y: 0, w: 2, h: 2 },
// { i: "ProductionHours", x: 2, y: 0, w: 2, h: 2 },
],
});
const [updateLayout] = useMutation(UPDATE_DASHBOARD_LAYOUT);
const defaultProps = {
className: "layout",
breakpoints: { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }
// cols: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 },
// rowHeight: 100
const handleLayoutChange = async (newLayout) => {
setState({ ...state, layout: newLayout });
const result = await updateLayout({
variables: { email: currentUser.email, layout: newLayout },
});
if (!!result.errors) {
notification["error"]({
message: t("dashboard.errors.updatinglayout", {
message: JSON.stringify(result.errors),
}),
});
}
};
const handleRemoveComponent = (key) => {
const idxToRemove = state.layout.findIndex((i) => i.i === key);
const newLayout = state.layout;
newLayout.splice(idxToRemove, 1);
console.log(newLayout);
handleLayoutChange(newLayout);
};
const handleAddComponent = (e) => {
handleLayoutChange([
...state.layout,
{
i: e.key,
x: (state.layout.length * 2) % (state.cols || 12),
y: Infinity, // puts it at the bottom
w: componentList[e.key].w || 2,
h: componentList[e.key].h || 2,
},
]);
};
// We're using the cols coming back from this to calculate where to add new items.
const onBreakpointChange = (breakpoint, cols) => {
console.log("breakpoint, cols", breakpoint, cols);
// setState({ ...state, breakpoint: breakpoint, cols: cols });
setState({ ...state, breakpoint: breakpoint, cols: cols });
};
if (true) return null;
const existingLayoutKeys = state.layout.map((i) => i.i);
const addComponentOverlay = (
<Menu onClick={handleAddComponent}>
{Object.keys(componentList).map((key) => (
<Menu.Item
key={key}
value={key}
disabled={existingLayoutKeys.includes(key)}
>
{componentList[key].label}
</Menu.Item>
))}
</Menu>
);
return (
<Sdiv>
The Grid.
<div>
<Dropdown overlay={addComponentOverlay} trigger={["click"]}>
<Button>{t("dashboard.actions.addcomponent")}</Button>
</Dropdown>
<ResponsiveReactGridLayout
{...defaultProps}
className="layout"
breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
width="100%"
onLayoutChange={handleLayoutChange}
onBreakpointChange={onBreakpointChange}
width='100%'
onLayoutChange={layout => {
console.log("layout", layout);
setState({ ...state, layout });
}}>
>
{state.layout.map((item, index) => {
const TheComponent = componentList[item.i].component;
return (
<Card style={{ width: "100px" }} key={item.i} data-grid={item}>
A Card {index}
</Card>
<div key={item.i} data-grid={item}>
<LoadingSkeleton loading={loading}>
<Icon
component={MdClose}
key={item.i}
style={{
position: "absolute",
zIndex: "2",
right: ".25rem",
top: ".25rem",
cursor: "pointer",
}}
onClick={() => handleRemoveComponent(item.i)}
/>
<TheComponent
className="dashboard-card"
size="small"
style={{ height: "100%", width: "100%" }}
/>
</LoadingSkeleton>
</div>
);
})}
</ResponsiveReactGridLayout>
</Sdiv>
</div>
);
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(DashboardGridComponent);
const componentList = {
ProductionDollars: {
label: "Production Dollars",
component: DashboardTotalProductionDollars,
w: 2,
h: 1,
},
ProductionHours: {
label: "Production Hours",
component: DashboardTotalProductionHours,
w: 2,
h: 1,
},
ProjectedMonthlySales: {
label: "Projected Monthly Sales",
component: DashboardProjectedMonthlySales,
w: 2,
h: 1,
},
MonthlyRevenueGraph: {
label: "Monthly Sales Graph",
component: DashboardMonthlyRevenueGraph,
w: 2,
h: 2,
},
};