diff --git a/bodyshop_translations.babel b/bodyshop_translations.babel
index a6b7d0456..22823dc7c 100644
--- a/bodyshop_translations.babel
+++ b/bodyshop_translations.babel
@@ -40827,6 +40827,69 @@
+
+ jobs
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ lastmonth
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ lastweek
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
monthlytarget
false
@@ -40848,6 +40911,48 @@
+
+ productivestatistics
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ productivetimeticketsoverdate
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
targets
false
@@ -40869,6 +40974,69 @@
+
+ thismonth
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ thisweek
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
+
+ timetickets
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
todateactual
false
@@ -40890,6 +41058,27 @@
+
+ totaloverperiod
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ es-MX
+ false
+
+
+ fr-CA
+ false
+
+
+
weeklyactual
false
diff --git a/client/src/components/scoreboard-targets-table/scoreboard-targets-table.util.js b/client/src/components/scoreboard-targets-table/scoreboard-targets-table.util.js
index 2b9c0b3f7..9f925a1a3 100644
--- a/client/src/components/scoreboard-targets-table/scoreboard-targets-table.util.js
+++ b/client/src/components/scoreboard-targets-table/scoreboard-targets-table.util.js
@@ -49,11 +49,6 @@ export const ListOfDaysInCurrentMonth = () => {
};
export const ListDaysBetween = ({ start, end }) => {
- console.log(
- "🚀 ~ file: scoreboard-targets-table.util.js ~ line 52 ~ start, end",
- start,
- end
- );
const days = [];
const dateStart = moment(start);
const dateEnd = moment(end);
diff --git a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.bar.component.jsx b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.bar.component.jsx
index 427766d3b..063638a47 100644
--- a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.bar.component.jsx
+++ b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.bar.component.jsx
@@ -1,14 +1,12 @@
import { Card } from "antd";
-import moment from "moment";
-import React, { useMemo } from "react";
+import React from "react";
+import { useTranslation } from "react-i18next";
import { connect } from "react-redux";
import {
- Area,
Bar,
CartesianGrid,
ComposedChart,
Legend,
- Line,
ResponsiveContainer,
Tooltip,
XAxis,
@@ -16,9 +14,7 @@ import {
} from "recharts";
import { createStructuredSelector } from "reselect";
import { selectBodyshop } from "../../redux/user/user.selectors";
-import * as Utils from "../scoreboard-targets-table/scoreboard-targets-table.util";
-import _ from "lodash";
-
+import TimeTicketsDatesSelector from "../ticket-tickets-dates-selector/time-tickets-dates-selector.component";
const graphProps = {
strokeWidth: 3,
};
@@ -35,86 +31,16 @@ export default connect(
mapDispatchToProps
)(ScoreboardTicketsBar);
-export function ScoreboardTicketsBar({ start, end, timetickets, bodyshop }) {
- console.log(
- "🚀 ~ file: scoreboard-timetickets.bar.component.jsx ~ line 39 ~ start, end,",
- start,
- end
- );
- const listOfBusDays = Utils.ListOfDaysInCurrentMonth();
-
- const data = useMemo(() => {
- const ticketsGroupedByDate = _.groupBy(timetickets, "date");
-
- const listOfDays = Utils.ListDaysBetween({ start, end });
- console.log(
- "🚀 ~ file: scoreboard-timetickets.bar.component.jsx ~ line 45 ~ listOfDays",
- listOfDays
- );
-
- console.log(
- "🚀 ~ file: scoreboard-timetickets.bar.component.jsx ~ line 43 ~ groupedByDate",
- ticketsGroupedByDate
- );
-
- const ret = [];
- listOfDays.forEach((day) => {
- const r = {
- date: day,
- total: 0,
- };
- });
- }, [timetickets]);
- // const data = listOfBusDays.reduce((acc, val) => {
- // //Sum up the current day.
-
- // const groupedbyDate = _.groupBy(data, "date");
- // let dayhrs;
- // if (!!sbEntriesByDate[val]) {
- // dayhrs = sbEntriesByDate[val].reduce(
- // (dayAcc, dayVal) => {
- // return {
- // bodyhrs: dayAcc.bodyhrs + dayVal.bodyhrs,
- // painthrs: dayAcc.painthrs + dayVal.painthrs,
- // };
- // },
- // { bodyhrs: 0, painthrs: 0 }
- // );
- // } else {
- // dayhrs = {
- // bodyhrs: 0,
- // painthrs: 0,
- // };
- // }
-
- // const theValue = {
- // date: moment(val).format("D ddd"),
- // paintHrs: _.round(dayhrs.painthrs, 1),
- // bodyHrs: _.round(dayhrs.bodyhrs, 1),
- // accTargetHrs: _.round(
- // Utils.AsOfDateTargetHours(
- // bodyshop.scoreboard_target.dailyBodyTarget +
- // bodyshop.scoreboard_target.dailyPaintTarget,
- // val
- // ),
- // 1
- // ),
- // accHrs: _.round(
- // acc.length > 0
- // ? acc[acc.length - 1].accHrs + dayhrs.painthrs + dayhrs.bodyhrs
- // : dayhrs.painthrs + dayhrs.bodyhrs,
- // 1
- // ),
- // };
-
- // return [...acc, theValue];
- // }, []);
-
+export function ScoreboardTicketsBar({ data, bodyshop }) {
+ const { t } = useTranslation();
return (
-
+ }
+ >
@@ -122,34 +48,32 @@ export function ScoreboardTicketsBar({ start, end, timetickets, bodyshop }) {
-
-
-
- */}
+ {data &&
+ data.employees.map((e, idx) => (
+
+ ))}
+
+ {/*
+ /> */}
diff --git a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx
index fae8f4379..f85982359 100644
--- a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx
+++ b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.component.jsx
@@ -1,12 +1,16 @@
-import React from "react";
-import { useLocation } from "react-router-dom";
-import queryString from "query-string";
-import moment from "moment";
import { useQuery } from "@apollo/client";
+import { Col, Row } from "antd";
+import _ from "lodash";
+import moment from "moment";
+import queryString from "query-string";
+import React, { useMemo } from "react";
+import { useLocation } from "react-router-dom";
import { QUERY_TIME_TICKETS_IN_RANGE } from "../../graphql/timetickets.queries";
import AlertComponent from "../alert/alert.component";
-import TimeTicketsDatesSelector from "../../components/ticket-tickets-dates-selector/time-tickets-dates-selector.component";
+import LoadingSpinner from "../loading-spinner/loading-spinner.component";
+import * as Utils from "../scoreboard-targets-table/scoreboard-targets-table.util";
import ScoreboardTicketsBar from "./scoreboard-timetickets.bar.component";
+import ScoreboardTicketsStats from "./scoreboard-timetickets.stats.component";
export default function ScoreboardTimeTickets() {
const searchParams = queryString.parse(useLocation().search);
@@ -15,25 +19,230 @@ export default function ScoreboardTimeTickets() {
? moment(start)
: moment().startOf("week").subtract(7, "days");
const endDate = end ? moment(end) : moment().endOf("week");
+
+ const fixedPeriods = useMemo(() => {
+ const endOfThisMonth = moment().endOf("month");
+ const startofthisMonth = moment().startOf("month");
+
+ const endOfLastmonth = moment().subtract(1, "month").endOf("month");
+ const startOfLastmonth = moment().subtract(1, "month").startOf("month");
+
+ const endOfThisWeek = moment().endOf("week");
+ const startOfThisWeek = moment().startOf("week");
+
+ const endOfLastWeek = moment().subtract(1, "week").endOf("week");
+ const startOfLastWeek = moment().subtract(1, "week").startOf("week");
+
+ const allDates = [
+ endOfThisMonth,
+ startofthisMonth,
+ endOfLastmonth,
+ startOfLastmonth,
+ endOfThisWeek,
+ startOfThisWeek,
+ endOfLastWeek,
+ startOfLastWeek,
+ ];
+ const start = moment.min(allDates);
+ const end = moment.max(allDates);
+ return {
+ start,
+ end,
+ endOfThisMonth,
+ startofthisMonth,
+ endOfLastmonth,
+ startOfLastmonth,
+ endOfThisWeek,
+ startOfThisWeek,
+ endOfLastWeek,
+ startOfLastWeek,
+ };
+ }, []);
+
const { loading, error, data } = useQuery(QUERY_TIME_TICKETS_IN_RANGE, {
variables: {
- start: startDate,
- end: endDate,
+ start: startDate.format("YYYY-MM-DD"),
+ end: endDate.format("YYYY-MM-DD"),
+ fixedStart: fixedPeriods.start.format("YYYY-MM-DD"),
+ fixedEnd: fixedPeriods.end.format("YYYY-MM-DD"),
},
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
+ pollInterval: 60000,
+ skip: !fixedPeriods,
});
- if (error) return ;
+ const calculatedData = useMemo(() => {
+ if (!data) return [];
+ const ret = {
+ totalThisWeek: 0,
+ totalLastWeek: 0,
+ totalThisMonth: 0,
+ totalLastMonth: 0,
+ totalOverPeriod: 0,
+ employees: {},
+ };
+ data.fixedperiod.forEach((ticket) => {
+ const ticketDate = moment(ticket.date);
+
+ if (!ret.employees[ticket.employee.employee_number]) {
+ ret.employees[ticket.employee.employee_number] = {
+ totalThisWeek: 0,
+ totalLastWeek: 0,
+ totalThisMonth: 0,
+ totalLastMonth: 0,
+ totalOverPeriod: 0,
+ };
+ }
+
+ if (
+ ticketDate.isBetween(
+ fixedPeriods.startOfThisWeek,
+ fixedPeriods.endOfThisWeek,
+ undefined,
+ "[]"
+ )
+ ) {
+ ret.totalThisWeek = ret.totalThisWeek + ticket.productivehrs;
+ ret.employees[ticket.employee.employee_number].totalThisWeek =
+ ret.employees[ticket.employee.employee_number].totalThisWeek +
+ ticket.productivehrs;
+ } else if (
+ ticketDate.isBetween(
+ fixedPeriods.startOfLastWeek,
+ fixedPeriods.endOfLastWeek,
+ undefined,
+ "[]"
+ )
+ ) {
+ ret.totalLastWeek = ret.totalLastWeek + ticket.productivehrs;
+ ret.employees[ticket.employee.employee_number].totalLastWeek =
+ ret.employees[ticket.employee.employee_number].totalLastWeek +
+ ticket.productivehrs;
+ }
+ if (
+ ticketDate.isBetween(
+ fixedPeriods.startofthisMonth,
+ fixedPeriods.endOfThisMonth,
+ undefined,
+ "[]"
+ )
+ ) {
+ ret.totalThisMonth = ret.totalThisMonth + ticket.productivehrs;
+ ret.employees[ticket.employee.employee_number].totalThisMonth =
+ ret.employees[ticket.employee.employee_number].totalThisMonth +
+ ticket.productivehrs;
+ } else if (
+ ticketDate.isBetween(
+ fixedPeriods.startOfLastmonth,
+ fixedPeriods.endOfLastmonth,
+ undefined,
+ "[]"
+ )
+ ) {
+ ret.totalLastMonth = ret.totalLastMonth + ticket.productivehrs;
+ ret.employees[ticket.employee.employee_number].totalLastMonth =
+ ret.employees[ticket.employee.employee_number].totalLastMonth +
+ ticket.productivehrs;
+ }
+ });
+
+ const ticketsGroupedByDate = _.groupBy(data.timetickets, "date");
+ const listOfDays = Utils.ListDaysBetween({
+ start: startDate,
+ end: endDate,
+ });
+
+ const employees = [];
+ const ret2 = [];
+ let totals = {
+ totalproductive: 0,
+ totalactual: 0,
+ employees: {},
+ };
+
+ listOfDays.forEach((day) => {
+ const r = {
+ date: moment(day).format("MM/DD"),
+ actualtotal: 0,
+ productivetotal: 0,
+ employees: {},
+ };
+
+ if (ticketsGroupedByDate[day]) {
+ ticketsGroupedByDate[day].forEach((ticket) => {
+ r.actualtotal = r.actualtotal + ticket.actualhrs;
+ r.productivetotal = r.productivetotal + ticket.productivehrs;
+ totals.totalactual = totals.totalactual + ticket.actualhrs;
+ totals.totalproductive =
+ totals.totalproductive + ticket.productivehrs;
+
+ employees.push(ticket.employee.employee_number);
+ //Add to table data.
+ ret.employees[ticket.employee.employee_number].totalOverPeriod =
+ ret.employees[ticket.employee.employee_number].totalOverPeriod +
+ ticket.productivehrs;
+
+ if (!totals.employees[ticket.employee.employee_number])
+ totals.employees[ticket.employee.employee_number] = {
+ totalactual: 0,
+ totalproductive: 0,
+ };
+
+ if (!r.employees[ticket.employee.employee_number])
+ r.employees[ticket.employee.employee_number] = {
+ actual: 0,
+ productive: 0,
+ };
+
+ //Add to totals.
+ totals.employees[ticket.employee.employee_number].totalproductive =
+ totals.employees[ticket.employee.employee_number].totalproductive +
+ ticket.productivehrs;
+
+ totals.employees[ticket.employee.employee_number].totalactual =
+ totals.employees[ticket.employee.employee_number].totalactual +
+ ticket.actualhrs;
+ //Add to dailys.
+ r.employees[ticket.employee.employee_number].productive =
+ r.employees[ticket.employee.employee_number].productive +
+ ticket.productivehrs;
+
+ r.employees[ticket.employee.employee_number].actual =
+ r.employees[ticket.employee.employee_number].actual +
+ ticket.actualhrs;
+ });
+ }
+
+ ret2.push(r);
+ });
+
+ return {
+ fixed: ret,
+ timeperiod: {
+ totals,
+ chartData: ret2,
+ employees: _.uniq(employees),
+ colors: getColorArray(employees.length),
+ },
+ };
+ }, [fixedPeriods, data, startDate, endDate]);
+
+ if (error) return ;
+ if (loading) return ;
return (
-
-
-
-
+
+
+
+
+
+
+
+
);
}
@@ -43,3 +252,50 @@ export default function ScoreboardTimeTickets() {
//Hours produced in last 7 days
//Hours produced for time period by day
//Hours produced by employee by day for time period.
+
+function getColorArray(num) {
+ return [
+ "#3366cc",
+ "#dc3912",
+ "#ff9900",
+ "#109618",
+ "#990099",
+ "#0099c6",
+ "#dd4477",
+ "#66aa00",
+ "#b82e2e",
+ "#316395",
+ "#3366cc",
+ "#994499",
+ "#22aa99",
+ "#aaaa11",
+ "#6633cc",
+ "#e67300",
+ "#8b0707",
+ "#651067",
+ "#329262",
+ "#5574a6",
+ "#3b3eac",
+ "#b77322",
+ "#16d620",
+ "#b91383",
+ "#f4359e",
+ "#9c5935",
+ "#a9c413",
+ "#2a778d",
+ "#668d1c",
+ "#bea413",
+ "#0c5922",
+ "#743411",
+ ];
+ // var result = [];
+ // for (var i = 0; i < num; i += 1) {
+ // var letters = "0123456789ABCDEF".split("");
+ // var color = "#";
+ // for (var j = 0; j < 6; j += 1) {
+ // color += letters[Math.floor(Math.random() * 16)];
+ // }
+ // result.push(color);
+ // }
+ // return result;
+}
diff --git a/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx
new file mode 100644
index 000000000..863f5f14f
--- /dev/null
+++ b/client/src/components/scoreboard-timetickets/scoreboard-timetickets.stats.component.jsx
@@ -0,0 +1,101 @@
+import { Card, Col, Row, Space, Statistic, Table } from "antd";
+import React from "react";
+import { useTranslation } from "react-i18next";
+import { connect } from "react-redux";
+import { createStructuredSelector } from "reselect";
+import { selectBodyshop } from "../../redux/user/user.selectors";
+
+const mapStateToProps = createStructuredSelector({
+ bodyshop: selectBodyshop,
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ //setUserLanguage: language => dispatch(setUserLanguage(language))
+});
+export default connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(ScoreboardTicketsStats);
+
+export function ScoreboardTicketsStats({ data, bodyshop }) {
+ const { t } = useTranslation();
+
+ const columns = [
+ {
+ title: t("employees.fields.employee_number"),
+ dataIndex: "employee_number",
+ key: "employee_number",
+ sorter: (a, b) => a.employee_number - b.employee_number,
+ },
+ {
+ title: t("scoreboard.labels.thisweek"),
+ dataIndex: "totalThisWeek",
+ key: "totalThisWeek",
+ sorter: (a, b) => a.totalThisWeek - b.totalThisWeek,
+ },
+ {
+ title: t("scoreboard.labels.lastweek"),
+ dataIndex: "totalLastWeek",
+ key: "totalLastWeek",
+ sorter: (a, b) => a.totalLastWeek - b.totalLastWeek,
+ },
+ {
+ title: t("scoreboard.labels.thismonth"),
+ dataIndex: "totalThisMonth",
+ key: "totalThisMonth",
+ sorter: (a, b) => a.totalThisMonth - b.totalThisMonth,
+ },
+ {
+ title: t("scoreboard.labels.lastmonth"),
+ dataIndex: "totalLastMonth",
+ key: "totalLastMonth",
+ sorter: (a, b) => a.totalLastMonth - b.totalLastMonth,
+ },
+ {
+ title: t("scoreboard.labels.totaloverperiod"),
+ dataIndex: "totalOverPeriod",
+ key: "totalOverPeriod",
+ sorter: (a, b) => a.totalOverPeriod - b.totalOverPeriod,
+ },
+ ];
+
+ const tableData = data
+ ? Object.keys(data.employees).map((key) => {
+ return { employee_number: key, ...data.employees[key] };
+ })
+ : [];
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx b/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx
index b7a5ac44b..a827e3fd7 100644
--- a/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx
+++ b/client/src/components/ticket-tickets-dates-selector/time-tickets-dates-selector.component.jsx
@@ -17,6 +17,7 @@ export default function TimeTicketsDatesSelector() {
if (!!start && !!end) {
history.push({
search: queryString.stringify({
+ ...searchParams,
start: start.format("YYYY-MM-DD"),
end: end.format("YYYY-MM-DD"),
}),
@@ -25,6 +26,7 @@ export default function TimeTicketsDatesSelector() {
} else {
history.push({
search: queryString.stringify({
+ ...searchParams,
start: null,
end: null,
}),
diff --git a/client/src/graphql/jobs-lines.queries.js b/client/src/graphql/jobs-lines.queries.js
index 3617df239..b2184f072 100644
--- a/client/src/graphql/jobs-lines.queries.js
+++ b/client/src/graphql/jobs-lines.queries.js
@@ -61,6 +61,7 @@ export const GET_LINE_TICKET_BY_PK = gql`
flat_rate
clockon
clockoff
+ rate
employee {
id
first_name
diff --git a/client/src/graphql/timetickets.queries.js b/client/src/graphql/timetickets.queries.js
index 057edc1cb..12d370560 100644
--- a/client/src/graphql/timetickets.queries.js
+++ b/client/src/graphql/timetickets.queries.js
@@ -26,7 +26,12 @@ export const QUERY_TICKETS_BY_JOBID = gql`
`;
export const QUERY_TIME_TICKETS_IN_RANGE = gql`
- query QUERY_TIME_TICKETS_IN_RANGE($start: date!, $end: date!) {
+ query QUERY_TIME_TICKETS_IN_RANGE(
+ $start: date!
+ $end: date!
+ $fixedStart: date!
+ $fixedEnd: date!
+ ) {
timetickets(
where: { date: { _gte: $start, _lte: $end } }
order_by: { date: desc_nulls_first }
@@ -56,6 +61,35 @@ export const QUERY_TIME_TICKETS_IN_RANGE = gql`
last_name
}
}
+ fixedperiod: timetickets(
+ where: { date: { _gte: $fixedStart, _lte: $fixedEnd } }
+ order_by: { date: desc_nulls_first }
+ ) {
+ actualhrs
+ ciecacode
+ clockoff
+ clockon
+ cost_center
+ created_at
+ date
+ id
+ rate
+ productivehrs
+ memo
+ jobid
+ flat_rate
+ job {
+ id
+ ro_number
+ }
+ employeeid
+ employee {
+ id
+ employee_number
+ first_name
+ last_name
+ }
+ }
}
`;
diff --git a/client/src/pages/scoreboard/scoreboard.page.container.jsx b/client/src/pages/scoreboard/scoreboard.page.container.jsx
index 1abffe30e..a15ad12ac 100644
--- a/client/src/pages/scoreboard/scoreboard.page.container.jsx
+++ b/client/src/pages/scoreboard/scoreboard.page.container.jsx
@@ -1,19 +1,21 @@
-import Icon from "@ant-design/icons";
+import Icon, { BarsOutlined } from "@ant-design/icons";
import { Tabs } from "antd";
import React, { useEffect } from "react";
import { useTranslation } from "react-i18next";
+import { FaShieldAlt } from "react-icons/fa";
import { connect } from "react-redux";
import { createStructuredSelector } from "reselect";
import FeatureWrapper from "../../components/feature-wrapper/feature-wrapper.component";
import RbacWrapper from "../../components/rbac-wrapper/rbac-wrapper.component";
import ScoreboardDisplay from "../../components/scoreboard-display/scoreboard-display.component";
+import ScoreboardTimeTickets from "../../components/scoreboard-timetickets/scoreboard-timetickets.component";
import {
setBreadcrumbs,
setSelectedHeader,
} from "../../redux/application/application.actions";
import { selectBodyshop } from "../../redux/user/user.selectors";
-import { FaHardHat, FaRegStickyNote, FaShieldAlt } from "react-icons/fa";
-import ScoreboardTimeTickets from "../../components/scoreboard-timetickets/scoreboard-timetickets.component";
+import queryString from "query-string";
+import { useHistory, useLocation } from "react-router-dom";
const mapStateToProps = createStructuredSelector({
bodyshop: selectBodyshop,
@@ -26,7 +28,9 @@ const mapDispatchToProps = (dispatch) => ({
export function ScoreboardContainer({ setBreadcrumbs, setSelectedHeader }) {
const { t } = useTranslation();
-
+ const searchParams = queryString.parse(useLocation().search);
+ const { tab } = searchParams;
+ const history = useHistory();
useEffect(() => {
document.title = t("titles.scoreboard");
setSelectedHeader("scoreboard");
@@ -41,12 +45,21 @@ export function ScoreboardContainer({ setBreadcrumbs, setSelectedHeader }) {
return (
-
+ {
+ searchParams.tab = key;
+ history.push({
+ search: queryString.stringify(searchParams),
+ });
+ }}
+ >
- {t("menus.jobsdetail.general")}
+ {t("scoreboard.labels.jobs")}
}
destroyInactiveTabPane
@@ -57,8 +70,8 @@ export function ScoreboardContainer({ setBreadcrumbs, setSelectedHeader }) {
-
- {t("menus.jobsdetail.general")}
+
+ {t("scoreboard.labels.timetickets")}
}
destroyInactiveTabPane
diff --git a/client/src/translations/en_us/common.json b/client/src/translations/en_us/common.json
index 9f42c9251..ba02ecc71 100644
--- a/client/src/translations/en_us/common.json
+++ b/client/src/translations/en_us/common.json
@@ -2426,9 +2426,18 @@
"asoftodaytarget": "As of Today",
"dailyactual": "Actual (D)",
"dailytarget": "Daily",
+ "jobs": "Jobs",
+ "lastmonth": "Last Month",
+ "lastweek": "Last Week",
"monthlytarget": "Monthly",
+ "productivestatistics": "Productive Hours Statistics",
+ "productivetimeticketsoverdate": "Productive Hours over Selected Dates",
"targets": "Targets",
+ "thismonth": "This Month",
+ "thisweek": "This Week",
+ "timetickets": "Timetickets",
"todateactual": "Actual (MTD)",
+ "totaloverperiod": "Total Period",
"weeklyactual": "Actual (W)",
"weeklytarget": "Weekly",
"workingdays": "Working Days / Month"
diff --git a/client/src/translations/es/common.json b/client/src/translations/es/common.json
index 2c26b4a3b..ae5d81de2 100644
--- a/client/src/translations/es/common.json
+++ b/client/src/translations/es/common.json
@@ -2426,9 +2426,18 @@
"asoftodaytarget": "",
"dailyactual": "",
"dailytarget": "",
+ "jobs": "",
+ "lastmonth": "",
+ "lastweek": "",
"monthlytarget": "",
+ "productivestatistics": "",
+ "productivetimeticketsoverdate": "",
"targets": "",
+ "thismonth": "",
+ "thisweek": "",
+ "timetickets": "",
"todateactual": "",
+ "totaloverperiod": "",
"weeklyactual": "",
"weeklytarget": "",
"workingdays": ""
diff --git a/client/src/translations/fr/common.json b/client/src/translations/fr/common.json
index 2f2547393..b71d833e8 100644
--- a/client/src/translations/fr/common.json
+++ b/client/src/translations/fr/common.json
@@ -2426,9 +2426,18 @@
"asoftodaytarget": "",
"dailyactual": "",
"dailytarget": "",
+ "jobs": "",
+ "lastmonth": "",
+ "lastweek": "",
"monthlytarget": "",
+ "productivestatistics": "",
+ "productivetimeticketsoverdate": "",
"targets": "",
+ "thismonth": "",
+ "thisweek": "",
+ "timetickets": "",
"todateactual": "",
+ "totaloverperiod": "",
"weeklyactual": "",
"weeklytarget": "",
"workingdays": ""