- 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 (
|
||||
<Col style={{ marginLeft: "15px" }}>
|
||||
<Col>
|
||||
<Typography>{t("production.labels.legend")}</Typography>
|
||||
<List
|
||||
grid={{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { SyncOutlined } from "@ant-design/icons";
|
||||
import { useApolloClient } from "@apollo/client";
|
||||
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 React, { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
@@ -175,28 +175,6 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
[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(
|
||||
() =>
|
||||
associationSettings?.kanban_settings && Object.keys(associationSettings.kanban_settings).length > 0
|
||||
@@ -215,7 +193,17 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
orientation: false,
|
||||
cardSize: "small",
|
||||
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]
|
||||
);
|
||||
@@ -234,14 +222,8 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
<div>
|
||||
<IndefiniteLoading loading={isMoving} />
|
||||
<PageHeader
|
||||
title={
|
||||
<Space>
|
||||
<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>
|
||||
}
|
||||
title={cardSettings.cardcolor && <CardColorLegend cardSettings={cardSettings} bodyshop={bodyshop} />}
|
||||
style={{ paddingInline: 0, paddingBlock: 0 }}
|
||||
extra={
|
||||
<Space wrap>
|
||||
<Button onClick={() => refetch && refetch()}>
|
||||
@@ -256,11 +238,16 @@ function ProductionBoardKanbanComponent({ data, bodyshop, refetch, insertAuditTr
|
||||
</Space>
|
||||
}
|
||||
/>
|
||||
{cardSettings.cardcolor && <CardColorLegend cardSettings={cardSettings} bodyshop={bodyshop} />}
|
||||
|
||||
<ProductionListDetailComponent jobs={data} />
|
||||
|
||||
<Board data={boardLanes} onDragEnd={onDragEnd} orientation={orientation} cardSettings={cardSettings} />
|
||||
<Board
|
||||
queryData={data}
|
||||
data={boardLanes}
|
||||
onDragEnd={onDragEnd}
|
||||
orientation={orientation}
|
||||
cardSettings={cardSettings}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@ import React, { useEffect, useMemo } from "react";
|
||||
import { useQuery, useSubscription } from "@apollo/client";
|
||||
import { connect } from "react-redux";
|
||||
import { createStructuredSelector } from "reselect";
|
||||
import {
|
||||
QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES,
|
||||
SUBSCRIPTION_JOBS_IN_PRODUCTION_WITH_STATUSES
|
||||
} from "../../graphql/jobs.queries";
|
||||
import { QUERY_JOBS_IN_PRODUCTION, SUBSCRIPTION_JOBS_IN_PRODUCTION } from "../../graphql/jobs.queries";
|
||||
import { QUERY_KANBAN_SETTINGS } from "../../graphql/user.queries";
|
||||
import { selectBodyshop, selectCurrentUser } from "../../redux/user/user.selectors";
|
||||
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]
|
||||
);
|
||||
|
||||
const { refetch, loading, data } = useQuery(QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES, {
|
||||
variables: { statuses: combinedStatuses },
|
||||
const { refetch, loading, data } = useQuery(QUERY_JOBS_IN_PRODUCTION, {
|
||||
pollInterval: 3600000,
|
||||
fetchPolicy: "network-only",
|
||||
nextFetchPolicy: "network-only",
|
||||
onError: (error) => console.error(`Error fetching jobs in production: ${error.message}`)
|
||||
});
|
||||
|
||||
const { data: updatedJobs } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION_WITH_STATUSES, {
|
||||
variables: { statuses: combinedStatuses },
|
||||
const { data: updatedJobs } = useSubscription(SUBSCRIPTION_JOBS_IN_PRODUCTION, {
|
||||
onError: (error) => console.error(`Error subscribing to jobs in production: ${error.message}`)
|
||||
});
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// ProductionBoardKanbanSettings.jsx
|
||||
import { useMutation } from "@apollo/client";
|
||||
import { Button, Card, Checkbox, Col, Form, notification, Popover, Radio, Row } from "antd";
|
||||
import React, { useEffect, useState } from "react";
|
||||
@@ -121,6 +122,22 @@ export default function ProductionBoardKanbanSettings({ associationSettings, par
|
||||
].map((item) => renderCheckboxItem(item, `production.labels.${item}`))}
|
||||
</Row>
|
||||
</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 * as actions from "../../../../redux/trello/trello.actions.js";
|
||||
import { BoardWrapper } from "../styles/Base.js";
|
||||
import ProductionStatistics from "../../production-board-kanban.statistics.jsx";
|
||||
|
||||
const useDragMap = () => {
|
||||
const dragMapRef = useRef(new Map());
|
||||
@@ -30,7 +31,8 @@ const BoardContainer = ({
|
||||
orientation = "horizontal",
|
||||
cardSettings = {},
|
||||
eventBusHandle,
|
||||
reducerData
|
||||
reducerData,
|
||||
queryData
|
||||
}) => {
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
@@ -124,33 +126,36 @@ const BoardContainer = ({
|
||||
);
|
||||
|
||||
return (
|
||||
<PopoverWrapper>
|
||||
<BoardWrapper orientation={orientation}>
|
||||
<DragDropContext onDragEnd={onLaneDrag} onDragStart={onDragStart} contextId="production-board">
|
||||
{currentReducerData.lanes.map((lane, index) => (
|
||||
<Lane
|
||||
key={lane.id}
|
||||
id={lane.id}
|
||||
title={lane.title}
|
||||
index={index}
|
||||
laneSortFunction={laneSortFunction}
|
||||
orientation={orientation}
|
||||
cards={lane.cards}
|
||||
isDragging={isDragging}
|
||||
isProcessing={isProcessing}
|
||||
cardSettings={cardSettings}
|
||||
maxLaneHeight={maxLaneHeight}
|
||||
setMaxLaneHeight={setMaxLaneHeight}
|
||||
maxCardHeight={maxCardHeight}
|
||||
setMaxCardHeight={setMaxCardHeight}
|
||||
maxCardWidth={maxCardWidth}
|
||||
setMaxCardWidth={setMaxCardWidth}
|
||||
lastDrag={getLastDragTime(lane.id)}
|
||||
/>
|
||||
))}
|
||||
</DragDropContext>
|
||||
</BoardWrapper>
|
||||
</PopoverWrapper>
|
||||
<div>
|
||||
<ProductionStatistics data={queryData} reducerData={currentReducerData} cardSettings={cardSettings} />
|
||||
<PopoverWrapper>
|
||||
<BoardWrapper orientation={orientation}>
|
||||
<DragDropContext onDragEnd={onLaneDrag} onDragStart={onDragStart} contextId="production-board">
|
||||
{currentReducerData.lanes.map((lane, index) => (
|
||||
<Lane
|
||||
key={lane.id}
|
||||
id={lane.id}
|
||||
title={lane.title}
|
||||
index={index}
|
||||
laneSortFunction={laneSortFunction}
|
||||
orientation={orientation}
|
||||
cards={lane.cards}
|
||||
isDragging={isDragging}
|
||||
isProcessing={isProcessing}
|
||||
cardSettings={cardSettings}
|
||||
maxLaneHeight={maxLaneHeight}
|
||||
setMaxLaneHeight={setMaxLaneHeight}
|
||||
maxCardHeight={maxCardHeight}
|
||||
setMaxCardHeight={setMaxCardHeight}
|
||||
maxCardWidth={maxCardWidth}
|
||||
setMaxCardWidth={setMaxCardWidth}
|
||||
lastDrag={getLastDragTime(lane.id)}
|
||||
/>
|
||||
))}
|
||||
</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`
|
||||
query QUERY_LBR_HRS_BY_PK($id: uuid!) {
|
||||
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`
|
||||
query QUERY_JOBS_IN_PRODUCTION($statuses: [String!]) {
|
||||
jobs(where: { inproduction: { _eq: true }, status: { _in: $statuses } }) {
|
||||
export const SUBSCRIPTION_JOBS_IN_PRODUCTION = gql`
|
||||
subscription SUBSCRIPTION_JOBS_IN_PRODUCTION {
|
||||
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
|
||||
updated_at
|
||||
comment
|
||||
@@ -2571,6 +2504,7 @@ export const QUERY_JOBS_IN_PRODUCTION_WITH_STATUSES = gql`
|
||||
est_ct_fn
|
||||
est_ct_ln
|
||||
suspended
|
||||
job_totals
|
||||
date_repairstarted
|
||||
joblines_status {
|
||||
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": {
|
||||
"layout": "Layout",
|
||||
"information": "Information",
|
||||
"statistics_title": "Statistics",
|
||||
"board_settings": "Board Settings",
|
||||
"tabs": {
|
||||
"card": "Card",
|
||||
"board": "Board",
|
||||
"lane": "Lane"
|
||||
"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"
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
@@ -2811,7 +2819,21 @@
|
||||
},
|
||||
"successes": {
|
||||
"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": {
|
||||
"errors": {
|
||||
|
||||
@@ -2722,27 +2722,52 @@
|
||||
"purchases_by_vendor_summary": ""
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
"actions": {
|
||||
"addcolumns": "",
|
||||
"bodypriority-clear": "",
|
||||
"bodypriority-set": "",
|
||||
"detailpriority-clear": "",
|
||||
"detailpriority-set": "",
|
||||
"paintpriority-clear": "",
|
||||
"paintpriority-set": "",
|
||||
"remove": "",
|
||||
"removecolumn": "",
|
||||
"saveconfig": "",
|
||||
"suspend": "",
|
||||
"unsuspend": ""
|
||||
},
|
||||
"errors": {
|
||||
"boardupdate": "",
|
||||
"removing": "",
|
||||
"settings": ""
|
||||
},
|
||||
"labels": {
|
||||
"production": {
|
||||
"options": {
|
||||
"small": "",
|
||||
"medium": "",
|
||||
"large": "",
|
||||
"vertical": "",
|
||||
"horizontal": ""
|
||||
},
|
||||
"settings": {
|
||||
"layout": "",
|
||||
"information": "",
|
||||
"statistics_title": "",
|
||||
"board_settings": "",
|
||||
"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": ""
|
||||
}
|
||||
},
|
||||
"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": "",
|
||||
"on": "",
|
||||
"off": "",
|
||||
@@ -2754,48 +2779,62 @@
|
||||
"card_size": "",
|
||||
"model_info": "",
|
||||
"actual_in": "",
|
||||
"alert": "",
|
||||
"alertoff": "",
|
||||
"alerton": "",
|
||||
"ats": "",
|
||||
"bodyhours": "",
|
||||
"bodypriority": "",
|
||||
"bodyshop": {
|
||||
"labels": {
|
||||
"qbo_departmentid": "",
|
||||
"qbo_usa": ""
|
||||
}
|
||||
},
|
||||
"cardcolor": "",
|
||||
"cardsettings": "",
|
||||
"clm_no": "",
|
||||
"comment": "",
|
||||
"compact": "",
|
||||
"detailpriority": "",
|
||||
"employeeassignments": "",
|
||||
"employeesearch": "",
|
||||
"ins_co_nm": "",
|
||||
"jobdetail": "",
|
||||
"laborhrs": "",
|
||||
"legend": "",
|
||||
"note": "",
|
||||
"ownr_nm": "",
|
||||
"paintpriority": "",
|
||||
"partsstatus": "",
|
||||
"production_note": "",
|
||||
"refinishhours": "",
|
||||
"scheduled_completion": "",
|
||||
"selectview": "",
|
||||
"stickyheader": "",
|
||||
"sublets": "",
|
||||
"totalhours": "",
|
||||
"touchtime": "",
|
||||
"viewname": ""
|
||||
},
|
||||
"successes": {
|
||||
"removed": ""
|
||||
}
|
||||
},
|
||||
"alert": "",
|
||||
"alertoff": "",
|
||||
"alerton": "",
|
||||
"ats": "",
|
||||
"bodyhours": "",
|
||||
"bodypriority": "",
|
||||
"bodyshop": {
|
||||
"labels": {
|
||||
"qbo_departmentid": "",
|
||||
"qbo_usa": ""
|
||||
}
|
||||
},
|
||||
"cardcolor": "",
|
||||
"cardsettings": "",
|
||||
"clm_no": "",
|
||||
"comment": "",
|
||||
"compact": "",
|
||||
"detailpriority": "",
|
||||
"employeeassignments": "",
|
||||
"employeesearch": "",
|
||||
"ins_co_nm": "",
|
||||
"jobdetail": "",
|
||||
"laborhrs": "",
|
||||
"legend": "",
|
||||
"note": "",
|
||||
"ownr_nm": "",
|
||||
"paintpriority": "",
|
||||
"partsstatus": "",
|
||||
"production_note": "",
|
||||
"refinishhours": "",
|
||||
"scheduled_completion": "",
|
||||
"selectview": "",
|
||||
"stickyheader": "",
|
||||
"sublets": "",
|
||||
"totalhours": "",
|
||||
"touchtime": "",
|
||||
"viewname": ""
|
||||
},
|
||||
"successes": {
|
||||
"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": {
|
||||
"errors": {
|
||||
"state": "Error al leer el estado de la página. Porfavor refresca."
|
||||
|
||||
@@ -2722,72 +2722,119 @@
|
||||
"purchases_by_vendor_summary": ""
|
||||
}
|
||||
},
|
||||
"production": {
|
||||
"actions": {
|
||||
"addcolumns": "",
|
||||
"bodypriority-clear": "",
|
||||
"bodypriority-set": "",
|
||||
"detailpriority-clear": "",
|
||||
"detailpriority-set": "",
|
||||
"paintpriority-clear": "",
|
||||
"paintpriority-set": "",
|
||||
"remove": "",
|
||||
"removecolumn": "",
|
||||
"saveconfig": "",
|
||||
"suspend": "",
|
||||
"unsuspend": ""
|
||||
},
|
||||
"errors": {
|
||||
"boardupdate": "",
|
||||
"removing": "",
|
||||
"settings": ""
|
||||
},
|
||||
"labels": {
|
||||
"production": {
|
||||
"options": {
|
||||
"small": "",
|
||||
"medium": "",
|
||||
"large": "",
|
||||
"vertical": "",
|
||||
"horizontal": ""
|
||||
},
|
||||
"settings": {
|
||||
"layout": "",
|
||||
"information": "",
|
||||
"statistics_title": "",
|
||||
"board_settings": "",
|
||||
"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": ""
|
||||
}
|
||||
},
|
||||
"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": "",
|
||||
"on": "",
|
||||
"off": "",
|
||||
"wide": "",
|
||||
"tall": "",
|
||||
"vertical": "",
|
||||
"horizontal": "",
|
||||
"orientation": "",
|
||||
"card_size": "",
|
||||
"model_info": "",
|
||||
"actual_in": "",
|
||||
"alert": "",
|
||||
"alertoff": "",
|
||||
"alerton": "",
|
||||
"ats": "",
|
||||
"bodyhours": "",
|
||||
"bodypriority": "",
|
||||
"bodyshop": {
|
||||
"labels": {
|
||||
"qbo_departmentid": "",
|
||||
"qbo_usa": ""
|
||||
}
|
||||
},
|
||||
"cardcolor": "",
|
||||
"cardsettings": "",
|
||||
"clm_no": "",
|
||||
"comment": "",
|
||||
"compact": "",
|
||||
"detailpriority": "",
|
||||
"employeeassignments": "",
|
||||
"employeesearch": "",
|
||||
"ins_co_nm": "",
|
||||
"jobdetail": "",
|
||||
"laborhrs": "",
|
||||
"legend": "",
|
||||
"note": "",
|
||||
"ownr_nm": "",
|
||||
"paintpriority": "",
|
||||
"partsstatus": "",
|
||||
"production_note": "",
|
||||
"refinishhours": "",
|
||||
"scheduled_completion": "",
|
||||
"selectview": "",
|
||||
"stickyheader": "",
|
||||
"sublets": "",
|
||||
"totalhours": "",
|
||||
"touchtime": "",
|
||||
"viewname": ""
|
||||
},
|
||||
"successes": {
|
||||
"removed": ""
|
||||
}
|
||||
},
|
||||
"alert": "",
|
||||
"alertoff": "",
|
||||
"alerton": "",
|
||||
"ats": "",
|
||||
"bodyhours": "",
|
||||
"bodypriority": "",
|
||||
"bodyshop": {
|
||||
"labels": {
|
||||
"qbo_departmentid": "",
|
||||
"qbo_usa": ""
|
||||
}
|
||||
},
|
||||
"cardcolor": "",
|
||||
"cardsettings": "",
|
||||
"clm_no": "",
|
||||
"comment": "",
|
||||
"compact": "",
|
||||
"detailpriority": "",
|
||||
"employeeassignments": "",
|
||||
"employeesearch": "",
|
||||
"ins_co_nm": "",
|
||||
"jobdetail": "",
|
||||
"laborhrs": "",
|
||||
"legend": "",
|
||||
"note": "",
|
||||
"ownr_nm": "",
|
||||
"paintpriority": "",
|
||||
"partsstatus": "",
|
||||
"production_note": "",
|
||||
"refinishhours": "",
|
||||
"scheduled_completion": "",
|
||||
"selectview": "",
|
||||
"stickyheader": "",
|
||||
"sublets": "",
|
||||
"totalhours": "",
|
||||
"touchtime": "",
|
||||
"viewname": ""
|
||||
},
|
||||
"successes": {
|
||||
"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": {
|
||||
"errors": {
|
||||
"state": "Erreur lors de la lecture de l'état de la page. Rafraichissez, s'il vous plait."
|
||||
|
||||
Reference in New Issue
Block a user