diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel index b42046c8c..3ee30f568 100644 --- a/bodyshop_translations.babel +++ b/bodyshop_translations.babel @@ -10647,6 +10647,69 @@ titles + + monthlyjobcosting + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + monthlylaborsales + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + + + monthlypartssales + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + monthlyrevenuegraph false @@ -10668,6 +10731,27 @@ + + prodhrssummary + false + + + + + + en-US + false + + + es-MX + false + + + fr-CA + false + + + productiondollars false diff --git a/client/src/components/dashboard-components/monthly-job-costing/monthly-job-costing.component.jsx b/client/src/components/dashboard-components/monthly-job-costing/monthly-job-costing.component.jsx new file mode 100644 index 000000000..dff539d19 --- /dev/null +++ b/client/src/components/dashboard-components/monthly-job-costing/monthly-job-costing.component.jsx @@ -0,0 +1,163 @@ +import { Card, Input, Space, Table, Typography } from "antd"; +import axios from "axios"; +import React, { useEffect, useState } from "react"; +import { useTranslation } from "react-i18next"; +import { alphaSort } from "../../../utils/sorters"; +import LoadingSkeleton from "../../loading-skeleton/loading-skeleton.component"; +import Dinero from "dinero.js"; +import DashboardRefreshRequired from "../refresh-required.component"; + +export default function DashboardMonthlyJobCosting({ data, ...cardProps }) { + const { t } = useTranslation(); + const [loading, setLoading] = useState(false); + const [costingData, setcostingData] = useState(null); + const [searchText, setSearchText] = useState(""); + const [state, setState] = useState({ + sortedInfo: {}, + }); + + useEffect(() => { + async function getCostingData() { + if (data && data.monthly_sales) { + setLoading(true); + const response = await axios.post("/job/costingmulti", { + jobids: data.monthly_sales.map((x) => x.id), + }); + setcostingData(response.data); + setLoading(false); + } + } + + getCostingData(); + }, [data]); + + if (!data) return null; + if (!data.monthly_sales) return ; + const handleTableChange = (pagination, filters, sorter) => { + setState({ ...state, filteredInfo: filters, sortedInfo: sorter }); + }; + const columns = [ + { + title: t("bodyshop.fields.responsibilitycenter"), + dataIndex: "cost_center", + key: "cost_center", + sorter: (a, b) => alphaSort(a.cost_center, b.cost_center), + sortOrder: + state.sortedInfo.columnKey === "cost_center" && state.sortedInfo.order, + }, + { + title: t("jobs.labels.sales"), + dataIndex: "sales", + key: "sales", + sorter: (a, b) => + parseFloat(a.sales.substring(1)) - parseFloat(b.sales.substring(1)), + sortOrder: + state.sortedInfo.columnKey === "sales" && state.sortedInfo.order, + }, + + { + title: t("jobs.labels.costs"), + dataIndex: "costs", + key: "costs", + sorter: (a, b) => + parseFloat(a.costs.substring(1)) - parseFloat(b.costs.substring(1)), + sortOrder: + state.sortedInfo.columnKey === "costs" && state.sortedInfo.order, + }, + + { + title: t("jobs.labels.gpdollars"), + dataIndex: "gpdollars", + key: "gpdollars", + sorter: (a, b) => + parseFloat(a.gpdollars.substring(1)) - + parseFloat(b.gpdollars.substring(1)), + + sortOrder: + state.sortedInfo.columnKey === "gpdollars" && state.sortedInfo.order, + }, + { + title: t("jobs.labels.gppercent"), + dataIndex: "gppercent", + key: "gppercent", + sorter: (a, b) => + parseFloat(a.gppercent.slice(0, -1) || 0) - + parseFloat(b.gppercent.slice(0, -1) || 0), + sortOrder: + state.sortedInfo.columnKey === "gppercent" && state.sortedInfo.order, + }, + ]; + const filteredData = + searchText === "" + ? (costingData && costingData.allCostCenterData) || [] + : costingData.allCostCenterData.filter((d) => + (d.cost_center || "") + .toString() + .toLowerCase() + .includes(searchText.toLowerCase()) + ); + + return ( + + { + e.preventDefault(); + setSearchText(e.target.value); + }} + /> + + } + {...cardProps} + > + +
+ ( + + + + {t("general.labels.totals")} + + + + {Dinero( + costingData && + costingData.allSummaryData && + costingData.allSummaryData.totalSales + ).toFormat()} + + + {Dinero( + costingData && + costingData.allSummaryData && + costingData.allSummaryData.totalCost + ).toFormat()} + + + {Dinero( + costingData && + costingData.allSummaryData && + costingData.allSummaryData.gpdollars + ).toFormat()} + + + + )} + /> + + + + ); +} diff --git a/client/src/components/dashboard-components/monthly-labor-sales/monthly-labor-sales.component.jsx b/client/src/components/dashboard-components/monthly-labor-sales/monthly-labor-sales.component.jsx new file mode 100644 index 000000000..c47afbe1f --- /dev/null +++ b/client/src/components/dashboard-components/monthly-labor-sales/monthly-labor-sales.component.jsx @@ -0,0 +1,148 @@ +import { Card } from "antd"; +import Dinero from "dinero.js"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Cell, Pie, PieChart, ResponsiveContainer, Sector } from "recharts"; +import DashboardRefreshRequired from "../refresh-required.component"; + +export default function DashboardMonthlyLaborSales({ data, ...cardProps }) { + const { t } = useTranslation(); + const [activeIndex, setActiveIndex] = useState(0); + if (!data) return null; + if (!data.monthly_sales) return ; + + const laborData = {}; + + data.monthly_sales.forEach((job) => { + job.joblines.forEach((jobline) => { + if (!jobline.mod_lbr_ty) return; + if (!laborData[jobline.mod_lbr_ty]) + laborData[jobline.mod_lbr_ty] = Dinero(); + laborData[jobline.mod_lbr_ty] = laborData[jobline.mod_lbr_ty].add( + Dinero({ + amount: Math.round( + (job[`rate_${jobline.mod_lbr_ty.toLowerCase()}`] || 0) * 100 + ), + }).multiply(jobline.mod_lb_hrs || 0) + ); + }); + }); + + const chartData = Object.keys(laborData).map((key) => { + return { + name: t(`joblines.fields.lbr_types.${key.toUpperCase()}`), + value: laborData[key].getAmount() / 100, + // color: pieColor(i.status), + }; + }); + console.log( + "🚀 ~ file: monthly-parts-sales.component.jsx ~ line 34 ~ chartData", + chartData + ); + + return ( + +
+ + + setActiveIndex(index)} + > + {chartData.map((entry, index) => ( + + ))} + + + +
+
+ ); +} + +export const DashboardMonthlyRevenueGraphGql = ` + +`; + +const renderActiveShape = (props) => { + const RADIAN = Math.PI / 180; + const { + cx, + cy, + midAngle, + innerRadius, + outerRadius, + startAngle, + endAngle, + fill, + payload, + percent, + value, + } = props; + const sin = Math.sin(-RADIAN * midAngle); + const cos = Math.cos(-RADIAN * midAngle); + const sx = cx + (outerRadius + 10) * cos; + const sy = cy + (outerRadius + 10) * sin; + const mx = cx + (outerRadius + 30) * cos; + const my = cy + (outerRadius + 30) * sin; + const ex = mx + (cos >= 0 ? 1 : -1) * 22; + const ey = my; + const textAnchor = cos >= 0 ? "start" : "end"; + + return ( + + + {payload.name} + + + + + + = 0 ? 1 : -1) * 12} + y={ey} + textAnchor={textAnchor} + fill="#333" + > + {payload.name} + + = 0 ? 1 : -1) * 12} + y={ey} + dy={18} + textAnchor={textAnchor} + fill="#999" + > + {Dinero({ amount: Math.round(value * 100) }).toFormat()} + + + ); +}; diff --git a/client/src/components/dashboard-components/monthly-parts-sales/monthly-parts-sales.component.jsx b/client/src/components/dashboard-components/monthly-parts-sales/monthly-parts-sales.component.jsx new file mode 100644 index 000000000..9f651c009 --- /dev/null +++ b/client/src/components/dashboard-components/monthly-parts-sales/monthly-parts-sales.component.jsx @@ -0,0 +1,145 @@ +import { Card } from "antd"; +import Dinero from "dinero.js"; +import React, { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { Cell, Pie, PieChart, ResponsiveContainer, Sector } from "recharts"; +import DashboardRefreshRequired from "../refresh-required.component"; + +export default function DashboardMonthlyPartsSales({ data, ...cardProps }) { + const { t } = useTranslation(); + const [activeIndex, setActiveIndex] = useState(0); + if (!data) return null; + if (!data.monthly_sales) return ; + + const partData = {}; + + data.monthly_sales.forEach((job) => { + job.joblines.forEach((jobline) => { + if (!jobline.part_type) return; + if (!partData[jobline.part_type]) partData[jobline.part_type] = Dinero(); + partData[jobline.part_type] = partData[jobline.part_type].add( + Dinero({ amount: Math.round((jobline.act_price || 0) * 100) }).multiply( + jobline.part_qty || 0 + ) + ); + }); + }); + + const chartData = Object.keys(partData).map((key) => { + return { + name: t(`joblines.fields.part_types.${key.toUpperCase()}`), + value: partData[key].getAmount() / 100, + // color: pieColor(i.status), + }; + }); + console.log( + "🚀 ~ file: monthly-parts-sales.component.jsx ~ line 34 ~ chartData", + chartData + ); + + return ( + +
+ + + setActiveIndex(index)} + > + {chartData.map((entry, index) => ( + + ))} + + + +
+
+ ); +} + +export const DashboardMonthlyRevenueGraphGql = ` + +`; + +const renderActiveShape = (props) => { + const RADIAN = Math.PI / 180; + const { + cx, + cy, + midAngle, + innerRadius, + outerRadius, + startAngle, + endAngle, + fill, + payload, + percent, + value, + } = props; + const sin = Math.sin(-RADIAN * midAngle); + const cos = Math.cos(-RADIAN * midAngle); + const sx = cx + (outerRadius + 10) * cos; + const sy = cy + (outerRadius + 10) * sin; + const mx = cx + (outerRadius + 30) * cos; + const my = cy + (outerRadius + 30) * sin; + const ex = mx + (cos >= 0 ? 1 : -1) * 22; + const ey = my; + const textAnchor = cos >= 0 ? "start" : "end"; + + return ( + + + {payload.name} + + + + + + = 0 ? 1 : -1) * 12} + y={ey} + textAnchor={textAnchor} + fill="#333" + > + {payload.name} + + = 0 ? 1 : -1) * 12} + y={ey} + dy={18} + textAnchor={textAnchor} + fill="#999" + > + {Dinero({ amount: Math.round(value * 100) }).toFormat()} + + + ); +}; diff --git a/client/src/components/dashboard-components/monthly-revenue-graph/monthly-revenue-graph.component.jsx b/client/src/components/dashboard-components/monthly-revenue-graph/monthly-revenue-graph.component.jsx index 1cac27110..4cc24d59c 100644 --- a/client/src/components/dashboard-components/monthly-revenue-graph/monthly-revenue-graph.component.jsx +++ b/client/src/components/dashboard-components/monthly-revenue-graph/monthly-revenue-graph.component.jsx @@ -16,18 +16,16 @@ import { } from "recharts"; import Dinero from "dinero.js"; import * as Utils from "../../scoreboard-targets-table/scoreboard-targets-table.util"; +import DashboardRefreshRequired from "../refresh-required.component"; export default function DashboardMonthlyRevenueGraph({ data, ...cardProps }) { const { t } = useTranslation(); if (!data) return null; + if (!data.monthly_sales) return ; const jobsByDate = _.groupBy(data.monthly_sales, (item) => moment(item.date_invoiced).format("YYYY-MM-DD") ); - console.log( - "🚀 ~ file: monthly-revenue-graph.component.jsx ~ line 27 ~ jobsByDate", - jobsByDate - ); const listOfDays = Utils.ListOfDaysInCurrentMonth(); @@ -56,44 +54,38 @@ export default function DashboardMonthlyRevenueGraph({ data, ...cardProps }) { return ( - - - - - - - - - - - +
+ + + + + + + + + + + +
); } export const DashboardMonthlyRevenueGraphGql = ` - monthly_sales: jobs(where: {_and: [{date_invoiced: {_gte: "${moment() - .startOf("month") - .format("YYYY-MM-DD")}"}}, {date_invoiced: {_lte: "${moment() - .endOf("month") - .format("YYYY-MM-DD")}"}}]}) { - id - date_invoiced - job_totals - } + `; diff --git a/client/src/components/dashboard-components/pojected-monthly-sales/projected-monthly-sales.component.jsx b/client/src/components/dashboard-components/pojected-monthly-sales/projected-monthly-sales.component.jsx index 65d3f8edc..e8c26daec 100644 --- a/client/src/components/dashboard-components/pojected-monthly-sales/projected-monthly-sales.component.jsx +++ b/client/src/components/dashboard-components/pojected-monthly-sales/projected-monthly-sales.component.jsx @@ -1,30 +1,40 @@ -import { ArrowDownOutlined, ArrowUpOutlined } from "@ant-design/icons"; import { Card, Statistic } from "antd"; +import Dinero from "dinero.js"; +import moment from "moment"; import React from "react"; import { useTranslation } from "react-i18next"; - +import DashboardRefreshRequired from "../refresh-required.component"; export default function DashboardProjectedMonthlySales({ data, ...cardProps }) { const { t } = useTranslation(); - const aboveTargetMonthlySales = false; + if (!data) return null; + if (!data.projected_monthly_sales) + return ; + const dollars = + data.projected_monthly_sales && + data.projected_monthly_sales.reduce( + (acc, val) => acc.add(Dinero(val.job_totals.totals.subtotal)), + Dinero() + ); return ( - - - {aboveTargetMonthlySales ? ( - - ) : ( - - )} - $ - - } - valueStyle={{ color: aboveTargetMonthlySales ? "green" : "red" }} - /> + + ); } + +export const DashboardProjectedMonthlySalesGql = ` + projected_monthly_sales: jobs(where: {_or: [{_and: [{date_invoiced: {_gte: "${moment() + .startOf("month") + .format("YYYY-MM-DD")}"}}, {date_invoiced: {_lte: "${moment() + .endOf("month") + .format("YYYY-MM-DD")}"}}]}, {_and: [{scheduled_completion: {_gte: "${moment() + .startOf("month") + .format("YYYY-MM-DD")}"}}, {scheduled_completion: {_lte: "${moment() + .endOf("month") + .format("YYYY-MM-DD")}"}}]}]}) { + id + date_invoiced + job_totals + } +`; diff --git a/client/src/components/dashboard-components/refresh-required.component.jsx b/client/src/components/dashboard-components/refresh-required.component.jsx new file mode 100644 index 000000000..6a9289724 --- /dev/null +++ b/client/src/components/dashboard-components/refresh-required.component.jsx @@ -0,0 +1,25 @@ +import { Card, Typography } from "antd"; +import { SyncOutlined } from "@ant-design/icons"; + +import React from "react"; +import { useTranslation } from "react-i18next"; +export default function DashboardRefreshRequired(props) { + const { t } = useTranslation(); + + return ( + +
+ + + {t("dashboard.errors.refreshrequired")} + +
+
+ ); +} diff --git a/client/src/components/dashboard-components/total-production-dollars/total-production-dollars.component.jsx b/client/src/components/dashboard-components/total-production-dollars/total-production-dollars.component.jsx index cab5b891d..2d1c29c97 100644 --- a/client/src/components/dashboard-components/total-production-dollars/total-production-dollars.component.jsx +++ b/client/src/components/dashboard-components/total-production-dollars/total-production-dollars.component.jsx @@ -2,6 +2,7 @@ import { Card, Statistic } from "antd"; import Dinero from "dinero.js"; import React from "react"; import { useTranslation } from "react-i18next"; +import DashboardRefreshRequired from "../refresh-required.component"; export default function DashboardTotalProductionDollars({ data, @@ -9,18 +10,17 @@ export default function DashboardTotalProductionDollars({ }) { const { t } = useTranslation(); if (!data) return null; - - const dollars = data.production_jobs.reduce( - (acc, val) => acc.add(Dinero(val.job_totals.totals.subtotal)), - Dinero() - ); + if (!data.production_jobs) return ; + const dollars = + data.production_jobs && + data.production_jobs.reduce( + (acc, val) => acc.add(Dinero(val.job_totals.totals.subtotal)), + Dinero() + ); return ( - - + + ); } diff --git a/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx b/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx index b72b1304f..81a852400 100644 --- a/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx +++ b/client/src/components/dashboard-components/total-production-hours/total-production-hours.component.jsx @@ -1,11 +1,11 @@ -import React from "react"; import { Card, Space, Statistic } from "antd"; +import React from "react"; import { useTranslation } from "react-i18next"; -import { ArrowDownOutlined, ArrowUpOutlined } from "@ant-design/icons"; - import { connect } from "react-redux"; import { createStructuredSelector } from "reselect"; import { selectBodyshop } from "../../../redux/user/user.selectors"; +import DashboardRefreshRequired from "../refresh-required.component"; + const mapStateToProps = createStructuredSelector({ bodyshop: selectBodyshop, }); @@ -22,22 +22,25 @@ export function DashboardTotalProductionHours({ }) { const { t } = useTranslation(); if (!data) return null; - const hours = data.production_jobs.reduce( - (acc, val) => { - return { - body: acc.body + val.labhrs.aggregate.sum.mod_lb_hrs, - ref: acc.ref + val.larhrs.aggregate.sum.mod_lb_hrs, - total: - acc.total + - val.labhrs.aggregate.sum.mod_lb_hrs + - val.larhrs.aggregate.sum.mod_lb_hrs, - }; - }, - { body: 0, ref: 0, total: 0 } - ); + if (!data.production_jobs) return ; + const hours = + data.production_jobs && + data.production_jobs.reduce( + (acc, val) => { + return { + body: acc.body + val.labhrs.aggregate.sum.mod_lb_hrs, + ref: acc.ref + val.larhrs.aggregate.sum.mod_lb_hrs, + total: + acc.total + + val.labhrs.aggregate.sum.mod_lb_hrs + + val.larhrs.aggregate.sum.mod_lb_hrs, + }; + }, + { body: 0, ref: 0, total: 0 } + ); const aboveTargetHours = hours.total >= bodyshop.prodtargethrs; return ( - + diff --git a/client/src/components/dashboard-grid/dashboard-grid.component.jsx b/client/src/components/dashboard-grid/dashboard-grid.component.jsx index 5692a7588..910913168 100644 --- a/client/src/components/dashboard-grid/dashboard-grid.component.jsx +++ b/client/src/components/dashboard-grid/dashboard-grid.component.jsx @@ -1,6 +1,8 @@ import Icon, { SyncOutlined } from "@ant-design/icons"; import { gql, useMutation, useQuery } from "@apollo/client"; import { Button, Dropdown, Menu, notification, PageHeader, Space } from "antd"; +import _ from "lodash"; +import moment from "moment"; import React, { useState } from "react"; import { Responsive, WidthProvider } from "react-grid-layout"; import { useTranslation } from "react-i18next"; @@ -14,10 +16,15 @@ import { selectCurrentUser, } from "../../redux/user/user.selectors"; import AlertComponent from "../alert/alert.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 from "../dashboard-components/pojected-monthly-sales/projected-monthly-sales.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, @@ -44,8 +51,9 @@ export function DashboardGridComponent({ currentUser, bodyshop }) { const [state, setState] = useState({ ...(bodyshop.associations[0].user.dashboardlayout ? bodyshop.associations[0].user.dashboardlayout - : { items: [], layout: [], layouts: [] }), + : { items: [], layout: {}, layouts: [] }), }); + const { loading, error, data, refetch } = useQuery( createDashboardQuery(state) ); @@ -74,7 +82,12 @@ export function DashboardGridComponent({ currentUser, bodyshop }) { const handleRemoveComponent = (key) => { logImEXEvent("dashboard_remove_component", { name: key }); const idxToRemove = state.items.findIndex((i) => i.i === key); - const items = state.items; + console.log( + "🚀 ~ file: dashboard-grid.component.jsx ~ line 81 ~ idxToRemove", + idxToRemove + ); + const items = _.cloneDeep(state.items); + items.splice(idxToRemove, 1); setState({ ...state, items }); }; @@ -88,7 +101,7 @@ export function DashboardGridComponent({ currentUser, bodyshop }) { { i: e.key, x: (state.items.length * 2) % (state.cols || 12), - y: Infinity, // puts it at the bottom + y: 99, // puts it at the bottom w: componentList[e.key].w || 2, h: componentList[e.key].h || 2, }, @@ -100,11 +113,6 @@ export function DashboardGridComponent({ currentUser, bodyshop }) { () => GenerateDashboardData(data), [data] ); - - // const onBreakpointChange = (breakpoint, cols) => { - // setState({ ...state, breakpoint: breakpoint, cols: cols }); - // }; - const existingLayoutKeys = state.items.map((i) => i.i); const addComponentOverlay = ( @@ -149,7 +157,14 @@ export function DashboardGridComponent({ currentUser, bodyshop }) { {state.items.map((item, index) => { const TheComponent = componentList[item.i].component; return ( -
+
{ return gql` query QUERY_DASHBOARD_DETAILS { ${componentBasedAdditions} + monthly_sales: jobs(where: {_and: [{date_invoiced: {_gte: "${moment() + .startOf("month") + .format("YYYY-MM-DD")}"}}, {date_invoiced: {_lte: "${moment() + .endOf("month") + .format("YYYY-MM-DD")}"}}]}) { + id + date_invoiced + job_totals + rate_la1 + rate_la2 + rate_la3 + rate_la4 + rate_laa + rate_lab + rate_lad + rate_lae + rate_laf + rate_lag + rate_lam + rate_lar + rate_las + rate_lau + rate_ma2s + rate_ma2t + rate_ma3s + rate_mabl + rate_macs + rate_mahw + rate_mapa + rate_mash + rate_matd + joblines(where: { removed: { _eq: false } }) { + id + mod_lbr_ty + mod_lb_hrs + act_price + part_qty + part_type + } + } production_jobs: jobs(where: { inproduction: { _eq: true } }) { id ro_number diff --git a/client/src/components/dashboard-grid/dashboard-grid.styles.scss b/client/src/components/dashboard-grid/dashboard-grid.styles.scss index 9f831ff1c..62a3ae72b 100644 --- a/client/src/components/dashboard-grid/dashboard-grid.styles.scss +++ b/client/src/components/dashboard-grid/dashboard-grid.styles.scss @@ -127,13 +127,28 @@ .dashboard-card { height: 100%; width: 100%; - .ant-card-body { - // background-color: red; - height: 90%; + height: 80%; width: 100%; - display: flex; - flex-direction: column; - align-items: center; + // // background-color: red; + // height: 90%; + // width: 100%; + // padding: 8px; + // display: flex; + // flex-direction: column; + // align-items: center; + // justify-content: center; + } + .ant-spin-nested-loading { + height: 100%; + .ant-spin-container { + height: 100%; + .ant-table { + height: 100%; + .ant-table-container { + height: 100%; + } + } + } } } diff --git a/client/src/components/header/header.component.jsx b/client/src/components/header/header.component.jsx index c7467c60a..2c3887891 100644 --- a/client/src/components/header/header.component.jsx +++ b/client/src/components/header/header.component.jsx @@ -3,6 +3,7 @@ import Icon, { BarChartOutlined, CarFilled, ClockCircleFilled, + DashboardFilled, DollarCircleFilled, ExportOutlined, FieldTimeOutlined, @@ -18,7 +19,6 @@ import Icon, { ScheduleOutlined, SettingOutlined, TeamOutlined, - DashboardFilled, ToolFilled, UnorderedListOutlined, UserOutlined, @@ -46,7 +46,6 @@ import { import { setModalContext } from "../../redux/modals/modals.actions"; import { signOutStart } from "../../redux/user/user.actions"; import { selectCurrentUser } from "../../redux/user/user.selectors"; -import GlobalSearch from "../global-search/global-search.component"; const mapStateToProps = createStructuredSelector({ currentUser: selectCurrentUser, diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json index e66a95d4a..1eb0ae3c6 100644 --- a/client/src/translations/en_us/common.json +++ b/client/src/translations/en_us/common.json @@ -672,12 +672,16 @@ }, "labels": { "bodyhrs": "Body Hrs", - "dollarsinproduction": "Dollars in Production", + "dollarsinproduction": "Dollars in Production'", "prodhrs": "Production Hrs", "refhrs": "Refinish Hrs" }, "titles": { + "monthlyjobcosting": "Monthly Job Costing ", + "monthlylaborsales": "Monthly Labor Sales", + "monthlypartssales": "Monthly Parts Sales", "monthlyrevenuegraph": "Monthly Revenue Graph", + "prodhrssummary": "Production Hours Summary", "productiondollars": "Total dollars in production", "productionhours": "Total hours in production", "projectedmonthlysales": "Projected Monthly Sales" diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json index a92dffe59..6cbc97daa 100644 --- a/client/src/translations/es/common.json +++ b/client/src/translations/es/common.json @@ -677,7 +677,11 @@ "refhrs": "" }, "titles": { + "monthlyjobcosting": "", + "monthlylaborsales": "", + "monthlypartssales": "", "monthlyrevenuegraph": "", + "prodhrssummary": "", "productiondollars": "", "productionhours": "", "projectedmonthlysales": "" diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json index b1e8b255a..f9b208bd5 100644 --- a/client/src/translations/fr/common.json +++ b/client/src/translations/fr/common.json @@ -677,7 +677,11 @@ "refhrs": "" }, "titles": { + "monthlyjobcosting": "", + "monthlylaborsales": "", + "monthlypartssales": "", "monthlyrevenuegraph": "", + "prodhrssummary": "", "productiondollars": "", "productionhours": "", "projectedmonthlysales": ""