- Finish up with Statistics
Signed-off-by: Dave Richer <dave@imexsystems.ca>
This commit is contained in:
@@ -22,7 +22,7 @@ const CardColorLegend = ({ bodyshop }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Col style={{ marginLeft: "15px" }}>
|
<Col>
|
||||||
<Typography>{t("production.labels.legend")}</Typography>
|
<Typography>{t("production.labels.legend")}</Typography>
|
||||||
<List
|
<List
|
||||||
grid={{
|
grid={{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { SyncOutlined } from "@ant-design/icons";
|
import { SyncOutlined } from "@ant-design/icons";
|
||||||
import { useApolloClient } from "@apollo/client";
|
import { useApolloClient } from "@apollo/client";
|
||||||
import Board from "./trello-board/index";
|
import Board from "./trello-board/index";
|
||||||
import { Button, notification, Skeleton, Space, Statistic } from "antd";
|
import { Button, notification, Skeleton, Space } from "antd";
|
||||||
import { PageHeader } from "@ant-design/pro-layout";
|
import { PageHeader } from "@ant-design/pro-layout";
|
||||||
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
@@ -175,28 +175,6 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
[boardLanes, client, getCardByID, isMoving, t, insertAuditTrail]
|
[boardLanes, client, getCardByID, isMoving, t, insertAuditTrail]
|
||||||
);
|
);
|
||||||
|
|
||||||
const totalHrs = useMemo(
|
|
||||||
() =>
|
|
||||||
data
|
|
||||||
.reduce(
|
|
||||||
(acc, val) =>
|
|
||||||
acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0) + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0),
|
|
||||||
0
|
|
||||||
)
|
|
||||||
.toFixed(1),
|
|
||||||
[data]
|
|
||||||
);
|
|
||||||
|
|
||||||
const totalLAB = useMemo(
|
|
||||||
() => data.reduce((acc, val) => acc + (val.labhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1),
|
|
||||||
[data]
|
|
||||||
);
|
|
||||||
|
|
||||||
const totalLAR = useMemo(
|
|
||||||
() => data.reduce((acc, val) => acc + (val.larhrs?.aggregate?.sum?.mod_lb_hrs || 0), 0).toFixed(1),
|
|
||||||
[data]
|
|
||||||
);
|
|
||||||
|
|
||||||
const cardSettings = useMemo(
|
const cardSettings = useMemo(
|
||||||
() =>
|
() =>
|
||||||
associationSettings?.kanban_settings && Object.keys(associationSettings.kanban_settings).length > 0
|
associationSettings?.kanban_settings && Object.keys(associationSettings.kanban_settings).length > 0
|
||||||
@@ -215,7 +193,17 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
orientation: false,
|
orientation: false,
|
||||||
cardSize: "small",
|
cardSize: "small",
|
||||||
model_info: true,
|
model_info: true,
|
||||||
kiosk: false
|
kiosk: false,
|
||||||
|
totalHrs: true,
|
||||||
|
totalAmountInProduction: false,
|
||||||
|
totalLAB: true,
|
||||||
|
totalLAR: true,
|
||||||
|
jobsInProduction: true,
|
||||||
|
totalHrsOnBoard: false,
|
||||||
|
totalLABOnBoard: false,
|
||||||
|
totalLAROnBoard: false,
|
||||||
|
jobsOnBoard: false,
|
||||||
|
totalAmountOnBoard: true
|
||||||
},
|
},
|
||||||
[associationSettings]
|
[associationSettings]
|
||||||
);
|
);
|
||||||
@@ -234,14 +222,8 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
<div>
|
<div>
|
||||||
<IndefiniteLoading loading={isMoving} />
|
<IndefiniteLoading loading={isMoving} />
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title={
|
title={cardSettings.cardcolor && <CardColorLegend cardSettings={cardSettings} bodyshop={bodyshop} />}
|
||||||
<Space>
|
style={{ paddingInline: 0, paddingBlock: 0 }}
|
||||||
<Statistic title={t("dashboard.titles.productionhours")} value={totalHrs} />
|
|
||||||
<Statistic title={t("dashboard.titles.labhours")} value={totalLAB} />
|
|
||||||
<Statistic title={t("dashboard.titles.larhours")} value={totalLAR} />
|
|
||||||
<Statistic title={t("appointments.labels.inproduction")} value={data && data.length} />
|
|
||||||
</Space>
|
|
||||||
}
|
|
||||||
extra={
|
extra={
|
||||||
<Space wrap>
|
<Space wrap>
|
||||||
<Button onClick={() => refetch && refetch()}>
|
<Button onClick={() => refetch && refetch()}>
|
||||||
@@ -256,11 +238,16 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
|||||||
</Space>
|
</Space>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{cardSettings.cardcolor && <CardColorLegend cardSettings={cardSettings} bodyshop={bodyshop} />}
|
|
||||||
|
|
||||||
<ProductionListDetailComponent jobs={data} />
|
<ProductionListDetailComponent jobs={data} />
|
||||||
|
|
||||||
<Board data={boardLanes} onDragEnd={onDragEnd} orientation={orientation} cardSettings={cardSettings} />
|
<Board
|
||||||
|
queryData={data}
|
||||||
|
data={boardLanes}
|
||||||
|
onDragEnd={onDragEnd}
|
||||||
|
orientation={orientation}
|
||||||
|
cardSettings={cardSettings}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ import React, { useEffect, useMemo } from "react";
|
|||||||
import { useQuery, useSubscription } from "@apollo/client";
|
import { useQuery, useSubscription } from "@apollo/client";
|
||||||
import { connect } from "react-redux";
|
import { connect } from "react-redux";
|
||||||
import { createStructuredSelector } from "reselect";
|
import { createStructuredSelector } from "reselect";
|
||||||
import {
|
import { QUERY_JOBS_IN_PRODUCTION, SUBSCRIPTION_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries";
|
||||||
QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES,
|
|
||||||
SUBSCRIPTION_JOBS_IN_PRODUCTION_WITH_STATUSES
|
|
||||||
} from "../../graphql/jobs.queries";
|
|
||||||
import { QUERY_KANBAN_SETTINGS } from "../../graphql/user.queries";
|
import { QUERY_KANBAN_SETTINGS } from "../../graphql/user.queries";
|
||||||
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||||
import ProductionBoardKanbanComponent from "./production-board-kanban.component";
|
import ProductionBoardKanbanComponent from "./production-board-kanban.component";
|
||||||
@@ -24,16 +21,14 @@ function ProductionBoardKanbanContainer({ bodyshop, currentUser }) {
|
|||||||
[bodyshop.md_ro_statuses.production_statuses, bodyshop.md_ro_statuses.additional_board_statuses]
|
[bodyshop.md_ro_statuses.production_statuses, bodyshop.md_ro_statuses.additional_board_statuses]
|
||||||
);
|
);
|
||||||
|
|
||||||
const { refetch, loading, data } = useQuery(QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES, {
|
const { refetch, loading, data } = useQuery(QUERY_JOBS_IN_PRODUCTION, {
|
||||||
variables: { statuses: combinedStatuses },
|
|
||||||
pollInterval: 3600000,
|
pollInterval: 3600000,
|
||||||
fetchPolicy: "network-only",
|
fetchPolicy: "network-only",
|
||||||
nextFetchPolicy: "network-only",
|
nextFetchPolicy: "network-only",
|
||||||
onError: (error) => console.error(`Error fetching jobs in production: ${error.message}`)
|
onError: (error) => console.error(`Error fetching jobs in production: ${error.message}`)
|
||||||
});
|
});
|
||||||
|
|
||||||
const { data: updatedJobs } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION_WITH_STATUSES, {
|
const { data: updatedJobs } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION, {
|
||||||
variables: { statuses: combinedStatuses },
|
|
||||||
onError: (error) => console.error(`Error subscribing to jobs in production: ${error.message}`)
|
onError: (error) => console.error(`Error subscribing to jobs in production: ${error.message}`)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// ProductionBoardKanbanSettings.jsx
|
||||||
import { useMutation } from "@apollo/client";
|
import { useMutation } from "@apollo/client";
|
||||||
import { Button, Card, Checkbox, Col, Form, notification, Popover, Radio, Row } from "antd";
|
import { Button, Card, Checkbox, Col, Form, notification, Popover, Radio, Row } from "antd";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
@@ -121,6 +122,22 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
|||||||
].map((item) => renderCheckboxItem(item, `production.labels.${item}`))}
|
].map((item) => renderCheckboxItem(item, `production.labels.${item}`))}
|
||||||
</Row>
|
</Row>
|
||||||
</Card>
|
</Card>
|
||||||
|
<Card title={t("production.settings.statistics_title")} style={cardStyle}>
|
||||||
|
<Row gutter={[16, 16]}>
|
||||||
|
{[
|
||||||
|
{ name: "totalHrs", label: "total_hours_in_production" },
|
||||||
|
{ name: "totalLAB", label: "total_lab_in_production" },
|
||||||
|
{ name: "totalLAR", label: "total_lar_in_production" },
|
||||||
|
{ name: "totalAmountInProduction", label: "total_amount_in_production" },
|
||||||
|
{ name: "jobsInProduction", label: "jobs_in_production" },
|
||||||
|
{ name: "totalHrsOnBoard", label: "total_hours_on_board" },
|
||||||
|
{ name: "totalLABOnBoard", label: "total_lab_on_board" },
|
||||||
|
{ name: "totalLAROnBoard", label: "total_lar_on_board" },
|
||||||
|
{ name: "jobsOnBoard", label: "total_jobs_on_board" },
|
||||||
|
{ name: "totalAmountOnBoard", label: "total_amount_on_board" }
|
||||||
|
].map((item) => renderCheckboxItem(item.name, `production.settings.statistics.${item.label}`))}
|
||||||
|
</Row>
|
||||||
|
</Card>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,145 @@
|
|||||||
|
import React, { useMemo } from "react";
|
||||||
|
import { Statistic, Card } from "antd";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
const ProductionStatistics = ({ data, cardSettings, reducerData }) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const calculateTotal = (items, key, subKey) => {
|
||||||
|
return items.reduce((acc, item) => acc + (item[key]?.aggregate?.sum?.[subKey] || 0), 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateTotalAmount = (items, key) => {
|
||||||
|
return items.reduce((acc, item) => acc + (item[key]?.totals?.subtotal?.amount || 0), 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateReducerTotal = (lanes, key, subKey) => {
|
||||||
|
return lanes.reduce((acc, lane) => {
|
||||||
|
return (
|
||||||
|
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata[key]?.aggregate?.sum?.[subKey] || 0), 0)
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const calculateReducerTotalAmount = (lanes, key) => {
|
||||||
|
return lanes.reduce((acc, lane) => {
|
||||||
|
return (
|
||||||
|
acc + lane.cards.reduce((laneAcc, card) => laneAcc + (card.metadata[key]?.totals?.subtotal?.amount || 0), 0)
|
||||||
|
);
|
||||||
|
}, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatValue = (value, type) => {
|
||||||
|
if (type === "Jobs") {
|
||||||
|
return value.toFixed(0);
|
||||||
|
}
|
||||||
|
if (type === "Hrs") {
|
||||||
|
return value.toFixed(2);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
const totalHrs = useMemo(() => {
|
||||||
|
if (!cardSettings.totalHrs) return null;
|
||||||
|
const total = calculateTotal(data, "labhrs", "mod_lb_hrs") + calculateTotal(data, "larhrs", "mod_lb_hrs");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [data, cardSettings.totalHrs]);
|
||||||
|
|
||||||
|
const totalLAB = useMemo(() => {
|
||||||
|
if (!cardSettings.totalLAB) return null;
|
||||||
|
const total = calculateTotal(data, "labhrs", "mod_lb_hrs");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [data, cardSettings.totalLAB]);
|
||||||
|
|
||||||
|
const totalLAR = useMemo(() => {
|
||||||
|
if (!cardSettings.totalLAR) return null;
|
||||||
|
const total = calculateTotal(data, "larhrs", "mod_lb_hrs");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [data, cardSettings.totalLAR]);
|
||||||
|
|
||||||
|
const jobsInProduction = useMemo(
|
||||||
|
() => (cardSettings.jobsInProduction ? data.length : null),
|
||||||
|
[data, cardSettings.jobsInProduction]
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalAmountInProduction = useMemo(() => {
|
||||||
|
if (!cardSettings.totalAmountInProduction) return null;
|
||||||
|
const total = calculateTotalAmount(data, "job_totals");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [data, cardSettings.totalAmountInProduction]);
|
||||||
|
|
||||||
|
const totalHrsOnBoard = useMemo(() => {
|
||||||
|
if (!reducerData || !cardSettings.totalHrsOnBoard) return null;
|
||||||
|
const total =
|
||||||
|
calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs") +
|
||||||
|
calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [reducerData, cardSettings.totalHrsOnBoard]);
|
||||||
|
|
||||||
|
const totalLABOnBoard = useMemo(() => {
|
||||||
|
if (!reducerData || !cardSettings.totalLABOnBoard) return null;
|
||||||
|
const total = calculateReducerTotal(reducerData.lanes, "labhrs", "mod_lb_hrs");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [reducerData, cardSettings.totalLABOnBoard]);
|
||||||
|
|
||||||
|
const totalLAROnBoard = useMemo(() => {
|
||||||
|
if (!reducerData || !cardSettings.totalLAROnBoard) return null;
|
||||||
|
const total = calculateReducerTotal(reducerData.lanes, "larhrs", "mod_lb_hrs");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [reducerData, cardSettings.totalLAROnBoard]);
|
||||||
|
|
||||||
|
const jobsOnBoard = useMemo(
|
||||||
|
() =>
|
||||||
|
reducerData && cardSettings.jobsOnBoard
|
||||||
|
? reducerData.lanes.reduce((acc, lane) => acc + lane.cards.length, 0)
|
||||||
|
: null,
|
||||||
|
[reducerData, cardSettings.jobsOnBoard]
|
||||||
|
);
|
||||||
|
|
||||||
|
const totalAmountOnBoard = useMemo(() => {
|
||||||
|
if (!reducerData || !cardSettings.totalAmountOnBoard) return null;
|
||||||
|
const total = calculateReducerTotalAmount(reducerData.lanes, "job_totals");
|
||||||
|
return parseFloat(total.toFixed(2));
|
||||||
|
}, [reducerData, cardSettings.totalAmountOnBoard]);
|
||||||
|
|
||||||
|
const statistics = [
|
||||||
|
{ value: totalHrs, title: t("total_hours_in_production"), suffix: t("production.statistics.hours") },
|
||||||
|
{
|
||||||
|
value: totalAmountInProduction,
|
||||||
|
title: t("total_amount_in_production"),
|
||||||
|
prefix: t("production.statistics.currency_symbol")
|
||||||
|
},
|
||||||
|
{ value: totalLAB, title: t("total_lab_in_production"), suffix: t("production.statistics.hours") },
|
||||||
|
{ value: totalLAR, title: t("total_lar_in_production"), suffix: t("production.statistics.hours") },
|
||||||
|
{ value: jobsInProduction, title: t("jobs_in_production"), suffix: "Jobs" },
|
||||||
|
{ value: totalHrsOnBoard, title: t("total_hours_on_board"), suffix: t("production.statistics.hours") },
|
||||||
|
{
|
||||||
|
value: totalAmountOnBoard,
|
||||||
|
title: t("total_amount_on_board"),
|
||||||
|
prefix: t("production.statistics.currency_symbol")
|
||||||
|
},
|
||||||
|
{ value: totalLABOnBoard, title: t("total_lab_on_board"), suffix: t("production.statistics.hours") },
|
||||||
|
{ value: totalLAROnBoard, title: t("total_lar_on_board"), suffix: t("production.statistics.hours") },
|
||||||
|
{ value: jobsOnBoard, title: t("total_jobs_on_board"), suffix: "Jobs" }
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ display: "flex", gap: "5px", flexWrap: "wrap", marginBottom: "5px" }}>
|
||||||
|
{statistics.map(
|
||||||
|
(stat, index) =>
|
||||||
|
stat.value !== null && (
|
||||||
|
<Card key={index}>
|
||||||
|
<Statistic
|
||||||
|
title={t(`production.statistics.${stat.title}`)}
|
||||||
|
value={formatValue(stat.value, stat.suffix)}
|
||||||
|
prefix={stat.prefix}
|
||||||
|
suffix={stat.suffix}
|
||||||
|
/>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProductionStatistics;
|
||||||
@@ -7,6 +7,7 @@ import Lane from "./Lane";
|
|||||||
import { PopoverWrapper } from "react-popopo";
|
import { PopoverWrapper } from "react-popopo";
|
||||||
import * as actions from "../../../../redux/trello/trello.actions.js";
|
import * as actions from "../../../../redux/trello/trello.actions.js";
|
||||||
import { BoardWrapper } from "../styles/Base.js";
|
import { BoardWrapper } from "../styles/Base.js";
|
||||||
|
import ProductionStatistics from "../../production-board-kanban.statistics.jsx";
|
||||||
|
|
||||||
const useDragMap = () => {
|
const useDragMap = () => {
|
||||||
const dragMapRef = useRef(new Map());
|
const dragMapRef = useRef(new Map());
|
||||||
@@ -30,7 +31,8 @@ const BoardContainer = ({
|
|||||||
orientation = "horizontal",
|
orientation = "horizontal",
|
||||||
cardSettings = {},
|
cardSettings = {},
|
||||||
eventBusHandle,
|
eventBusHandle,
|
||||||
reducerData
|
reducerData,
|
||||||
|
queryData
|
||||||
}) => {
|
}) => {
|
||||||
const [isDragging, setIsDragging] = useState(false);
|
const [isDragging, setIsDragging] = useState(false);
|
||||||
const [isProcessing, setIsProcessing] = useState(false);
|
const [isProcessing, setIsProcessing] = useState(false);
|
||||||
@@ -124,33 +126,36 @@ const BoardContainer = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopoverWrapper>
|
<div>
|
||||||
<BoardWrapper orientation={orientation}>
|
<ProductionStatistics data={queryData} reducerData={currentReducerData} cardSettings={cardSettings} />
|
||||||
<DragDropContext onDragEnd={onLaneDrag} onDragStart={onDragStart} contextId="production-board">
|
<PopoverWrapper>
|
||||||
{currentReducerData.lanes.map((lane, index) => (
|
<BoardWrapper orientation={orientation}>
|
||||||
<Lane
|
<DragDropContext onDragEnd={onLaneDrag} onDragStart={onDragStart} contextId="production-board">
|
||||||
key={lane.id}
|
{currentReducerData.lanes.map((lane, index) => (
|
||||||
id={lane.id}
|
<Lane
|
||||||
title={lane.title}
|
key={lane.id}
|
||||||
index={index}
|
id={lane.id}
|
||||||
laneSortFunction={laneSortFunction}
|
title={lane.title}
|
||||||
orientation={orientation}
|
index={index}
|
||||||
cards={lane.cards}
|
laneSortFunction={laneSortFunction}
|
||||||
isDragging={isDragging}
|
orientation={orientation}
|
||||||
isProcessing={isProcessing}
|
cards={lane.cards}
|
||||||
cardSettings={cardSettings}
|
isDragging={isDragging}
|
||||||
maxLaneHeight={maxLaneHeight}
|
isProcessing={isProcessing}
|
||||||
setMaxLaneHeight={setMaxLaneHeight}
|
cardSettings={cardSettings}
|
||||||
maxCardHeight={maxCardHeight}
|
maxLaneHeight={maxLaneHeight}
|
||||||
setMaxCardHeight={setMaxCardHeight}
|
setMaxLaneHeight={setMaxLaneHeight}
|
||||||
maxCardWidth={maxCardWidth}
|
maxCardHeight={maxCardHeight}
|
||||||
setMaxCardWidth={setMaxCardWidth}
|
setMaxCardHeight={setMaxCardHeight}
|
||||||
lastDrag={getLastDragTime(lane.id)}
|
maxCardWidth={maxCardWidth}
|
||||||
/>
|
setMaxCardWidth={setMaxCardWidth}
|
||||||
))}
|
lastDrag={getLastDragTime(lane.id)}
|
||||||
</DragDropContext>
|
/>
|
||||||
</BoardWrapper>
|
))}
|
||||||
</PopoverWrapper>
|
</DragDropContext>
|
||||||
|
</BoardWrapper>
|
||||||
|
</PopoverWrapper>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -292,82 +292,6 @@ export const QUERY_EXACT_JOBS_IN_PRODUCTION = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const QUERY_JOBS_IN_PRODUCTION = gql`
|
|
||||||
query QUERY_JOBS_IN_PRODUCTION {
|
|
||||||
jobs(where: { inproduction: { _eq: true } }) {
|
|
||||||
id
|
|
||||||
updated_at
|
|
||||||
comment
|
|
||||||
status
|
|
||||||
category
|
|
||||||
iouparent
|
|
||||||
ro_number
|
|
||||||
ownerid
|
|
||||||
ownr_fn
|
|
||||||
ownr_ln
|
|
||||||
ownr_co_nm
|
|
||||||
v_model_yr
|
|
||||||
v_model_desc
|
|
||||||
clm_no
|
|
||||||
v_make_desc
|
|
||||||
v_color
|
|
||||||
vehicleid
|
|
||||||
plate_no
|
|
||||||
actual_in
|
|
||||||
scheduled_completion
|
|
||||||
scheduled_delivery
|
|
||||||
date_last_contacted
|
|
||||||
date_next_contact
|
|
||||||
ins_co_nm
|
|
||||||
clm_total
|
|
||||||
ownr_ph1
|
|
||||||
ownr_ph2
|
|
||||||
special_coverage_policy
|
|
||||||
owner_owing
|
|
||||||
production_vars
|
|
||||||
kanbanparent
|
|
||||||
alt_transport
|
|
||||||
employee_body
|
|
||||||
employee_refinish
|
|
||||||
employee_prep
|
|
||||||
employee_csr
|
|
||||||
est_ct_fn
|
|
||||||
est_ct_ln
|
|
||||||
suspended
|
|
||||||
date_repairstarted
|
|
||||||
joblines_status {
|
|
||||||
part_type
|
|
||||||
status
|
|
||||||
count
|
|
||||||
}
|
|
||||||
labhrs: joblines_aggregate(where: { _and: [{ mod_lbr_ty: { _neq: "LAR" } }, { removed: { _eq: false } }] }) {
|
|
||||||
aggregate {
|
|
||||||
sum {
|
|
||||||
mod_lb_hrs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
larhrs: joblines_aggregate(where: { _and: [{ mod_lbr_ty: { _eq: "LAR" } }, { removed: { _eq: false } }] }) {
|
|
||||||
aggregate {
|
|
||||||
sum {
|
|
||||||
mod_lb_hrs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
subletLines: joblines(
|
|
||||||
where: { _and: { part_type: { _in: ["PAS", "PASL"] }, removed: { _eq: false } } }
|
|
||||||
order_by: { line_no: asc }
|
|
||||||
) {
|
|
||||||
id
|
|
||||||
line_desc
|
|
||||||
sublet_ignored
|
|
||||||
sublet_completed
|
|
||||||
jobid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const QUERY_LBR_HRS_BY_PK = gql`
|
export const QUERY_LBR_HRS_BY_PK = gql`
|
||||||
query QUERY_LBR_HRS_BY_PK($id: uuid!) {
|
query QUERY_LBR_HRS_BY_PK($id: uuid!) {
|
||||||
jobs_by_pk(id: $id) {
|
jobs_by_pk(id: $id) {
|
||||||
@@ -2529,9 +2453,18 @@ export const QUERY_PARTS_QUEUE_CARD_DETAILS = gql`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES = gql`
|
export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
|
||||||
query QUERY_JOBS_IN_PRODUCTION($statuses: [String!]) {
|
subscription SUBSCRIPTION_JOBS_IN_PRODUCTION {
|
||||||
jobs(where: { inproduction: { _eq: true }, status: { _in: $statuses } }) {
|
jobs(where: { inproduction: { _eq: true } }) {
|
||||||
|
id
|
||||||
|
updated_at
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const QUERY_JOBS_IN_PRODUCTION = gql`
|
||||||
|
query QUERY_JOBS_IN_PRODUCTION {
|
||||||
|
jobs(where: { inproduction: { _eq: true } }) {
|
||||||
id
|
id
|
||||||
updated_at
|
updated_at
|
||||||
comment
|
comment
|
||||||
@@ -2571,6 +2504,7 @@ export const QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES = gql`
|
|||||||
est_ct_fn
|
est_ct_fn
|
||||||
est_ct_ln
|
est_ct_ln
|
||||||
suspended
|
suspended
|
||||||
|
job_totals
|
||||||
date_repairstarted
|
date_repairstarted
|
||||||
joblines_status {
|
joblines_status {
|
||||||
part_type
|
part_type
|
||||||
@@ -2604,21 +2538,3 @@ export const QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES = gql`
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const SUBSCRIPTION_JOBS_IN_PRODUCTION_WITH_STATUSES = gql`
|
|
||||||
subscription SUBSCRIPTION_JOBS_IN_PRODUCTION($statuses: [String!]) {
|
|
||||||
jobs(where: { inproduction: { _eq: true }, status: { _in: $statuses } }) {
|
|
||||||
id
|
|
||||||
updated_at
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
|
|
||||||
subscription SUBSCRIPTION_JOBS_IN_PRODUCTION {
|
|
||||||
jobs(where: { inproduction: { _eq: true } }) {
|
|
||||||
id
|
|
||||||
updated_at
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|||||||
@@ -2733,11 +2733,19 @@
|
|||||||
"settings": {
|
"settings": {
|
||||||
"layout": "Layout",
|
"layout": "Layout",
|
||||||
"information": "Information",
|
"information": "Information",
|
||||||
|
"statistics_title": "Statistics",
|
||||||
"board_settings": "Board Settings",
|
"board_settings": "Board Settings",
|
||||||
"tabs": {
|
"statistics": {
|
||||||
"card": "Card",
|
"total_hours_in_production": "Hours in Production",
|
||||||
"board": "Board",
|
"total_lab_in_production": "Body Hours in Production",
|
||||||
"lane": "Lane"
|
"total_lar_in_production": "Refinish Hours in Production",
|
||||||
|
"total_amount_in_production": "Dollars in Production",
|
||||||
|
"jobs_in_production": "Jobs in Production",
|
||||||
|
"total_hours_on_board": "Hours on Board",
|
||||||
|
"total_lab_on_board": "Body Hours on Board",
|
||||||
|
"total_lar_on_board": "Refinish Hours on Board",
|
||||||
|
"total_amount_on_board": "Dollars on Board",
|
||||||
|
"total_jobs_on_board": "Jobs on Board"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -2811,7 +2819,21 @@
|
|||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"removed": "Job removed from production."
|
"removed": "Job removed from production."
|
||||||
}
|
},
|
||||||
|
"statistics": {
|
||||||
|
"total_hours_in_production": "Hours in Production",
|
||||||
|
"total_lab_in_production": "Body Hours in Production",
|
||||||
|
"total_lar_in_production": "Refinish Hours in Production",
|
||||||
|
"total_amount_in_production": "Dollars in Production",
|
||||||
|
"jobs_in_production": "Jobs in Production",
|
||||||
|
"total_hours_on_board": "Hours on Board",
|
||||||
|
"total_lab_on_board": "Body Hours on Board",
|
||||||
|
"total_lar_on_board": "Refinish Hours on Board",
|
||||||
|
"total_amount_on_board": "Dollars on Board",
|
||||||
|
"total_jobs_on_board": "Jobs on Board",
|
||||||
|
"hours": "Hours",
|
||||||
|
"currency_symbol": "$"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"errors": {
|
"errors": {
|
||||||
|
|||||||
@@ -2722,27 +2722,52 @@
|
|||||||
"purchases_by_vendor_summary": ""
|
"purchases_by_vendor_summary": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"production": {
|
"production": {
|
||||||
"actions": {
|
"options": {
|
||||||
"addcolumns": "",
|
"small": "",
|
||||||
"bodypriority-clear": "",
|
"medium": "",
|
||||||
"bodypriority-set": "",
|
"large": "",
|
||||||
"detailpriority-clear": "",
|
"vertical": "",
|
||||||
"detailpriority-set": "",
|
"horizontal": ""
|
||||||
"paintpriority-clear": "",
|
},
|
||||||
"paintpriority-set": "",
|
"settings": {
|
||||||
"remove": "",
|
"layout": "",
|
||||||
"removecolumn": "",
|
"information": "",
|
||||||
"saveconfig": "",
|
"statistics_title": "",
|
||||||
"suspend": "",
|
"board_settings": "",
|
||||||
"unsuspend": ""
|
"statistics": {
|
||||||
},
|
"total_hours_in_production": "",
|
||||||
"errors": {
|
"total_lab_in_production": "",
|
||||||
"boardupdate": "",
|
"total_lar_in_production": "",
|
||||||
"removing": "",
|
"total_amount_in_production": "",
|
||||||
"settings": ""
|
"jobs_in_production": "",
|
||||||
},
|
"total_hours_on_board": "",
|
||||||
"labels": {
|
"total_lab_on_board": "",
|
||||||
|
"total_lar_on_board": "",
|
||||||
|
"total_amount_on_board": "",
|
||||||
|
"total_jobs_on_board": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"addcolumns": "",
|
||||||
|
"bodypriority-clear": "",
|
||||||
|
"bodypriority-set": "",
|
||||||
|
"detailpriority-clear": "",
|
||||||
|
"detailpriority-set": "",
|
||||||
|
"paintpriority-clear": "",
|
||||||
|
"paintpriority-set": "",
|
||||||
|
"remove": "",
|
||||||
|
"removecolumn": "",
|
||||||
|
"saveconfig": "",
|
||||||
|
"suspend": "",
|
||||||
|
"unsuspend": ""
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"boardupdate": "",
|
||||||
|
"removing": "",
|
||||||
|
"settings": ""
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
"kiosk_mode": "",
|
"kiosk_mode": "",
|
||||||
"on": "",
|
"on": "",
|
||||||
"off": "",
|
"off": "",
|
||||||
@@ -2754,48 +2779,62 @@
|
|||||||
"card_size": "",
|
"card_size": "",
|
||||||
"model_info": "",
|
"model_info": "",
|
||||||
"actual_in": "",
|
"actual_in": "",
|
||||||
"alert": "",
|
"alert": "",
|
||||||
"alertoff": "",
|
"alertoff": "",
|
||||||
"alerton": "",
|
"alerton": "",
|
||||||
"ats": "",
|
"ats": "",
|
||||||
"bodyhours": "",
|
"bodyhours": "",
|
||||||
"bodypriority": "",
|
"bodypriority": "",
|
||||||
"bodyshop": {
|
"bodyshop": {
|
||||||
"labels": {
|
"labels": {
|
||||||
"qbo_departmentid": "",
|
"qbo_departmentid": "",
|
||||||
"qbo_usa": ""
|
"qbo_usa": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardcolor": "",
|
"cardcolor": "",
|
||||||
"cardsettings": "",
|
"cardsettings": "",
|
||||||
"clm_no": "",
|
"clm_no": "",
|
||||||
"comment": "",
|
"comment": "",
|
||||||
"compact": "",
|
"compact": "",
|
||||||
"detailpriority": "",
|
"detailpriority": "",
|
||||||
"employeeassignments": "",
|
"employeeassignments": "",
|
||||||
"employeesearch": "",
|
"employeesearch": "",
|
||||||
"ins_co_nm": "",
|
"ins_co_nm": "",
|
||||||
"jobdetail": "",
|
"jobdetail": "",
|
||||||
"laborhrs": "",
|
"laborhrs": "",
|
||||||
"legend": "",
|
"legend": "",
|
||||||
"note": "",
|
"note": "",
|
||||||
"ownr_nm": "",
|
"ownr_nm": "",
|
||||||
"paintpriority": "",
|
"paintpriority": "",
|
||||||
"partsstatus": "",
|
"partsstatus": "",
|
||||||
"production_note": "",
|
"production_note": "",
|
||||||
"refinishhours": "",
|
"refinishhours": "",
|
||||||
"scheduled_completion": "",
|
"scheduled_completion": "",
|
||||||
"selectview": "",
|
"selectview": "",
|
||||||
"stickyheader": "",
|
"stickyheader": "",
|
||||||
"sublets": "",
|
"sublets": "",
|
||||||
"totalhours": "",
|
"totalhours": "",
|
||||||
"touchtime": "",
|
"touchtime": "",
|
||||||
"viewname": ""
|
"viewname": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"removed": ""
|
"removed": ""
|
||||||
}
|
},
|
||||||
},
|
"statistics": {
|
||||||
|
"total_hours_in_production": "",
|
||||||
|
"total_lab_in_production": "",
|
||||||
|
"total_lar_in_production": "",
|
||||||
|
"total_amount_in_production": "",
|
||||||
|
"jobs_in_production": "",
|
||||||
|
"total_hours_on_board": "",
|
||||||
|
"total_lab_on_board": "",
|
||||||
|
"total_lar_on_board": "",
|
||||||
|
"total_amount_on_board": "",
|
||||||
|
"total_jobs_on_board": "",
|
||||||
|
"hours": "",
|
||||||
|
"currency_symbol": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"errors": {
|
"errors": {
|
||||||
"state": "Error al leer el estado de la página. Porfavor refresca."
|
"state": "Error al leer el estado de la página. Porfavor refresca."
|
||||||
|
|||||||
@@ -2722,72 +2722,119 @@
|
|||||||
"purchases_by_vendor_summary": ""
|
"purchases_by_vendor_summary": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"production": {
|
"production": {
|
||||||
"actions": {
|
"options": {
|
||||||
"addcolumns": "",
|
"small": "",
|
||||||
"bodypriority-clear": "",
|
"medium": "",
|
||||||
"bodypriority-set": "",
|
"large": "",
|
||||||
"detailpriority-clear": "",
|
"vertical": "",
|
||||||
"detailpriority-set": "",
|
"horizontal": ""
|
||||||
"paintpriority-clear": "",
|
},
|
||||||
"paintpriority-set": "",
|
"settings": {
|
||||||
"remove": "",
|
"layout": "",
|
||||||
"removecolumn": "",
|
"information": "",
|
||||||
"saveconfig": "",
|
"statistics_title": "",
|
||||||
"suspend": "",
|
"board_settings": "",
|
||||||
"unsuspend": ""
|
"statistics": {
|
||||||
},
|
"total_hours_in_production": "",
|
||||||
"errors": {
|
"total_lab_in_production": "",
|
||||||
"boardupdate": "",
|
"total_lar_in_production": "",
|
||||||
"removing": "",
|
"total_amount_in_production": "",
|
||||||
"settings": ""
|
"jobs_in_production": "",
|
||||||
},
|
"total_hours_on_board": "",
|
||||||
"labels": {
|
"total_lab_on_board": "",
|
||||||
|
"total_lar_on_board": "",
|
||||||
|
"total_amount_on_board": "",
|
||||||
|
"total_jobs_on_board": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"actions": {
|
||||||
|
"addcolumns": "",
|
||||||
|
"bodypriority-clear": "",
|
||||||
|
"bodypriority-set": "",
|
||||||
|
"detailpriority-clear": "",
|
||||||
|
"detailpriority-set": "",
|
||||||
|
"paintpriority-clear": "",
|
||||||
|
"paintpriority-set": "",
|
||||||
|
"remove": "",
|
||||||
|
"removecolumn": "",
|
||||||
|
"saveconfig": "",
|
||||||
|
"suspend": "",
|
||||||
|
"unsuspend": ""
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"boardupdate": "",
|
||||||
|
"removing": "",
|
||||||
|
"settings": ""
|
||||||
|
},
|
||||||
|
"labels": {
|
||||||
"kiosk_mode": "",
|
"kiosk_mode": "",
|
||||||
|
"on": "",
|
||||||
|
"off": "",
|
||||||
|
"wide": "",
|
||||||
|
"tall": "",
|
||||||
|
"vertical": "",
|
||||||
|
"horizontal": "",
|
||||||
|
"orientation": "",
|
||||||
|
"card_size": "",
|
||||||
"model_info": "",
|
"model_info": "",
|
||||||
"actual_in": "",
|
"actual_in": "",
|
||||||
"alert": "",
|
"alert": "",
|
||||||
"alertoff": "",
|
"alertoff": "",
|
||||||
"alerton": "",
|
"alerton": "",
|
||||||
"ats": "",
|
"ats": "",
|
||||||
"bodyhours": "",
|
"bodyhours": "",
|
||||||
"bodypriority": "",
|
"bodypriority": "",
|
||||||
"bodyshop": {
|
"bodyshop": {
|
||||||
"labels": {
|
"labels": {
|
||||||
"qbo_departmentid": "",
|
"qbo_departmentid": "",
|
||||||
"qbo_usa": ""
|
"qbo_usa": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"cardcolor": "",
|
"cardcolor": "",
|
||||||
"cardsettings": "",
|
"cardsettings": "",
|
||||||
"clm_no": "",
|
"clm_no": "",
|
||||||
"comment": "",
|
"comment": "",
|
||||||
"compact": "",
|
"compact": "",
|
||||||
"detailpriority": "",
|
"detailpriority": "",
|
||||||
"employeeassignments": "",
|
"employeeassignments": "",
|
||||||
"employeesearch": "",
|
"employeesearch": "",
|
||||||
"ins_co_nm": "",
|
"ins_co_nm": "",
|
||||||
"jobdetail": "",
|
"jobdetail": "",
|
||||||
"laborhrs": "",
|
"laborhrs": "",
|
||||||
"legend": "",
|
"legend": "",
|
||||||
"note": "",
|
"note": "",
|
||||||
"ownr_nm": "",
|
"ownr_nm": "",
|
||||||
"paintpriority": "",
|
"paintpriority": "",
|
||||||
"partsstatus": "",
|
"partsstatus": "",
|
||||||
"production_note": "",
|
"production_note": "",
|
||||||
"refinishhours": "",
|
"refinishhours": "",
|
||||||
"scheduled_completion": "",
|
"scheduled_completion": "",
|
||||||
"selectview": "",
|
"selectview": "",
|
||||||
"stickyheader": "",
|
"stickyheader": "",
|
||||||
"sublets": "",
|
"sublets": "",
|
||||||
"totalhours": "",
|
"totalhours": "",
|
||||||
"touchtime": "",
|
"touchtime": "",
|
||||||
"viewname": ""
|
"viewname": ""
|
||||||
},
|
},
|
||||||
"successes": {
|
"successes": {
|
||||||
"removed": ""
|
"removed": ""
|
||||||
}
|
},
|
||||||
},
|
"statistics": {
|
||||||
|
"total_hours_in_production": "",
|
||||||
|
"total_lab_in_production": "",
|
||||||
|
"total_lar_in_production": "",
|
||||||
|
"total_amount_in_production": "",
|
||||||
|
"jobs_in_production": "",
|
||||||
|
"total_hours_on_board": "",
|
||||||
|
"total_lab_on_board": "",
|
||||||
|
"total_lar_on_board": "",
|
||||||
|
"total_amount_on_board": "",
|
||||||
|
"total_jobs_on_board": "",
|
||||||
|
"hours": "",
|
||||||
|
"currency_symbol": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
"profile": {
|
"profile": {
|
||||||
"errors": {
|
"errors": {
|
||||||
"state": "Erreur lors de la lecture de l'état de la page. Rafraichissez, s'il vous plait."
|
"state": "Erreur lors de la lecture de l'état de la page. Rafraichissez, s'il vous plait."
|
||||||
|
|||||||
Reference in New Issue
Block a user