IO-1861 All scoreboard entries.

This commit is contained in:
Patrick Fic
2022-07-26 11:22:15 -07:00
parent 2586393b4c
commit 22cd7fcef1
11 changed files with 2947 additions and 3240 deletions

View File

@@ -41535,6 +41535,27 @@
</translation>
</translations>
</concept_node>
<concept_node>
<name>entries</name>
<definition_loaded>false</definition_loaded>
<description></description>
<comment></comment>
<default_text></default_text>
<translations>
<translation>
<language>en-US</language>
<approved>false</approved>
</translation>
<translation>
<language>es-MX</language>
<approved>false</approved>
</translation>
<translation>
<language>fr-CA</language>
<approved>false</approved>
</translation>
</translations>
</concept_node>
<concept_node>
<name>jobs</name>
<definition_loaded>false</definition_loaded>

View File

@@ -1,42 +1,42 @@
import { useQuery } from "@apollo/client";
import { Button, Card, Input, Modal, Space, Table } from "antd";
import React, { useState } from "react";
import { Dropdown, Button, Table, Space, Card, Input } from "antd";
import { useTranslation } from "react-i18next";
import { Link } from "react-router-dom";
import ScoreboardRemoveButton from "../scoreboard-remove-button/scorebard-remove-button.component";
import { QUERY_SCOREBOARD_PAGINATED } from "../../graphql/scoreboard.queries";
import { DateFormatter } from "../../utils/DateFormatter";
import ScoreboardEntryEdit from "../scoreboard-entry-edit/scoreboard-entry-edit.component";
import AlertComponent from "../alert/alert.component";
import OwnerNameDisplay from "../owner-name-display/owner-name-display.component";
import ScoreboardEntryEdit from "../scoreboard-entry-edit/scoreboard-entry-edit.component";
import ScoreboardRemoveButton from "../scoreboard-remove-button/scorebard-remove-button.component";
import { SyncOutlined } from "@ant-design/icons";
export default function ScoreboardJobsList({ scoreBoardlist }) {
const { t } = useTranslation();
const [searchText, setSearchText] = useState("");
const [state, setState] = useState({
visible: false,
search: "",
current: 1,
pageSize: 10,
});
const jobs = scoreBoardlist
? searchText === ""
? scoreBoardlist
: scoreBoardlist.filter(
(sb) =>
(sb.job.ro_number || "")
.toString()
.toLowerCase()
.includes(searchText.toLowerCase()) ||
(sb.job.ownr_co_nm || "")
.toLowerCase()
.includes(searchText.toLowerCase()) ||
(sb.job.ownr_fn || "")
.toLowerCase()
.includes(searchText.toLowerCase()) ||
(sb.job.ownr_ln || "")
.toLowerCase()
.includes(searchText.toLowerCase()) ||
(sb.job.v_model_desc || "")
.toLowerCase()
.includes(searchText.toLowerCase()) ||
(sb.job.v_make_desc || "")
.toLowerCase()
.includes(searchText.toLowerCase())
)
: [];
const { loading, error, data, refetch } = useQuery(
QUERY_SCOREBOARD_PAGINATED,
{
fetchPolicy: "network-only",
nextFetchPolicy: "network-only",
skip: !state.visible,
variables: {
search: state.search !== "" ? `%${state.search}%` : null,
offset: state.current ? (state.current - 1) * state.pageSize : 0,
limit: state.pageSize,
order: [
{
date: "desc",
},
],
},
}
);
const columns = [
{
@@ -97,35 +97,65 @@ export default function ScoreboardJobsList({ scoreBoardlist }) {
},
];
const overlay = (
<Card
style={{ maxWidth: "90vw", padding: "1rem" }}
onClick={(e) => e.stopPropagation()}
extra={
<Input.Search
placeholder={t("general.labels.search")}
onChange={(e) => {
setSearchText(e.target.value);
}}
value={searchText}
enterButton
onClick={(e) => e.stopPropagation()}
/>
}
>
<Table
pagination={false}
columns={columns}
rowKey="id"
dataSource={jobs}
onClick={(e) => e.stopPropagation()}
/>
</Card>
);
return (
<Dropdown trigger={["click"]} overlay={overlay}>
<Button>Jobs</Button>
</Dropdown>
<>
<Modal
visible={state.visible}
destroyOnClose
width="80%"
cancelButtonProps={{ style: { display: "none" } }}
onCancel={() =>
setState((state) => ({
...state,
visible: false,
current: 1,
search: "",
}))
}
>
{error && (
<AlertComponent type="error" message={JSON.stringify(error)} />
)}
<Card
extra={
<Space wrap>
<Button onClick={() => refetch()}>
<SyncOutlined />
</Button>
<Input.Search
placeholder={t("jobs.fields.ro_number")}
onSearch={(value) => {
setState((state) => ({ ...state, search: value }));
}}
value={state.search}
enterButton
/>
</Space>
}
>
<Table
columns={columns}
rowKey="id"
dataSource={data ? data.scoreboard : []}
loading={loading}
onClick={(e) => e.stopPropagation()}
onChange={(tableArgs) =>
setState((state) => ({ ...state, ...tableArgs }))
}
pagination={{
position: "top",
pageSize: state.pageSize || 10,
current: state.current || 1,
total: data ? data.scoreboard_aggregate.aggregate.count : 0,
}}
/>
</Card>
</Modal>
<Button
onClick={() => setState((state) => ({ ...state, visible: true }))}
>
{t("scoreboard.labels.entries")}
</Button>
</>
);
}

View File

@@ -17,6 +17,8 @@ export default function ScoreboardRemoveButton({ scoreboardId }) {
setLoading(true);
const result = await deleteScoreboardEntry({
variables: { sbId: scoreboardId },
awaitRefetchQueries: true,
refetchQueries: ["QUERY_SCOREBOARD_PAGINATED"],
});
if (!!result.errors) {

View File

@@ -185,8 +185,8 @@ export default function ScoreboardTimeTickets() {
ret.employees[ticket.employee.employee_number].totalOverPeriod +
ticket.productivehrs;
ret.employees[ticket.employee.employee_number].actualTotalOverPeriod =
ret.employees[ticket.employee.employee_number].actualTotalOverPeriod +
(ticket.actualhrs || 0);
ret.employees[ticket.employee.employee_number]
.actualTotalOverPeriod + (ticket.actualhrs || 0);
if (!totals.employees[ticket.employee.employee_number])
totals.employees[ticket.employee.employee_number] = {
@@ -236,8 +236,6 @@ export default function ScoreboardTimeTickets() {
};
}, [fixedPeriods, data, startDate, endDate]);
console.log(calculatedData);
if (error) return <AlertComponent message={error.message} type="error" />;
if (loading) return <LoadingSpinner />;
return (

View File

@@ -88,3 +88,38 @@ export const GET_BLOCKED_DAYS = gql`
}
}
`;
export const QUERY_SCOREBOARD_PAGINATED = gql`
query QUERY_SCOREBOARD_PAGINATED(
$search: String
$offset: Int
$limit: Int
$order: [scoreboard_order_by!]
) {
scoreboard(
where: { job: { ro_number: { _ilike: $search } } }
offset: $offset
limit: $limit
order_by: $order
) {
id
jobid
job {
id
ro_number
invoice_date
v_make_desc
v_model_desc
v_model_yr
}
date
bodyhrs
painthrs
}
scoreboard_aggregate(where: { job: { ro_number: { _ilike: $search } } }) {
aggregate {
count(distinct: true)
}
}
}
`;

View File

@@ -2465,6 +2465,7 @@
"dailyactual": "Actual (D)",
"dailytarget": "Daily",
"efficiencyoverperiod": "Efficiency over Selected Dates",
"entries": "Scoreboard Entries",
"jobs": "Jobs",
"lastmonth": "Last Month",
"lastweek": "Last Week",

View File

@@ -2465,6 +2465,7 @@
"dailyactual": "",
"dailytarget": "",
"efficiencyoverperiod": "",
"entries": "",
"jobs": "",
"lastmonth": "",
"lastweek": "",

View File

@@ -2465,6 +2465,7 @@
"dailyactual": "",
"dailytarget": "",
"efficiencyoverperiod": "",
"entries": "",
"jobs": "",
"lastmonth": "",
"lastweek": "",

File diff suppressed because it is too large Load Diff

View File

@@ -56,8 +56,6 @@
},
"devDependencies": {
"concurrently": "^7.3.0",
"eslint": "^8.20.0",
"eslint-plugin-promise": "^6.0.0",
"source-map-explorer": "^2.5.2"
}
}

1493
yarn.lock

File diff suppressed because it is too large Load Diff