- Merge release and adjust due to version differences

Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
Dave Richer
2024-02-22 18:44:43 -05:00
20 changed files with 1329 additions and 397 deletions

View File

@@ -1,19 +1,26 @@
import {BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined,} from "@ant-design/icons";
import {Card, Space, Table, Tooltip} from "antd";
import {Card, Space, Switch, Table, Tooltip, Typography} from "antd";
import dayjs from "../../../utils/day";
import React, {useState} from "react";
import {useTranslation} from "react-i18next";
import {Link} from "react-router-dom";
import {TimeFormatter} from "../../../utils/DateFormatter";
import {onlyUnique} from "../../../utils/arrayHelper";
import {alphaSort, dateSort} from "../../../utils/sorters";
import useLocalStorage from "../../../utils/useLocalStorage";
import ChatOpenButton from "../../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../../owner-name-display/owner-name-display.component";
import OwnerNameDisplay, {OwnerNameDisplayFunction,} from "../../owner-name-display/owner-name-display.component";
import DashboardRefreshRequired from "../refresh-required.component";
import {pageLimit} from "../../../utils/config";
export default function DashboardScheduledInToday({data, ...cardProps}) {
const {t} = useTranslation();
const [state, setState] = useState({
sortedInfo: {},
});
const [isTvModeScheduledIn, setIsTvModeScheduledIn] = useLocalStorage(
"isTvModeScheduledIn",
false
);
if (!data) return null;
if (!data.scheduled_in_today)
return <DashboardRefreshRequired {...cardProps} />;
@@ -27,6 +34,12 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
alt_transport: item.job.alt_transport,
clm_no: item.job.clm_no,
jobid: item.job.jobid,
joblines_body: item.job.joblines
.filter((l) => l.mod_lbr_ty !== "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0),
joblines_ref: item.job.joblines
.filter((l) => l.mod_lbr_ty === "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0),
ins_co_nm: item.job.ins_co_nm,
iouparent: item.job.iouparent,
ownerid: item.job.ownerid,
@@ -45,22 +58,200 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
v_vin: item.job.v_vin,
vehicleid: item.job.vehicleid,
note: item.note,
start: dayjs(item.start).format("hh:mm a"),
start: item.start,
title: item.title,
};
appt.push(i);
}
});
appt.sort(function (a, b) {
return new dayjs(a.start) - new dayjs(b.start);
return dayjs(a.start) - dayjs(b.start);
});
const columns = [
const tvFontSize = 16;
const tvFontWeight = "bold";
const tvColumns = [
{
title: t("appointments.fields.time"),
dataIndex: "start",
key: "start",
ellipsis: true,
sorter: (a, b) => dateSort(a.start, b.start),
sortOrder:
state.sortedInfo.columnKey === "start" && state.sortedInfo.order,
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<TimeFormatter>{record.start}</TimeFormatter>
</span>
),
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
>
<Space>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.ro_number || t("general.labels.na")}
{record.production_vars && record.production_vars.alert ? (
<ExclamationCircleFilled className="production-alert"/>
) : null}
{record.suspended && (
<PauseCircleOutlined style={{color: "orangered"}}/>
)}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{color: "orangered"}}/>
</Tooltip>
)}
</span>
</Space>
</Link>
),
},
{
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
return record.ownerid ? (
<Link
to={"/manage/owners/" + record.ownerid}
onClick={(e) => e.stopPropagation()}
>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<OwnerNameDisplay ownerObject={record}/>
</span>
</Link>
) : (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<OwnerNameDisplay ownerObject={record}/>
</span>
);
},
},
{
title: t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
onClick={(e) => e.stopPropagation()}
>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}
</span>
</Link>
) : (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>{`${
record.v_model_yr || ""
} ${record.v_make_desc || ""} ${record.v_model_desc || ""}`}</span>
);
},
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(appt &&
appt
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.alt_transport}
</span>
),
},
{
title: t("jobs.fields.lab"),
dataIndex: "joblines_body",
key: "joblines_body",
sorter: (a, b) => a.joblines_body - b.joblines_body,
sortOrder:
state.sortedInfo.columnKey === "joblines_body" &&
state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.joblines_body.toFixed(1)}
</span>
),
},
{
title: t("jobs.fields.lar"),
dataIndex: "joblines_ref",
key: "joblines_ref",
sorter: (a, b) => a.joblines_ref - b.joblines_ref,
sortOrder:
state.sortedInfo.columnKey === "joblines_ref" && state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.joblines_ref.toFixed(1)}
</span>
),
},
];
const columns = [
{
title: t("appointments.fields.time"),
dataIndex: "start",
key: "start",
ellipsis: true,
sorter: (a, b) => dateSort(a.start, b.start),
sortOrder:
state.sortedInfo.columnKey === "start" && state.sortedInfo.order,
render: (text, record) => <TimeFormatter>{record.start}</TimeFormatter>,
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order, render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
@@ -87,7 +278,10 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
dataIndex: "owner",
key: "owner",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
return record.ownerid ? (
<Link
@@ -104,24 +298,16 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
},
},
{
title: t("jobs.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
title: t("dashboard.labels.phone"),
dataIndex: "ownr_ph",
key: "ownr_ph",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
render: (text, record) => (<Space size="small" wrap>
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid}/>
),
},
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid}/>
),
</Space>),
},
{
title: t("jobs.fields.ownr_ea"),
@@ -130,7 +316,7 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ea} jobid={record.jobid}/>
<a href={`mailto:${record.ownr_ea}`}>{record.ownr_ea}</a>
),
},
{
@@ -138,7 +324,15 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
render: (text, record) => {
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order, render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
@@ -161,20 +355,46 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
key: "ins_co_nm",
ellipsis: true,
responsive: ["md"],
},
{
title: t("appointments.fields.time"),
dataIndex: "start",
key: "start",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm),
sortOrder:
state.sortedInfo.columnKey === "ins_co_nm" && state.sortedInfo.order,
filters:
(appt &&
appt
.map((j) => j.ins_co_nm)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Ins. Co.*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.ins_co_nm),
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(appt &&
appt
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
},
];
@@ -184,20 +404,28 @@ export default function DashboardScheduledInToday({data, ...cardProps}) {
return (
<Card
title={t("dashboard.titles.scheduledintoday", {
title={t("dashboard.titles.scheduledindate", {
date: dayjs().startOf("day").format("MM/DD/YYYY"),
})}
{...cardProps}
extra={
<Space>
<Typography.Text>{t("general.labels.tvmode")}</Typography.Text>
<Switch
onClick={() => setIsTvModeScheduledIn(!isTvModeScheduledIn)}
defaultChecked={isTvModeScheduledIn}
/>
</Space>
}{...cardProps}
>
<div style={{height: "100%"}}>
<Table
onChange={handleTableChange}
pagination={{position: "top", defaultPageSize: pageLimit}}
columns={columns}
pagination={false}
columns={isTvModeScheduledIn ? tvColumns : columns}
scroll={{x: true, y: "calc(100% - 2em)"}}
rowKey="id"
style={{height: "85%"}}
dataSource={appt}
dataSource={appt} size={isTvModeScheduledIn ? "small" : "middle"}
/>
</div>
</Card>
@@ -216,6 +444,10 @@ export const DashboardScheduledInTodayGql = `
alt_transport
clm_no
jobid: id
joblines(where: {removed: {_eq: false}}) {
mod_lb_hrs
mod_lbr_ty
}
ins_co_nm
iouparent
ownerid

View File

@@ -1,37 +1,286 @@
import {BranchesOutlined, ExclamationCircleFilled, PauseCircleOutlined,} from "@ant-design/icons";
import {Card, Space, Table, Tooltip} from "antd";
import {Card, Space, Switch, Table, Tooltip, Typography} from "antd";
import dayjs from "../../../utils/day";
import React, {useState} from "react";
import {useTranslation} from "react-i18next";
import {Link} from "react-router-dom";
import {TimeFormatter} from "../../../utils/DateFormatter";
import {onlyUnique} from "../../../utils/arrayHelper";
import {alphaSort, dateSort} from "../../../utils/sorters";
import useLocalStorage from "../../../utils/useLocalStorage";
import ChatOpenButton from "../../chat-open-button/chat-open-button.component";
import OwnerNameDisplay from "../../owner-name-display/owner-name-display.component";
import OwnerNameDisplay, {OwnerNameDisplayFunction,} from "../../owner-name-display/owner-name-display.component";
import DashboardRefreshRequired from "../refresh-required.component";
import {pageLimit} from "../../../utils/config";
export default function DashboardScheduledOutToday({data, ...cardProps}) {
const {t} = useTranslation();
const [state, setState] = useState({
sortedInfo: {},
});
const [isTvModeScheduledOut, setIsTvModeScheduledOut] = useLocalStorage(
"isTvModeScheduledOut",
false
);
if (!data) return null;
if (!data.scheduled_out_today)
return <DashboardRefreshRequired {...cardProps} />;
const filteredScheduledOutToday = data.scheduled_out_today.map((item) => {
const newData = data.scheduled_out_today.map((item) => {
const joblines_body = item.joblines
? item.joblines
.filter((l) => l.mod_lbr_ty !== "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
: 0;
const joblines_ref = item.joblines
? item.joblines
.filter((l) => l.mod_lbr_ty === "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
: 0;
return {
...item,
scheduled_completion: dayjs(item.scheduled_completion).format("hh:mm a"),
timestamp: dayjs(item.scheduled_completion).valueOf(),
}
}).sort((a, b) => a.timestamp - b.timestamp);
joblines_body,
joblines_ref,
};
});
const columns = [
newData.forEach((item) => {
item.joblines_body = item.joblines
? item.joblines
.filter((l) => l.mod_lbr_ty !== "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
: 0;
item.joblines_ref = item.joblines
? item.joblines
.filter((l) => l.mod_lbr_ty === "LAR")
.reduce((acc, val) => acc + val.mod_lb_hrs, 0)
: 0;
});
newData.sort(function (a, b) {
return new Date(a.scheduled_completion) - new Date(b.scheduled_completion);
});
const tvFontSize = 18;
const tvFontWeight = "bold";
const tvColumns = [
{
title: t("jobs.fields.scheduled_completion"),
dataIndex: "scheduled_completion",
key: "scheduled_completion",
ellipsis: true,
sorter: (a, b) =>
dateSort(a.scheduled_completion, b.scheduled_completion),
sortOrder:
state.sortedInfo.columnKey === "scheduled_completion" &&
state.sortedInfo.order,
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<TimeFormatter>{record.scheduled_completion}</TimeFormatter>
</span>
),
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order,
render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
>
<Space>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.ro_number || t("general.labels.na")}
{record.production_vars && record.production_vars.alert ? (
<ExclamationCircleFilled className="production-alert"/>
) : null}
{record.suspended && (
<PauseCircleOutlined style={{color: "orangered"}}/>
)}
{record.iouparent && (
<Tooltip title={t("jobs.labels.iou")}>
<BranchesOutlined style={{color: "orangered"}}/>
</Tooltip>
)}
</span>
</Space>
</Link>
),
},
{
title: t("jobs.fields.owner"),
dataIndex: "owner",
key: "owner",
ellipsis: true,
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
return record.ownerid ? (
<Link
to={"/manage/owners/" + record.ownerid}
onClick={(e) => e.stopPropagation()}
>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<OwnerNameDisplay ownerObject={record}/>
</span>
</Link>
) : (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
<OwnerNameDisplay ownerObject={record}/>
</span>
);
},
},
{
title: t("jobs.fields.vehicle"),
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order,
render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
onClick={(e) => e.stopPropagation()}
>
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}
</span>
</Link>
) : (
<span
style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}
>{`${record.v_model_yr || ""} ${record.v_make_desc || ""} ${
record.v_model_desc || ""
}`}</span>
);
},
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(newData &&
newData
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.alt_transport}
</span>
),
},
{
title: t("jobs.fields.status"),
dataIndex: "status",
key: "status",
ellipsis: true,
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "status" && state.sortedInfo.order,
filters:
(data.scheduled_out_today &&
data.scheduled_out_today
.map((j) => j.status)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Status*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.status}
</span>
),
},
{
title: t("jobs.fields.lab"),
dataIndex: "joblines_body",
key: "joblines_body",
sorter: (a, b) => a.joblines_body - b.joblines_body,
sortOrder:
state.sortedInfo.columnKey === "joblines_body" &&
state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.joblines_body.toFixed(1)}
</span>
),
},
{
title: t("jobs.fields.lar"),
dataIndex: "joblines_ref",
key: "joblines_ref",
sorter: (a, b) => a.joblines_ref - b.joblines_ref,
sortOrder:
state.sortedInfo.columnKey === "joblines_ref" && state.sortedInfo.order,
align: "right",
render: (text, record) => (
<span style={{fontSize: tvFontSize, fontWeight: tvFontWeight}}>
{record.joblines_ref.toFixed(1)}
</span>
),
},
];
const columns = [
{
title: t("jobs.fields.scheduled_completion"),
dataIndex: "scheduled_completion",
key: "scheduled_completion",
ellipsis: true,
sorter: (a, b) =>
dateSort(a.scheduled_completion, b.scheduled_completion),
sortOrder:
state.sortedInfo.columnKey === "scheduled_completion" &&
state.sortedInfo.order,
render: (text, record) => (
<TimeFormatter>{record.scheduled_completion}</TimeFormatter>
),
},
{
title: t("jobs.fields.ro_number"),
dataIndex: "ro_number",
key: "ro_number",
sorter: (a, b) => alphaSort(a.ro_number, b.ro_number),
sortOrder:
state.sortedInfo.columnKey === "ro_number" && state.sortedInfo.order, render: (text, record) => (
<Link
to={"/manage/jobs/" + record.jobid}
onClick={(e) => e.stopPropagation()}
@@ -58,7 +307,10 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
dataIndex: "owner",
key: "owner",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) =>
alphaSort(OwnerNameDisplayFunction(a), OwnerNameDisplayFunction(b)),
sortOrder:
state.sortedInfo.columnKey === "owner" && state.sortedInfo.order,
render: (text, record) => {
return record.ownerid ? (
<Link
@@ -75,24 +327,16 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
},
},
{
title: t("jobs.fields.ownr_ph1"),
dataIndex: "ownr_ph1",
key: "ownr_ph1",
title: t("dashboard.labels.phone"),
dataIndex: "ownr_ph",
key: "ownr_ph",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
render: (text, record) => (<Space size="small" wrap>
<ChatOpenButton phone={record.ownr_ph1} jobid={record.jobid}/>
),
},
{
title: t("jobs.fields.ownr_ph2"),
dataIndex: "ownr_ph2",
key: "ownr_ph2",
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ph2} jobid={record.jobid}/>
),
</Space>),
},
{
title: t("jobs.fields.ownr_ea"),
@@ -101,7 +345,7 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
ellipsis: true,
responsive: ["md"],
render: (text, record) => (
<ChatOpenButton phone={record.ownr_ea} jobid={record.jobid}/>
<a href={`mailto:${record.ownr_ea}`}>{record.ownr_ea}</a>
),
},
{
@@ -109,7 +353,15 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
dataIndex: "vehicle",
key: "vehicle",
ellipsis: true,
render: (text, record) => {
sorter: (a, b) =>
alphaSort(
`${a.v_model_yr || ""} ${a.v_make_desc || ""} ${
a.v_model_desc || ""
}`,
`${b.v_model_yr || ""} ${b.v_make_desc || ""} ${b.v_model_desc || ""}`
),
sortOrder:
state.sortedInfo.columnKey === "vehicle" && state.sortedInfo.order, render: (text, record) => {
return record.vehicleid ? (
<Link
to={"/manage/vehicles/" + record.vehicleid}
@@ -132,20 +384,46 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
key: "ins_co_nm",
ellipsis: true,
responsive: ["md"],
},
{
title: t("jobs.fields.scheduled_completion"),
dataIndex: "scheduled_completion",
key: "scheduled_completion",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) => alphaSort(a.ins_co_nm, b.ins_co_nm),
sortOrder:
state.sortedInfo.columnKey === "ins_co_nm" && state.sortedInfo.order,
filters:
(data.scheduled_out_today &&
data.scheduled_out_today
.map((j) => j.ins_co_nm)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Ins. Co.*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
onFilter: (value, record) => value.includes(record.ins_co_nm),
},
{
title: t("appointments.fields.alt_transport"),
dataIndex: "alt_transport",
key: "alt_transport",
ellipsis: true,
responsive: ["md"],
sorter: (a, b) => alphaSort(a.alt_transport, b.alt_transport),
sortOrder:
state.sortedInfo.columnKey === "alt_transport" &&
state.sortedInfo.order,
filters:
(data.scheduled_out_today &&
data.scheduled_out_today
.map((j) => j.alt_transport)
.filter(onlyUnique)
.map((s) => {
return {
text: s || "No Alt. Transport*",
value: [s],
};
})
.sort((a, b) => alphaSort(a.text, b.text))) ||
[],
},
];
@@ -155,20 +433,29 @@ export default function DashboardScheduledOutToday({data, ...cardProps}) {
return (
<Card
title={t("dashboard.titles.scheduledouttoday", {
title={t("dashboard.titles.scheduledoutdate", {
date: dayjs().startOf("day").format("MM/DD/YYYY"),
})}
{...cardProps}
extra={
<Space>
<Typography.Text>{t("general.labels.tvmode")}</Typography.Text>
<Switch
onClick={() => setIsTvModeScheduledOut(!isTvModeScheduledOut)}
defaultChecked={isTvModeScheduledOut}
/>
</Space>
}{...cardProps}
>
<div style={{height: "100%"}}>
<Table
onChange={handleTableChange}
pagination={{position: "top", defaultPageSize: pageLimit}}
columns={columns}
pagination={false}
columns={isTvModeScheduledOut ? tvColumns : columns}
scroll={{x: true, y: "calc(100% - 2em)"}}
rowKey="id"
style={{height: "85%"}}
dataSource={filteredScheduledOutToday}
dataSource={data.scheduled_out_today}
size={isTvModeScheduledOut ? "small" : "middle"}
/>
</div>
</Card>
@@ -185,6 +472,10 @@ export const DashboardScheduledOutTodayGql = `
alt_transport
clm_no
jobid: id
joblines(where: {removed: {_eq: false}}) {
mod_lb_hrs
mod_lbr_ty
}
ins_co_nm
iouparent
ownerid
@@ -197,6 +488,7 @@ export const DashboardScheduledOutTodayGql = `
production_vars
ro_number
scheduled_completion
status
suspended
v_make_desc
v_model_desc